如何获取动态生成的 X86_64 返回相对于 RIP/RBP 的值
我正在尝试读取内存中相对于 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 标记它失败了。
I'm trying to read values in memory relative to the %rip
on 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 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
:
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:
(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
. It returned -1 flagging that it had failed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您很可能在 mprotect() 调用期间收到 SIGSEGV。如果操作系统不允许 malloc() 返回的内存的代码执行(很可能是如果您没有使用某些古老的内核),则 mprotect() 只是出现段错误。这不是一个错误,而是一个功能。
You most likely get the SIGSEGV during the mprotect() call. 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. That's not a bug, it's a feature.
ret 指令基本上是从堆栈中弹出值;转到值。
当您
转到
时,ret
最终会被执行,问题是堆栈上有垃圾(也许ret
指令试图goto 9
因为 codesize 是堆栈顶部的变量,谁知道......)。基本上,它不起作用,因为您错误地使用了 asm 片段。
我可以问一下你想做什么吗?我可以帮忙 :)
一个测试程序来让你满意:
the
ret
instruction is basically apop 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 theret
instruction tries togoto 9
because codesize is the variable on the top of the stack, who knows...).Basically, it doesn't work because you are using your asm snippet incorrectly.
May I ask what you are trying to do ? I could help :)
A test program to get your rip: