[英]Find memory address in hex string in kernel module
我正在編寫一個內核模塊,通過首先搜索地址旁邊的十六進制字節來查找do_debug
(0xffffffff8134f709)的內存地址。 我不確定我使用的是正確的十六進制字節:“ \\ xe8 \\ x61 \\ x07 \\ x00 \\ x00”(我希望堅持使用C而不是匯編語言。)
struct desc_ptr idt_register;
store_idt(&idt_register);
printk("idt_register.address: %lx\n", idt_register.address); // same as in /boot/System.map*
gate_desc *idt_table = (gate_desc *)idt_register.address;
unsigned char *debug = (unsigned char *)gate_offset(idt_table[0x1]);
printk("debug: %lx\n", (unsigned long)debug); // same as in /boot/System.map*
int count = 0;
while(count < 150){
if( (*(debug) == 0xe8) && (*(debug + 1) == 0x61) && (*(debug + 2) == 0x07) && (*(debug + 3) == 0x00) && (*(debug + 4) == 0x00) ){
debug += 5;
unsigned long *do_debug = (unsigned long *)(0xffffffff00000000 | *((unsigned long *)(debug)));
if((unsigned long)do_debug != 0xffffffff8134f709){
printk("do_debug: %lx\n", (unsigned long)do_debug); // wrong address !
return;
}
break;
}
debug++;
count++;
}
gdb:
gdb ./vmlinux-3.2.0-4-amd64
...
(gdb) info line debug
Line 54 of "/build/linux-s5x2oE/linux-3.2.46/drivers/pci/hotplug/pci_hotplug_core.c" is at address 0xffffffff811cf02b <power_read_file+2> but contains no code.
Line 1322 of "/build/linux-s5x2oE/linux-3.2.46/arch/x86/kernel/entry_64.S"
starts at address 0xffffffff8134ef80 and ends at 0xffffffff8134efc0.
(gdb) disas 0xffffffff8134ef80,0xffffffff8134efc0
Dump of assembler code from 0xffffffff8134ef80 to 0xffffffff8134efc0:
0xffffffff8134ef80: callq *0x2c687a(%rip) # 0xffffffff81615800
0xffffffff8134ef86: pushq $0xffffffffffffffff
0xffffffff8134ef88: sub $0x78,%rsp
0xffffffff8134ef8c: callq 0xffffffff8134ed40
0xffffffff8134ef91: mov %rsp,%rdi
0xffffffff8134ef94: xor %esi,%esi
0xffffffff8134ef96: subq $0x1000,%gs:0x1137c
0xffffffff8134efa3: callq 0xffffffff8134f709 <do_debug>
0xffffffff8134efa8: addq $0x1000,%gs:0x1137c
0xffffffff8134efb5: jmpq 0xffffffff8134f160
0xffffffff8134efba: nopw 0x0(%rax,%rax,1)
End of assembler dump.
(gdb) x/i 0xffffffff8134efa3
0xffffffff8134efa3: callq 0xffffffff8134f709 <do_debug>
(gdb) x/xw 0xffffffff8134efa3
0xffffffff8134efa3: 0x000761e8
(gdb)
readelf:
ffffffff8134ef96: 65 48 81 2c 25 7c 13 subq $0x1000,%gs:0x1137c
ffffffff8134ef9d: 01 00 00 10 00 00
ffffffff8134efa3: e8 61 07 00 00 callq ffffffff8134f709 <do_debug>
ffffffff8134efa8: 65 48 81 04 25 7c 13 addq $0x1000,%gs:0x1137c
ffffffff8134efaf: 01 00 00 10 00 00
編輯:
(gdb) print do_debug
$1 = {void (struct pt_regs *, long int)} 0xffffffff8134f709 <do_debug>
(gdb)
我對linux內核不熟悉。 在while語句中,當您進入第一個if語句時, 調試將指向ffffffff8134efa8
ffffffff8134efa8: 65 48 81 04 25 7c 13 addq $0x1000,%gs:0x1137c # debug point here
ffffffff8134efaf: 01 00 00 10 00 00
下一條語句
unsigned long *do_debug = (unsigned long *)(0xffffffff00000000 |
*((unsigned long *)(debug)));
會得到這個結果。
do_debug = (unsigned long *)(0xffffffff00000000 | 0x01137c2504814865) = 0xffffffff04814865
如果要獲取do_debug地址,則應執行以下操作:
if( (*(debug) == 0xe8) && (*(debug + 1) == 0x61) && (*(debug + 2) == 0x07) && (*(debug + 3) == 0x00) && (*(debug + 4) == 0x00) ){
//debug += 5;
uint32_t offset = ntohl(*(unsigned int *)(debug+1)); //get the do_debug function offset
unsigned long *do_debug = (debug+5)+offset; // next_code_instruction + offset
//debug+5 point to ffffffff8134efa8
//offset is 0x761
//so ffffffff8134efa8+0x761 = 0xffffffff8134f709
if((unsigned long)do_debug != 0xffffffff8134f709){
printk("do_debug: %lx\n", (unsigned long)do_debug); // wrong address !
return;
}
break;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.