不理解 Hopper 反编译器的输出
Not understanding Hopper decompiler output
我懂一点 C 和一点汇编,想开始学习逆向工程,所以我下载了 Mac 的 Hopper Disassembler 试用版。我创建了一个超级基础的 C 程序:
int main() {
int a = 5;
return 0;
}
并使用 -g 标志编译它(因为我之前看到过这个但不确定它是否重要):
gcc -g simple.c
然后我在 Hopper Disassembler 中打开 a.out
文件并点击 Pseudo Code 按钮,它给了我:
int _main() {
rax = 0x0;
var_4 = 0x0;
var_8 = 0x5;
rsp = rsp + 0x8;
rbp = stack[2047];
return 0x0;
}
我在这里唯一能理解的是将变量设置为 0x5
。对于这样一个简单的程序,我无法理解所有这些附加行的用途(例如 rsp = rsp + 0x8;
)。有人愿意给我解释一下吗?
此外,如果有人知道 sources/tutorials 介绍逆向工程,那也会非常有帮助。谢谢。
看起来它在生成 "disassembly pseudocode" 方面做得特别差(不管它是反汇编程序还是反编译程序?无法决定)
在这种情况下,它看起来有 elided 堆栈帧设置(函数 prolog),但没有清理(函数 epilog)。因此,通过使用实际的反汇编程序查看实际的反汇编代码,您将更好地了解发生了什么:
$ gcc -c simple.c
$ objdump -d simple.o
simple.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 05 00 00 00 movl [=10=]x5,-0x4(%rbp)
b: b8 00 00 00 00 mov [=10=]x0,%eax
10: 5d pop %rbp
11: c3 retq
所以我们这里有代码来设置堆栈框架(地址 0-1),您的分配 (4),设置 return 值 (b),拆除框架(10) 然后 returning (11)。由于使用不同版本的 gcc 或不同的目标,您可能会看到不同的东西。
在反汇编的情况下,第一部分已被反汇编程序删除(作为一项无趣的内务处理任务而遗漏),但倒数第二部分(撤消第一部分)没有。
您看到的是反编译代码。每个反编译器的输出看起来都接近于此,因为它不会尝试获取变量名,因为它们可以经常更改,而且通常是。
所以它将把它们放在一个 'var_??' 中,最后附上一个数字。一旦您了解了逆向工程并且非常了解您正在使用的编程语言,您就可以理解代码。当您尝试对 PHP、JavaScript 代码等进行反混淆处理时,这并没有什么不同。
如果您遇到逆向工程恶意软件,请做好准备,因为没有什么是容易的。您将拥有不同的加壳器、混淆器、混乱的代码、VM 检测例程等。因此,如果您的目标是逆向工程,请做好准备迎接漫长的道路。
我懂一点 C 和一点汇编,想开始学习逆向工程,所以我下载了 Mac 的 Hopper Disassembler 试用版。我创建了一个超级基础的 C 程序:
int main() {
int a = 5;
return 0;
}
并使用 -g 标志编译它(因为我之前看到过这个但不确定它是否重要):
gcc -g simple.c
然后我在 Hopper Disassembler 中打开 a.out
文件并点击 Pseudo Code 按钮,它给了我:
int _main() {
rax = 0x0;
var_4 = 0x0;
var_8 = 0x5;
rsp = rsp + 0x8;
rbp = stack[2047];
return 0x0;
}
我在这里唯一能理解的是将变量设置为 0x5
。对于这样一个简单的程序,我无法理解所有这些附加行的用途(例如 rsp = rsp + 0x8;
)。有人愿意给我解释一下吗?
此外,如果有人知道 sources/tutorials 介绍逆向工程,那也会非常有帮助。谢谢。
看起来它在生成 "disassembly pseudocode" 方面做得特别差(不管它是反汇编程序还是反编译程序?无法决定)
在这种情况下,它看起来有 elided 堆栈帧设置(函数 prolog),但没有清理(函数 epilog)。因此,通过使用实际的反汇编程序查看实际的反汇编代码,您将更好地了解发生了什么:
$ gcc -c simple.c
$ objdump -d simple.o
simple.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 05 00 00 00 movl [=10=]x5,-0x4(%rbp)
b: b8 00 00 00 00 mov [=10=]x0,%eax
10: 5d pop %rbp
11: c3 retq
所以我们这里有代码来设置堆栈框架(地址 0-1),您的分配 (4),设置 return 值 (b),拆除框架(10) 然后 returning (11)。由于使用不同版本的 gcc 或不同的目标,您可能会看到不同的东西。
在反汇编的情况下,第一部分已被反汇编程序删除(作为一项无趣的内务处理任务而遗漏),但倒数第二部分(撤消第一部分)没有。
您看到的是反编译代码。每个反编译器的输出看起来都接近于此,因为它不会尝试获取变量名,因为它们可以经常更改,而且通常是。
所以它将把它们放在一个 'var_??' 中,最后附上一个数字。一旦您了解了逆向工程并且非常了解您正在使用的编程语言,您就可以理解代码。当您尝试对 PHP、JavaScript 代码等进行反混淆处理时,这并没有什么不同。
如果您遇到逆向工程恶意软件,请做好准备,因为没有什么是容易的。您将拥有不同的加壳器、混淆器、混乱的代码、VM 检测例程等。因此,如果您的目标是逆向工程,请做好准备迎接漫长的道路。