How to get dynamically generated X86_64 to return a value relative to RIP / RBP

I am trying to read values ​​in memory relatively %ripon X86_64. In my first example, I just want to read

If I write the following code in C, I can call it and get the correct result ( \x....C3C9):

void * test() {
    __asm("mov 0(%rip), %rax");
}

The generated code is as follows:

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 

If I now pass this code directly to memory and execute it, I get segfault while I expect to read \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;
}

What am I doing wrong?

edit The answer is that I should not have used it malloc, but mmapto allocate a page-aligned memory area:

(unsigned char*)mmap(NULL, 1024, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, 0);

, , mprotect. -1, , .

+3
2

, SIGSEGV mprotect(). , malloc(), ( , - ), mprotect() segfaults. , .

+1

ret pop value from the stack; goto value.

goto <your_code>, ret, , (, ret goto 9, codeize - , ...).

, , asm.

, ? :)


, :

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;
}
0

All Articles