目录
逆向工程之逆向分析实战(二):深度破解 “crack me” 程序
在逆向工程的实战中,我们继续探索破解 “crack me” 程序的方法,这次将采用修改程序指令的方式来绕过验证,同时也会对比不同破解方法的优劣,并分享逆向分析的建议和作业内容。
一、实战内容介绍
(一)目标
本次实战仍然围绕 “crack me” 程序展开,目的是通过修改程序的指令,使其跳过原有的验证过程,实现无需特定的 “k file.date” 文件及其中特定内容就能正常使用程序。
(二)原理
基于对程序二进制文件的修改来改变程序的执行逻辑。程序在运行过程中通过一系列的条件判断(如文件是否存在、文件内容是否符合要求等)来决定是否继续执行或报错。我们利用一个名为 “k patch” 的插件,在反汇编代码层面修改这些条件判断指令(如 JNZ 等跳转指令),从而改变程序的执行路径,绕过验证。
二、逆向分析步骤
(一)准备工作
确保已经拥有 “crack me.exe” 程序,并将其放置在虚拟机中。同时,我们需要使用老师提供的工具,包括 IDA 等逆向分析工具,并且已经在虚拟机中安装好相关插件,如 editor 里面的 “k patch”。
(二)重命名 “k file.date” 文件
将 “k file.date” 文件重命名,模拟没有该文件的情况。因为在正常情况下,程序会对该文件进行验证,而我们要突破这种验证机制。
(三)使用 IDA 和 “k patch” 修改程序指令
- 分析首次跳转指令
- 启动 IDA(这里假设是 IDA32,因为之前分析得知程序是 32 位的),通过 “File” -> “Open” 打开 “crack me.exe” 程序。在 IDA 的反汇编代码中找到程序开始阶段因缺少 “k file.date” 文件而导致报错的跳转指令(如 JNZ 指令)。
- 利用 “k patch” 插件进行修改。在 IDA 界面中找到相关指令后,右键点击,选择 “k patch”,然后在弹出的界面中将 JNZ(非零跳转)改成 JZ(零跳转)。修改完成后点击 “patch” 按钮。这样,程序在执行到此处时的跳转方向就会与原来相反,从而避免因找不到文件而报错。
- 处理后续报错跳转指令
- 继续运行程序,会发现还存在其他因缺少文件内容而导致的报错跳转。同样的道理,找到这些跳转指令(如在读取文件内容相关操作附近的跳转指令)。
- 再次使用 “k patch” 插件,右键点击相应指令,进行 patch 修改,改变其跳转条件。例如,如果是类似 JNZ 的指令,根据情况将其改成 JZ 或者其他合适的指令,以改变程序的执行路径,使其跳过报错环节。
- 处理与文件内容验证相关的跳转指令
- 程序在运行过程中还会对 “k file.date” 文件内容进行验证,比如判断某个寄存器(如 ESI)的值是否满足条件(如是否等于 8)。当我们没有该文件时,这些验证会导致报错。
- 找到这些与文件内容验证相关的跳转指令,通过 “k patch” 插件修改其跳转条件,让程序能够继续执行,而不因为验证不通过而报错。
(四)动态分析验证修改效果
- 设置断点与调试准备
- 在 IDA 中利用其动态分析功能。在关键代码处设置断点,例如在修改后的跳转指令附近或者其他重要的验证代码处。选择合适的分析器(如对于这个 Windows 程序选择 “local windows debug”),然后点击执行。
- 单步执行与观察状态
- 程序运行到断点处后,可以使用快捷键 F7(步进进入此函数)或 F8(不进入此函数)进行单步执行。在执行过程中,观察寄存器的值、栈的状态等信息,查看程序是否按照我们修改后的逻辑执行,是否成功跳过了所有的验证环节。
(五)保存修改后的程序
- 应用修改并备份
在 editor 中找到 “patch program” 选项,点击应用,将我们刚才对程序的修改保存。同时,注意点击 “crack back back up”,这会将修改后的程序保存为 “crack me.exe”,并将修改之前的程序备份,文件名后面加上 “.BAK”。
(六)测试修改后的程序
- 运行测试
此时,即使没有 “k file.date” 文件,直接运行修改后的 “crack me.exe” 程序,应该可以正常使用。可以将其复制到其他位置进行测试,验证破解是否成功。
三、两种破解方法对比
(一)基于条件分析的方法
这种方法是通过精确找出程序的验证条件,然后满足这些条件来破解程序。例如,之前我们分析出破解 “crack me” 程序需要在同目录下存在 “k file.date” 文件,该文件至少包含 16 个字符,且字符中至少有 8 个是‘G’。这种方法的优势在于没有改变程序原有的执行路径,程序的功能能够正常发挥。但缺点是花费的功夫较大,需要准确找出所有的验证条件。
(二)基于修改判定条件的方法(本次实战方法)
通过修改程序的判定条件(如跳转指令)来绕过验证。优点是比较简单,可以直接改变程序的执行走向。缺点是对于一些复杂的程序,这种修改可能会使程序无法正常运行。因为可能存在程序后面的正常功能依赖于前面被跳过的验证环节中的数据,如果跳过验证,这些功能可能会出错。
四、逆向分析建议
(一)注意编码风格
有编程经验有助于逆向分析。了解开发者的编程方式,能更好地理解程序,因为正向编程和逆向分析是相互关联的,知道正常的编程逻辑有助于推测程序在逆向时的功能。
(二)遵循集中原则
程序员在开发程序时,往往将功能相关的代码或数据写在同一个地方。如果某一行代码不理解,可以查看周围相关的部分,因为这一块地方可能具有相同或相似的功能。
(三)关注代码复用
在编写程序时,代码复用很普遍。了解这一点可以帮助我们在逆向分析时,根据开发人员的编程习惯,更容易猜测和判断程序的功能。总体而言,逆向分析需要七分猜测三分拆解,但这种猜测不是瞎猜,要根据经验和程序语句进行,并且猜测后还要进行验证。
(四)区分代码
要能区分哪些代码是人为编写的,哪些是编译器自动附加的。虽然像 IDA 这样的工具很强大,但它的分析结果也不是百分之百正确的。
(五)保持耐心
逆向工程有一定难度,尤其是在刚开始对逆向流程和汇编语言不熟悉的时候。可能做一个简单的题目都需要几个小时,这是正常的。坚持练习和学习,随着经验的积累会逐渐熟悉。
五、推荐书籍与作业
(一)推荐书籍
推荐《C 和指针》,这本书讲解了 C 语言中的指针,而指针是 C 语言的精髓,在汇编中指针与寻址相关,寻址又是汇编语言的核心内容。还有《汇编语言》(清华出版社第三版),对汇编讲解得很好。此外,《恶意代码分析实战》介绍了很多逆向分析的方法和工具,《深入理解计算机系统》《C++》等书籍也有助于提升相关知识,大家可以在闲暇时间学习。
(二)作业
作业是和田丸实验室逆向游乐园的 1 - 3 关。大家可以登录相关平台创建实验机(实验机是准备好的模拟环境,题目和工具都在里面),按照实验简介、预备知识、实验目的和实验步骤进行练习,主要目的是让大家练习逆向分析技能。
希望通过这次实战和相关内容分享,大家能对逆向分析有更深入的理解和实践能力。如果在过程中有任何问题,可以在群里向老师和同学提问。
“k patch”插件是什么?