2012-05-06 57 views
1

我想在Linux x86_64上獲得sys_call_table的偏移量。Linux sys_call_table rip相對尋址x86_64

所有我讀指針由MSR_LSTAR閱讀它system_call進入第一,它是正確的

static unsigned long read_msr(unsigned int msr) 
{ 

    unsigned low, high; 
    asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr)); 
    return ((low) | ((u64)(high) << 32)); 
} 

然後我分析它找到調用指令操作碼,它也是正確的

#define CALL_OP 0xFF 
#define CALL_MODRM 0x14 
static unsigned long find_syscall_table(unsigned char *ptr) 
{ 

    //correct 
    for (; (*ptr != CALL_OP) || (*(ptr+1) != CALL_MODRM); ptr++); 

    //not correct 
    ptr += *(unsigned int*)(ptr + 3); 
    pr_info("%lx", (unsigned long)ptr); 


    return ptr; 
} 

但是在調用操作碼後我沒有得到地址。 ptr的第一個字節是opcode,然後是ModRM字節,然後是SIB,然後是32位移位,所以我將ptr加3並將其解引用爲整數值,然後將其添加到ptr中,因爲它是%RIP,地址是RIP相對的。但結果值是錯誤的,它不符合我在gdb中看到的值,所以我錯在哪裏?

+2

通過在內部進行挖掘,您實際上想要完成什麼目標? –

+0

目標是在運行時修補sys_call_table。我想以上述的方式做到這一點,但我無法找出爲什麼它不工作 –

+0

正如我以前寫的,「call * sys_call_table(,%rax,8)」的system_call條目和偏移量是正確的,我檢查了它gdb allready。我認爲我在RIP相對地址方面失敗了,但不知道確切的位置 –

回答

0

這不是x7e9fed00,而是-0x7e9fed00 - 負排量。

這是2的補負數0x81601300

其存儲在由小端處理器爲「00 13 60 81」


不知道的符號 - 幅度形式,如果你願意然而,在結果地址找到sys_call_table。作爲另一種想法,似乎有些人通過在內存中搜索應該列在其中的函數的已知指針來找到它。

+0

ffffffff8145fe62-7e9fed00 = 0xFFFFFFFF02A61162這個結果我得到我的模塊和計算器。 objdump的和gdb節目表ffffffff81601300的偏移量( –

+0

ffffffff8145fe62是補償調用指令 –

+0

。如果ffffffff81601300是正確的答案,因爲「81601300」是你發現了存儲小端內存中的文字,看來這不是一個簽署相對於當前IP,而是一個無符號當前的「段」內的偏移偏移(或任何一個應該叫高字的當前地址的32位)。GDB可能只是假設,上面簽着你扔一個弧線球和將其顯示爲負數。可能值得仔細檢查該指令的確切含義。 –