[英]How to get dynamically generated X86_64 to return a value relative to the RIP / RBP
I'm trying to read values in memory relative to the %rip
on X86_64. 我试图读取内存中相对于X86_64上的%rip
值。 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
): 如果我在C中编写以下代码,我可以调用它并获得正确的结果( \\x....C3C9
):
void * test() {
__asm("mov 0(%rip), %rax");
}
The generated code looks 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 however put this code directly in memory and execute it I get a segfault, while I would expect to read \\x0000C3C9
: 但是,如果我现在将此代码直接放在内存中并执行它,我会得到一个段错误,而我希望读取\\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 shouldn't have used malloc
but mmap
to allocate a page-aligned memory region: 编辑答案是我不应该使用malloc
而是使用mmap
来分配页面对齐的内存区域:
(unsigned char*)mmap(NULL, 1024, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
And of course I should have checked the return value of the call to mprotect
. 当然我应该检查调用mprotect
的返回值。 It returned -1 flagging that it had failed. 它返回-1标记它失败了。
You most likely get the SIGSEGV during the mprotect() call. 您最有可能在mprotect()调用期间获得SIGSEGV。 If the code execution of the memory returned by malloc() is disallowed by the OS (it most likely is if you aren't using some ancient kernel), mprotect() just segfaults. 如果操作系统不允许执行malloc()返回的内存的代码执行(很可能是你没有使用某些古老内核),mprotect()只是段错误。 That's not a bug, it's a feature. 这不是一个错误,它是一个功能。
the ret
instruction is basically a pop value from the stack; goto value
ret
指令基本上是pop value from the stack; goto value
的pop value from the stack; goto value
pop value from the stack; goto value
. pop value from the stack; goto value
。
When you goto <your_code>
, ret
eventually gets executed the problem is that you have garbage on the stack (maybe the ret
instruction tries to goto 9
because codesize is the variable on the top of the stack, who knows...). 当你goto <your_code>
, ret
最终会被执行,问题是你的堆栈上有垃圾(也许ret
指令试图goto 9
因为codesize是堆栈顶部的变量,谁知道......)。
Basically, it doesn't work because you are using your asm snippet incorrectly. 基本上,它不起作用,因为你错误地使用你的asm片段。
May I ask what you are trying to do ? 请问您要做什么? I could help :) 我可以帮忙:)
A test program to get your rip: 获取你的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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.