我想向现有的二进制文件添加一些功能。二进制文件是使用gcc
.
- 即使我充分了解程序的功能,我是否需要先反编译二进制文件?
- 我应该如何添加必要的代码?
- 我需要任何工具才能做到这一点吗?
我想向现有的二进制文件添加一些功能。二进制文件是使用gcc
.
有几种广泛的方法可以做到这一点。
动态仪表
PIN、Valgrind或DynamoRIO等工具允许您动态更改程序的行为。例如,您可以在特定地址添加对新函数的调用,拦截库调用并更改它们,等等。
缺点是动态检测通常具有很高的开销。
静态仪表
您还可以尝试静态修改程序以添加所需的行为。一个挑战是您经常需要处理可执行文件格式。为此存在一些工具,例如elfsh
来自ERESI项目的工具,但我发现它们有缺陷且难以使用。
静态检测的另一个策略是“重新编译”。您可以通过反编译程序、修改源代码并重新编译来完成此操作。理论上,你也可以使用BAP之类的工具将程序提升到IL,修改它,然后使用LLVM重新编译它。但是,当前版本可能还不够成熟。
动态加载
您可以使用LD_PRELOAD
覆盖将要动态链接的函数。当您想要更改库函数的行为时,这是一个不错的选择。当然,它不适用于静态链接的二进制文件或静态函数。
二进制补丁
您通常可以使用十六进制编辑器对二进制文件进行简单的更改。例如,如果您想跳过某个函数调用或分支,通常可以将其替换为nop
指令。如果您需要添加大量新代码,您可能需要使用elfsh
来自ERESI项目的类似工具来帮助您调整二进制文件的大小。
很多时候,你可以通过小心地钩住一个程序来改变它的行为。您是否可以通过这种方式添加您想要的功能取决于程序的构建方式。如果程序以一个主要可执行文件和多个库的形式出现,这会有所帮助。
您可以通过首先将您自己的库与LD_PRELOAD
. 编写一个定义函数的库foo
,并在启动程序时将环境变量设置为LD_PRELOAD
编译 ( .so
) 库的路径:然后程序将调用您的foo
而不是它想要的。您可以foo
通过使用dlsym()
.
以下是一些示例和教程:
使用 的程序的一些示例LD_PRELOAD
:
malloc
的限制LD_PRELOAD
是您只能拦截在运行时解析的函数调用(动态链接)。如果你想拦截一个内部调用,你将不得不求助于更重的技术(修改磁盘上的可执行文件,或者使用 修改内存中的可执行文件ptrace
)。
我想向现有的二进制文件添加一些功能。
所以总的来说,这四个更大的问题适用于修改一个可执行文件:
提出的第一个基本问题: 程序是否警惕代码修改(自检、反调试技巧、复制保护等)?
如果是这样:
第二个问题是:
您能找出使用哪种编译器/语言来生成可执行文件吗?
更多细节更好,但大多数基本结构(if
和其他控制结构)在各种编译器上的映射应该非常相似。
这与之前关于 RE-Stackexchange 的问题有关。
第三个问题是:
用户界面是如何实现的(CLI、Win32-Window Controls、Custom...)?
如果这是已知的:
您能找出常见的 HLL 结构(菜单、下拉菜单、复选框等)与您要修改的使用的编译器/语言的映射吗?
第四个也是最大的问题是:
如何在程序中创建所需的功能?
从本质上讲,这可能需要相当多的逆向工程,以找出如何最好地挂钩程序而不打扰它。
中心点:您如何利用现有的内部 API 来实现您的目标,而不会破坏 Stuff(如 CRTL+Z、版本控制、恢复功能)?
示例项目:
关于包装的代码和反编译器:
我不会谈论用 VM / 解释器(Py2Exe、Java 2 Exe 等)打包的其他语言中的包装代码,或者使用已安装的语言(JVM、C#)。对于其中一些情况,有非常好的反编译器。成功反编译后,它几乎可以归结为击败代码混淆(如果有的话)。
关于 C/C++-Decompilers:
我不能谈论 C/C++-Decompilers,尽管它可以归结为尽力而为的 HLL-Remapping(对于 Decompiler 没有得到的东西)和 Code-Deobfuscation(如果它是在没有符号的情况下编译的)前提是可执行文件中没有进一步的保护。
关于 HLL 映射的建议:
本质上,这个问题的很大一部分涉及“HLL 映射”(高级语言映射(机器代码))以及相应机器代码中这些结构的修改。
我在此处(binary-auditing.com)上找到了关于此主题的优秀可下载入门课程,该课程使用“IDA Free” 。
(有点过时了,但因为之前在这个线程中没有提到)
很久以前,我花了几个月的时间来扩展一个只有二进制文件的软件。
然后,因为它是一个 x86 PE 二进制文件,所以我使用了 Tasm 和 Iczelion 的Code Snippet Creator:它不再是一个著名的工具,但它允许透明地使用 Tasm 并重新注入代码,以及 PE 转换等......
它在 EntryPoint 增加了代码,所以我手动做了我自己的补丁,然后跳转到原始的 EntryPoint。
现在有点老派了——这些天我可能会注入一个 DLL——但它确实有效。
至少,它让您可以通过 ASM 进行完全控制,同时通过自动修补保持可维护性。