汇编到 C 代码跳转
Assembly to C Code jumps
我对此很陌生,但我正在尝试对汇编代码进行逆向工程以弄清楚它在 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 [=12=]x1f,%ebx
%ebx = %ebx >> 0x1f = 0
0x0000000000401109 <+10>: add %ebx,%eax
%eax = %eax + %ebx = 0xe
0x000000000040110b <+12>: sar %eax
我相信这是 shorthand 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>
这意味着我们跳转到 func4+33 if ebx <= edi (if 7 <= x) 因为我不知道 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
不要尝试立即计算 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;
}
它很丑,但它有效。
现在,据我了解,给定一个 y,您正在寻找一个 x 使得 y = func4 (x, 0, 14);
您有两个选择:
- 重写 func4 使其变得易于理解,让您弄清楚它的作用并猜测您必须传递给哪个 x得到给定的 y.
- 为 x 的所有值计算
y = func4 (x, 0, 14)
,直到得到所需的 y.
我对此很陌生,但我正在尝试对汇编代码进行逆向工程以弄清楚它在 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 [=12=]x1f,%ebx
%ebx = %ebx >> 0x1f = 0
0x0000000000401109 <+10>: add %ebx,%eax
%eax = %eax + %ebx = 0xe
0x000000000040110b <+12>: sar %eax
我相信这是 shorthand 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>
这意味着我们跳转到 func4+33 if ebx <= edi (if 7 <= x) 因为我不知道 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
不要尝试立即计算 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;
}
它很丑,但它有效。
现在,据我了解,给定一个 y,您正在寻找一个 x 使得 y = func4 (x, 0, 14);
您有两个选择:
- 重写 func4 使其变得易于理解,让您弄清楚它的作用并猜测您必须传递给哪个 x得到给定的 y.
- 为 x 的所有值计算
y = func4 (x, 0, 14)
,直到得到所需的 y.