GCC 编译的二进制文件中的冗余寄存器值?
Redundant register values in GCC-compiled binary?
好的,我正在尝试学习逆向工程和 x64 汇编。例如,我在 C:
中编写了这个小测试程序
#include <stdio.h>
int square(int num) {
return num * num;
}
int main() {
int ans = square(5);
printf("%d", ans);
}
这会产生以下 square
函数的汇编代码:
push rbp
mov rbp,rsp
mov DWORD PTR [rbp-0x4],edi
mov eax,DWORD PTR [rbp-0x4]
imul eax,eax
pop rbp
ret
这对我来说有点奇怪,因为 edi
是函数参数,我相信它会存储在堆栈中并加载回 eax
,然后在那里相乘?为什么不跳过第 3 行和第 4 行而直接 imul edi, edi
?
所以我打开了 radare2 并这样做了,但是现在程序 returns 看似随机数,我在猜测内存地址?
有人可以向我解释为什么 GCC 使用这个看似冗余的寄存器,以及我在尝试修补二进制文件时做错了什么吗?
您没有启用优化,所以您正在查看调试代码。使用 -O3
,输出为:
请注意您的问题,您需要 分配给 eax
,因为 eax
将 return 值存储在 x86 应用程序中.
好的,我正在尝试学习逆向工程和 x64 汇编。例如,我在 C:
中编写了这个小测试程序#include <stdio.h>
int square(int num) {
return num * num;
}
int main() {
int ans = square(5);
printf("%d", ans);
}
这会产生以下 square
函数的汇编代码:
push rbp
mov rbp,rsp
mov DWORD PTR [rbp-0x4],edi
mov eax,DWORD PTR [rbp-0x4]
imul eax,eax
pop rbp
ret
这对我来说有点奇怪,因为 edi
是函数参数,我相信它会存储在堆栈中并加载回 eax
,然后在那里相乘?为什么不跳过第 3 行和第 4 行而直接 imul edi, edi
?
所以我打开了 radare2 并这样做了,但是现在程序 returns 看似随机数,我在猜测内存地址?
有人可以向我解释为什么 GCC 使用这个看似冗余的寄存器,以及我在尝试修补二进制文件时做错了什么吗?
您没有启用优化,所以您正在查看调试代码。使用 -O3
,输出为:
请注意您的问题,您需要 分配给 eax
,因为 eax
将 return 值存储在 x86 应用程序中.