自从NSA发布Ghidra以来,我对反转二进制文件就变得更加感兴趣,Ghidra具有内置功能,可以通过分解二进制文件生成伪C代码。
我想到了用相应的程序集和C代码构建操作码数据库的想法。我想写一个可以转储readelf和objdump之类的二进制文件,从C源文件中提取符号和函数并将其组合在一起的工具
因此,为了更清楚一点,让我们举一个例子。
我们在ubuntu系统上下载了vim-source。我们使用./configure和./make进行编译。二进制文件准备好后,我们启动工具,提取符号的操作码,从代码中创建汇编代码,提取.c文件的函数和函数体,将它们放在一起并将其写入数据库
因此数据库应包含以下内容:
c函数源代码,例如
int main()
{
return 0;
}
汇编器可能看起来像:
push rbp
mov rbp, rsp
...
ret
和操作码部分,如:
55 48 89 e5 89 7d ec 89 75 ...
所以我的问题是...对这些数据进行分类以将其用作反汇编程序中的插件是否有意义?想法是,插件可以将操作码发布到Web服务,并获得可能的c源代码。因此,反编译器可能会使用它来踢掉伪代码,并用实际代码示例代替它。
我知道这样做不是那么容易,因为我们有不同的编译器,体系结构,版本,字节序等。但是总而言之,对于一个包含每个体系结构/版本/编译器操作码的大型数据库,应该可以使对未知二进制文件的逆向工程变得更加容易。
我昨天将代码组合在一起,但是我不确定这是否有助于扩展反汇编程序。
要了解一下,下面是我用c编写的一个小的calc工具的示例以及我工具的输出:
|==================================================================|
| Adress | Function | Size |
|====================|================================|============|
| 0x0000000000000679 | add | 33 |
|==================================================================|
| OPCode |
|==================================================================|
| 55 48 89 e5 89 7d ec 89 75 e8 c7 45 fc 00 00 00 00 8b 55 ec 8b |
| 45 e8 01 d0 89 45 fc 8b 45 fc 5d c3 |
|==================================================================|
| Assembler |
|==================================================================|
| 0x1000 : push rbp |
| 0x1001 : mov rbp, rsp |
| 0x1004 : mov dword ptr [rbp - 0x14], edi |
| 0x1007 : mov dword ptr [rbp - 0x18], esi |
| 0x100a : mov dword ptr [rbp - 4], 0 |
| 0x1011 : mov edx, dword ptr [rbp - 0x14] |
| 0x1014 : mov eax, dword ptr [rbp - 0x18] |
| 0x1017 : add eax, edx |
| 0x1019 : mov dword ptr [rbp - 4], eax |
| 0x101c : mov eax, dword ptr [rbp - 4] |
| 0x101f : pop rbp |
| 0x1020 : ret |
|==================================================================|
| Source |
|==================================================================|
| int add(int a, int b) |
| { |
| int c = 0; |
| c = a + b; |
| return c; |
| } |
| |
|==================================================================|
答案 0 :(得分:0)
这种操作码数据库已经在各种编译为本地代码的编译器中实现。
例如,LLVM具有TableGen语言文件形式的此类数据库。后端反汇编程序通常是根据这些描述自动生成的。例如,看看Sparc backend。
诸如Capstone Disassembler之类的项目使用LLVM来分解用于各种CPU的代码。