GCC编译的二进制文件中的冗余寄存器值? [复制]
Posted
技术标签:
【中文标题】GCC编译的二进制文件中的冗余寄存器值? [复制]【英文标题】:Redundant register values in GCC-compiled binary? [duplicate] 【发布时间】:2020-09-05 16:08:14 【问题描述】:好的,所以我正在尝试学习逆向工程和 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并这样做了,但现在程序返回看似随机的数字,我在猜测内存地址?
谁能向我解释为什么 GCC 使用这个看似多余的寄存器,以及我在尝试修补二进制文件时做错了什么?
【问题讨论】:
您使用了多少优化? (-O3
?)
啊,我只是用默认设置编译它,O3优化的输出更有意义。谢谢!
【参考方案1】:
您没有启用优化,因此您正在查看调试代码。使用-O3
,输出为:
关于您的问题的注释,您需要分配给eax
,因为eax
将返回值存储在x86 应用程序中。
【讨论】:
对,这是有道理的。我发现我的补丁出了什么问题:edi
后来被 printf 的另一个参数覆盖:指向实际格式字符串的指针。 square的返回值应该在esi
。
这很好,因为edi
是用来传递参数的。请记住,edi
和 esi
是唯一可以运行 rep *sb
指令的寄存器,因此它们是很好的候选者。编译器(几乎)普遍使用一大堆约定,如果您真的想与编译器一起编写汇编代码,您需要了解它们,否则您将生成无效代码。
其实汇编编程现在可能有点野心勃勃,目前我主要只是想学习如何阅读编译器生成的汇编代码。但是感谢您的帮助,我真的很感激!
请不要张贴文字图片。您可以轻松地从 Godbolt 的 asm 输出窗格复制/粘贴文本。
但没有颜色格式。如果您不喜欢图片也没关系,如果它会改善其他人的生活,请随时添加您自己的无图片答案。以上是关于GCC编译的二进制文件中的冗余寄存器值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章