我对此非常陌生,但我正在尝试对汇编代码进行反向工程以弄清楚它在C中做了什么。我正在看的函数称为不同的函数(func4),我将它拆开来查看。对于我是否朝着正确的方向前进,我感谢任何帮助或建议。
在原始函数中,0xe在%edx中,0在%esi中,而我试图发现的值(我们称之为x)在%edi中。
FUNC4
0x00000000004010ff <+0>: push %rbx
0x0000000000401100 <+1>: mov %edx,%eax
所以现在%eax有0xe。
0x0000000000401102 <+3>: sub %esi,%eax
%eax = 0xe - 0
0x0000000000401104 <+5>: mov %eax,%ebx
0x0000000000401106 <+7>: shr $0x1f,%ebx
%ebx =%ebx&gt;&gt; 0x1f = 0
0x0000000000401109 <+10>: add %ebx,%eax
%eax =%eax +%ebx = 0xe
0x000000000040110b <+12>: sar %eax
我相信这是sar%eax的缩写,1,这将是7。
0x000000000040110d <+14>: lea (%rax,%rsi,1),%ebx
现在,我认为(%rax,%rsi,1)表示%rax +%rsi * 1,即7
0x0000000000401110 <+17>: cmp %edi,%ebx
0x0000000000401112 <+19>: jle 0x401120 <func4+33>
这意味着如果ebx&lt; = edi(如果7&lt; = x),我们跳转到func4 + 33因为我不知道x是什么,所以我们假设它大于7而不是跳跃。
0x0000000000401114 <+21>: lea -0x1(%rbx),%edx
0x0000000000401117 <+24>: callq 0x4010ff <func4>
这是我困惑的地方。我再次通过这个功能吗?只是寄存器中有不同的值?
0x000000000040111c <+29>: add %eax,%ebx
0x000000000040111e <+31>: jmp 0x40112e <func4+47>
0x0000000000401120 <+33>: cmp %edi,%ebx
0x0000000000401122 <+35>: jge 0x40112e <func4+47>
0x0000000000401124 <+37>: lea 0x1(%rbx),%esi
0x0000000000401127 <+40>: callq 0x4010ff <func4>
0x000000000040112c <+45>: add %eax,%ebx
0x000000000040112e <+47>: mov %ebx,%eax
0x0000000000401130 <+49>: pop %rbx
0x0000000000401131 <+50>: retq
答案 0 :(得分:1)
请勿尝试立即评估 func4 。首先通过逐个翻译每个装配线将其转换为C.结果应如下所示:
int func4 (int edi, int esi, int edx)
{
// temporaries
int eax, ebx;
eax = edx;
eax = eax - esi;
ebx = eax;
ebx = (unsigned int)ebx >> 31;
eax = eax + ebx;
eax = eax >> 1;
ebx = eax + esi + 1;
if (ebx <= edi) goto L1;
edx = ebx - 1;
eax = func4 (edi, esi, edx);
ebx = ebx + eax;
goto L2;
L1:
if (ebx >= edi) goto L2;
esi = ebx + 1;
eax = func4 (edi, esi, edx);
ebx = ebx + eax;
L2:
eax = ebx;
return eax;
}
当然它是丑陋的,你可能想重写它以使它更容易阅读,但它编译。</ p>
现在,根据我的理解,给定 y ,您正在寻找 x ,以便y = func4 (x, 0, 14);
您有两种选择:
y = func4 (x, 0, 14)
所有 x 的值,直到获得所需的 y 。如果允许您使用计算机,则蛮力方法(2)更容易。