如何动态生成X86_64以返回相对于RIP / RBP的值

时间:2011-05-06 00:09:58

标签: c assembly code-generation x86-64

我正在尝试读取内存中相对于X86_64上的%rip的值。在我的第一个例子中,我只想阅读

如果我在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表示它已失败。

2 个答案:

答案 0 :(得分:1)

你最有可能在mprotect()调用期间获得SIGSEGV。如果操作系统不允许执行malloc()返回的内存的代码执行(很可能是你没有使用某些古老内核),mprotect()只是段错误。这不是一个错误,它是一个功能。

答案 1 :(得分:0)

ret指令基本上是pop value from the stack; goto value

goto <your_code>ret最终被执行时,问题是堆栈上有垃圾(可能ret指令尝试goto 9因为codesize是变量在堆栈的顶部,谁知道......)。

基本上,它不起作用,因为您错误地使用了您的asm代码段。

请问您要做什么?我可以帮忙:))


获取你的rip的测试程序:

static inline unsigned long get_rip(void)
{
    unsigned long val;
    asm volatile(
        "call 1f\n"
        "1: popq %0\n"
        : "=r"(val));
    return val;
}

int main()
{
    printf("rip = %p\n", (void *)get_rip());
    return 0;
}