用Cutter修补二进制文件的5种方法
导语:用Cutter修补二进制文件的5种方法
我最近看了LiveOverflow上的一段视频https://www.youtube.com/watch?v=LyNyf3UM9Yc,该视频中展示了如何使用不同的工具来修补二进制文件。通过演示Radare2、Ghidra和Binary Ninja为该任务提供的一些特性,查看者可以从使用这些工具获得一些信息。
虽然视频中介绍的这些工具都很好,但是却没有提到Cutter。尽管它是团队中最年轻的成员,但Cutter成长得非常快,它会及时更新二进制修补程序。
“二进制修补”是通常为了更改其行为而对二进制文件进行小的更改和修改的过程,通过修改数据或代码,用户可以更改程序或特定指令中的某些值,并根据所需的结果调整二进制文件。
用Cutter修补二进制文件的5种方法:
1.反向跳转;
2.直接从反编译器开始;
3. 使用NOP;
4.分解指令;
5.组装字节;
Cutter介绍
Cutter是一个由radare2提供支持的免费开源逆向工程框架,它为逆向工程师提供了广泛的特性,其中最重要的是disassmebler、grpah、反编译器(基于Ghidra的反编译器)和十六进制编辑器以及最近新发布的调试器。
要下载最新版本的Cutter,请先进入官方网站。如果你想从源头上构建Cutter,以享受最新的改进特性和功能,请查看文档上的“构建”页面。
请注意,本文将非常简单明了,不会涵盖Cutter的其他功能。
本文的测试目标
在本文中,我们将使用与LiveOverflow视频中使用的相同二进制文件:license_1.c,点击这里下载Linux的二进制文件。
源代码如下:
#include #include int main(int argc, char *argv[]) { if(argc==2) { printf("Checking License: %s\n", argv[1]); if(strcmp(argv[1], "AAAA-Z10N-42-OK")==0) { printf("Access Granted!\n"); } else { printf("WRONG!\n"); } } else { printf("Usage: \n"); } return 0; }
程序相当简单,它从用户那里收到一个许可密钥,然后将它与一个硬编码密钥“AAAA-Z10N-42-OK”进行比较。如果密钥匹配,它将显示“授予访问权限!”否则,它将显示“错误!”
$ license_1 test_key Checking License: test_key WRONG!
最终目标是对程序进行修补,以使我们在输入错误密钥后会收到成功消息。
在开始之前,因为我们要修改二进制文件,所以我更喜欢备份原始文件。
$ cp license_1 license_1.backup
让我们打开Cutter,然后从我们的计算机中选择license_1二进制文件。在下一个对话框中,确保选择“以写模式加载(-w)”。你可以保持其他设置不变,然后按确定。
通过从侧面的“函数”列表中选择它或通过在界面顶部的导航框中输入“main” ,进入主函数。main()函数虽然非常小,但却包含程序的所有逻辑。
函数main()只有6个模块,这使我们可以很容易地找到要修补的位置。确实,我们看到了具有strcmp比较的块,并且我们希望以一种方式来修补条件跳转,使其继续显示成功消息。通过将jne 0x400617(jump not equal)修改为je(jump equal),只要我们不提供正确的密钥,就将获得成功消息。
方法1:反向跳转
该方法最简单,也可能是最直观的方法。就是右键单击jne指令,然后选择“编辑->反向跳转”。
Cutter很智能,可以为我们检测出条件相反的指令。在本文的示例中,是从jne到je,反之亦然。
现在我们可以测试我们的更改是否确实有效,使用的密钥与我们之前尝试的相同。我们所做的更改会自动应用到二进制文件中,因此我们可以简单地测试它。
$ license_1 test_key Checking License: test_key WRONG!
可以看出,修补很容易。
方法2:直接从反编译器开始
如果你下载了官方发布版本,则Cutter应该附带一个集成的Ghidra反编译器,它的本地实现称为r2ghidra-dec。如果你自己构建Cutter,则还需要构建r2ghidra-dec。不过,只需按照链接中的说明进行操作即可。
通过“Windows -> Decompiler”打开反编译器窗口,然后找到main函数。现在,单击显示if (iVar1 == 0) {的行,然后再次转到“编辑>反向跳转”。
上图显示了Cutter中的强大反编译功能。
方法3:使用NOP指令
这是跳过检查并直接显示成功消息的另一种简便方法,只需在反汇编视图中右键单击条件,然后选择“Edit -> Nop指令”。
使用NOP指令之前:
0x00400602 call sym.imp.strcmp ; int strcmp(const char *s1, const char *s2) 0x00400607 test eax, eax 0x00400609 jne 0x400617 0x0040060b mov edi, str.Access_Granted
使用NOP指令之后:
0x00400602 call sym.imp.strcmp ; int strcmp(const char *s1, const char *s2) 0x00400607 test eax, eax 0x00400609 nop 0x0040060a nop 0x0040060b mov edi, str.Access_Granted
方法4:分解指令
在这种方法中,我们将指令本身从jne更改为je。再次右键单击条件,这次选择“编辑->指令”。然后只需将文本从jne 0x400617更改为je 0x400617。 Cutter将自动获取构成指令的字节的预览,最后按确定按钮即可。
方法5:组装字节
如果你厌倦了汇编方法,并想回到字节修补的旧时代并自己修改字节,那么只需转到“编辑->字节”并将750c更改为740c(从jne更改为je)。Cutter将向你显示预览,以确保你不会弄乱。
奖励:通过与Cutter一起使用radare2控制台
如果你熟悉radare2,你可能会很高兴知道Cutter将提供一个集成的radare2控制台。从“Windows -> Console” 打开它,然后开始输入你喜欢的r2命令。没错,你只需使用wx,wa等w命令从命令行修补字节即可。
总结
在本文中,我们了解Cutter的强大。期间,我们遇到了逆向工程人员经常面临的问题,并使用了5种不同的方法解决了这一问题。虽然还有更多修补字节的方法,例如,在Cutter中使用十六进制编辑器,但是这5种方法应该足够了!
发表评论