将汇编代码逆向工程为 c 代码
Posted
技术标签:
【中文标题】将汇编代码逆向工程为 c 代码【英文标题】:Reverse engineer assembly code to c code 【发布时间】:2015-04-13 22:27:20 【问题描述】:我认为这实际上是一个非常简单的问题。我必须将此汇编代码反向工程为 c 代码。我还将提供我认为正在发生的事情,以便您希望指出我出错的地方,并且我现在可以从错误中吸取教训。
.LFBO
pushq %rbp
movq %rsp,%rbp
movl %edi,-4(%rbp)
movl %esi,-8(%rbp)
movl -4(%rbp),%eax
compl -8(%rbp),%eax
jg .L2
movl -8(%rbp),%eax
jmp .L3
.L2:
movl -4(%rbp),%eax
.L3:
popq %rbp
ret
所以这就是我认为的情况: .LFBO 之后的前两行:
pushq %rbp
movq %rsp,%rbp
只是为即将执行的执行设置堆栈。
movl %edi,-4(%rbp)
正在抓取第一个变量,称之为 x
movl %esi,-8(%rbp)
正在抓取第二个变量,称之为 y
movl -4(%rbp),%eax
正在抓取 x 以在下一行进行比较
compl -8(%rbp),%eax
通过计算 x-y 比较变量 x 和 y
jg .L2
如果 x > y 表示跳转到 .L2
如果 x
movl -8(%rbp),%eax
复制 x = y
jmp .L3
跳转到.L3
如果 jg 行处的 x > y 则跳转到 .L2: 并完成此行
movl -4(%rbp),%eax
这就是我意识到我真的很困惑的地方。在我看来,您正在将 x 复制到 x 然后 .L3 完成,我认为 x 已返回
【问题讨论】:
只是为了确认一下,这是 AT&T-syntax x86 程序集吗? 我不认为你感到困惑。您只是在查看未优化的代码,因此有些行完全没用(就像您所说的将 x 分配给 x )。那么,考虑到所有这些,您认为该函数的作用是什么? 是的,我相信这是 AT&T 语法 x86 程序集。它是由 linux @Dai 上的 c 代码创建的 那么代码的真正作用就是取 2 个变量(x 和 y),然后返回两者中较小的一个? @JS1 如果我正确阅读了汇编代码和您的分析,它将返回更大的:如果 x 更大,它会跳转到L2
,并且它会(不必要地)将 x 复制到 L2 的 %rax 中。
【参考方案1】:
不要想太多。只需逐渐将程序集替换为 C。这是可能的转换顺序。
.LFBO
pushq %rbp
movq %rsp,%rbp
movl %edi,-4(%rbp)
movl %esi,-8(%rbp)
movl -4(%rbp),%eax
compl -8(%rbp),%eax
jg .L2
movl -8(%rbp),%eax
jmp .L3
.L2:
movl -4(%rbp),%eax
.L3:
popq %rbp
ret
----
int LFBO (int edi, int esi)
rbp = rsp
[rbp - 4] = edi
[rbp - 8] = esi
eax = [rbp - 4]
if (eax > [rbp - 8]) goto L2
eax = [rbp - 8]
goto L3
L2:
eax = [rbp - 4]
L3:
return eax
----
int LFBO (int edi, int esi)
int eax;
eax = edi;
if (eax > esi) goto L2;
eax = esi;
goto L3;
L2:
eax = edi;
L3:
return eax;
----
int LFBO (int edi, int esi)
int eax;
eax = edi;
if (eax <= esi)
eax = esi;
else
eax = edi;
return eax;
----
int LFBO (int edi, int esi)
if (edi <= esi)
return esi;
else
return edi;
----
int LFBO (int x, int y)
if (x <= y)
return y;
else
return x;
----
int LFBO (int x, int y)
return (x > y) ? x : y;
您可以将此策略应用于任何组件。在这里,我花时间详细介绍了各种转换。通过练习,您可以更快地获得最终结果。
【讨论】:
这太棒了。感谢您的帮助!【参考方案2】:LFB0(int x, int y)
if (x<=y)
x = y;
else
x = x;
return(x);
在 cmets 的帮助下,我认为我们确定是正确的。
【讨论】:
@thang 不是一回事吗?【参考方案3】:.LFBO
pushq %rbp prolog
movq %rsp,%rbp prolog
movl %edi,-4(%rbp) [ebp-4] = edi
movl %esi,-8(%rbp) [ebp-8] = esi
movl -4(%rbp),%eax eax = [ebp-4] ie edi
compl -8(%rbp),%eax cmp eax with [ebp-8] ie esi
jg .L2 ;jg requires <=
movl -8(%rbp),%eax so cutting the junk
jmp .L3 this effectively becomes
.L2:
movl -4(%rbp),%eax ( edi <= esi ) ? eax = esi : eax= edi ; return;
.L3:
popq %rbp epilog
ret epilog
检验假设
lets compile the code in vc and test should compile unoptimized else
clever compiler will cast away everything do
/O1 push 10 pop eax retn;
/O2 mov eax ,10 ret
int main(void)
int edi=8,esi=10;
if ( edi <= esi) return esi; else return edi;
反汇编结果
0:000> uf @eip
image00400000+0x1000:
00401000 55 push ebp
00401001 8bec mov ebp,esp
00401003 83ec08 sub esp,8
00401006 c745fc08000000 mov dword ptr [ebp-4],8
0040100d c745f80a000000 mov dword ptr [ebp-8],0Ah
00401014 8b45fc mov eax,dword ptr [ebp-4]
00401017 3b45f8 cmp eax,dword ptr [ebp-8]
0040101a 7f07 jg image00400000+0x1023 (00401023)
image00400000+0x101c:
0040101c 8b45f8 mov eax,dword ptr [ebp-8]
0040101f eb05 jmp image00400000+0x1026 (00401026)
image00400000+0x1023:
00401023 8b45fc mov eax,dword ptr [ebp-4]
image00400000+0x1026:
00401026 8be5 mov esp,ebp
00401028 5d pop ebp
00401029 c3 ret
0:000>
【讨论】:
以上是关于将汇编代码逆向工程为 c 代码的主要内容,如果未能解决你的问题,请参考以下文章
用C语言编写了一个程序,源代码和工程文件都弄丢了,只剩下.exe的二进制程序文件。怎么反编译出.c
Android 逆向IDA 工具使用 ( IDA 32 位 / 64 位 版本 | 汇编代码视图 IDA View-A | 字符串窗口 Strings window )
Android 逆向IDA 工具使用 ( IDA 32 位 / 64 位 版本 | 汇编代码视图 IDA View-A | 字符串窗口 Strings window )