【问题标题】:Find memory address in hex string in kernel module在内核模块的十六进制字符串中查找内存地址
【发布时间】:2013-08-10 08:20:43
【问题描述】:

我正在编写一个内核模块,通过首先搜索地址旁边的十六进制字节来找到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)

阅读:

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)

【问题讨论】:

  • 我不确定内核二进制文件,但在 gdb 中尝试 print do_debug。对我来说适用于常规二进制文件。
  • @SergeyL。我不明白如何处理print do_debug。你能解释一下吗?
  • 地址输出错误是什么?是0xffffffff04814865吗?
  • @sigmalha 是的,就是地址。

标签: c linux linux-kernel gdb hex


【解决方案1】:

我对linux内核不熟悉。 在while语句中,当你进入第一个if语句时,debug然后指向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;
}

【讨论】:

  • 感谢您解释如何获取正确的地址。在我的系统中,不需要 ntohl()。
猜你喜欢
  • 2013-03-10
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
相关资源
最近更新 更多