如何将此汇编代码 (x64) 转换为 C?

逆向工程 拆卸 部件 x86-64
2021-07-06 09:26:24

我有以下程序集(x64)功能:

400700: sub  rsp,0x18
400704: mov  QWORD PTR [rsp+0x8],rdi
400709: cmp  QWORD PTR [rsp+0x8],0x0
40070f: jne  400718 <bar+0x18>
400711: mov  eax,0x0
400716: jmp  400734 <bar+0x34>
400718: mov  rax,QWORD PTR [rsp+0x8]
40071d: sub  rax,0x1
400721: mov  rdi,rax
400724: call 400700 <bar>
400729: mov  rdx,rax
40072c: mov  rax,QWORD PTR [rsp+0x8]
400731: add  rax,rdx
400734: add  rsp,0x18
400738: ret

我发现开始部分只是任何汇编程序的标题。另外,我认为这两个 QWORD 要么来自长整型要么来自字符。我猜测 jne 跳转可能是一个条件语句,但我不太确定。看起来该函数是递归的,因为它有一行再次调用“bar”。

我对整个函数的猜测是它需要两个 long 并递归地添加它们(Fibonacci,也许?)。不过,我对这个猜测没有太多理由,而且我可能是不正确的。

有人可以帮我解决这个问题吗?或者,如果有一种方法可以让我传入参数(我什至不知道函数采用什么样的参数)并查看输出,那么我可以尝试回溯并弄清楚程序在做什么。

谢谢

1个回答

此函数计算(以递归方式)n第一个整数的总和

     400700: sub  rsp,0x18                 ; Align the stack
     400704: mov  QWORD PTR [rsp+0x8],rdi  ; Store first argument on stack
     400709: cmp  QWORD PTR [rsp+0x8],0x0  ; test (n == 0)
  +--40070f: jne  400718 <bar+0x18>        ; jump to 400718 if (n != 0)
  |  400711: mov  eax,0x0                  ; set return code to zero
+-|--400716: jmp  400734 <bar+0x34>        ; jump to function end at 400734
| +->400718: mov  rax,QWORD PTR [rsp+0x8]  ; Get 'n' in rax
|    40071d: sub  rax,0x1                  ; n = n - 1
|    400721: mov  rdi,rax                  ; Load 'n - 1' as first argument
|    400724: call 400700 <bar>             ; recursive call to 'bar(n - 1)'
|    400729: mov  rdx,rax                  ; Load bar(n-1) return code in rdx
|    40072c: mov  rax,QWORD PTR [rsp+0x8]  ; Get current 'n' in rax
|    400731: add  rax,rdx                  ; rax = n + bar(n - 1)
+--->400734: add  rsp,0x18                 ; Restore the stack
     400738: ret                           ; return n + bar(n - 1)

最终代码:

bar (long long int n)
{
  return (n) ? n + bar(n - 1) : 0;
}

坦率地说,我会使用众所周知的公式n*(n+1)/2......