我正在嘗試讀取內存中相對於X86_64上的%rip
的值。在我的第一個例子中,我只是想讀如何獲取動態生成的X86_64以返回相對於RIP/RBP的值
如果我使用C下面的代碼,我可以調用它,並得到正確的結果(\x....C3C9
):
void * test() {
__asm("mov 0(%rip), %rax");
}
生成的代碼如下:
0000000000400624 <test>:
400624: 55 push %rbp
400625: 48 89 e5 mov %rsp,%rbp
400628: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 40062f <test+0xb>
40062f: c9 leaveq
400630: c3 retq
如果我現在不過直接把這個代碼在內存中,並執行它,我收到了段錯誤,而我希望閱讀\x0000C3C9
:
int main()
{
int codesize = 9;
unsigned char * code = (unsigned char*)malloc(1024);
memcpy(code, "\x48\x8B\x5\x0\x0\x0\x0\xC9\xC3\x00\x00", codesize + 2);
mprotect(code, codesize, PROT_EXEC | PROT_READ);
goto *code;
}
我做錯了什麼?
編輯 答案是,我不應該使用malloc
但mmap
分配一個頁對齊的內存區域:
(unsigned char*)mmap(NULL, 1024, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
當然,我應該檢查調用的返回值到mprotect
。它返回-1標記它失敗。
我被人誰又被刪除了他的評論評論,但是他引導我正確的方向。他說得對,「保護」失敗了(愚蠢的我,我應該檢查)。我猜'malloc'(顯然)不會返回與頁面邊界對齊的內存。通過使用'(unsigned char *)mmap(NULL,1024,PROT_WRITE | PROT_READ,MAP_ANONYMOUS | MAP_SHARED,-1,0);'它確實有效。 – tverwaes 2011-05-06 00:28:07
如果您將'PROT_EXEC'添加到'mmap'調用中,則不需要'mprotect'。 – 2011-05-06 00:31:40
因爲我讀過某些內核不允許同時使用'PROT_WRITE'和'PROT_EXEC'的情況,所以我沒有這樣做。我誤解了嗎? – tverwaes 2011-05-06 00:36:12