crackme-系列之-crackme4
首先进行查壳

可以看到程序使用的Delphi编写的 没有加壳
导出符号
既然是delphi编写的 那么我们首先把他放到IDA里,把所有的关于Delphi的签名全部加上
ida会自动帮我们识别所有的Delphi的函数,可以看到添加签名之后 未识别的函数就只有那么一点点,剩下的都是库函数。
然后导出为MAP文件,导入到OD里(LoadMapEx),可以极大的减轻负担。
窗体分析
两个编辑框 一个图片显示框,据说是注册之后会显示一个朱茵的图片。没有按钮,没有提示

利用Delphi的反编译工具Darkde4进行查看
打开窗体部分,原来之前一直误以为的图片显示框是一个大按钮,这个按钮有两个对应事件, 分别是单击事件和双击事件
这里是整个程序的所有的响应事件 以及对应的RVA
- 第一个FormCreate是窗体的创建事件 这个不必关心,一般创建事件都是显示图形界面相关的操作
- 第二个事件名是chkcode,全称应该是checkcode,校验代码,至于校验的是什么代码?不知道
- 第三个KeyUp是响应的键盘的弹起
- 第四个DbClick是按钮的双击事件
- 第五个Click是按钮的单击事件
那么思路和突破口也就有了,对应单击和双击事件的RVA 直接去OD分析两个响应事件的具体实现部分。
OD分析
在单击事件的RVA 0x00457B8处下断点,随便输入一组用户名,从上往下分析所有的执行过程。
获取用户名
获取用户名长度 将长度加上0x1E
将长度转为字符串
字符串拼接 拼接为长度+用户名+循环次数
整个算法循环18次 最后的结果如上图
算法循环完了之后 比较[esi+0x30C]的值是否相等,如果不相等直接退出。如果相等,又是一轮重复的循环校验,接着提示注册成功。就是说前面的循环算法就是作者下的一个套,真正有用的部分就是这个比较,也就是[esi+0x30C] 的值必须是0x85。
结论
[esi+0x30C] 的值必须是0x85。
双击事件
通过Delphi的反编译工具Darkde4的过程窗口找到双击事件的RVA。下断点,分析。注意,在这之前必须取消单击事件的断点,否则无法断下来。
还是同样的套路,一轮循环的验证之后,才来到真正有用的部分。 [esi+0x30C]和0x3E作比较,如果成立,就把[esi+0x30C]赋值为0x85,也就满足了单击事件的条件。 也就是说必定有一个地方,是把[esi+0x30C]赋值为0x3E。如果满足了这个条件,那么双击事件校验通过,单击事件 也通过。
结论
[esi+0x30C]的值必须为0x3E
再次寻找突破口
根据双击事件经验 我们能猜测,肯定有一个地方是把0x3E赋值给了[esi+0x30C]。 那么我们直接在OD中,右键->查找所有常量,输入3E,看看能不能找到mov [esi+0x30C],0x3E这样一条指令。如果能,那么这个就是真正校验的地方。
拉到函数最上面
之前导入的IDA的注释显示这个是chkcode的校验事件。就是之前我们在Darkde4过程窗口里看到的checkcode的响应事件,这个应该就是真正的校验函数了。下断点,开始分析
chcode事件
首先获取用户名长度 然后将用户名长度+5,接着进行字符串拼接 拼接方式为黑头Sun Bird(用户名长度+5)dseloffc012-OK(用户名),拼接好的字符串就是密码。
结果
接着输入用户名和序列号,根据之前的分析过程 我们需要先双击,再单击才能够校验成功
但是这里需要注意一点,在过程窗口中有一个KeyUp键盘弹起事件,在你输入序列号的时候 他会检测是否有键盘弹起,如果没有则不成功,这样做的目的是为了防止复制粘贴。破解的方法也很简单,在复制粘贴完序列号之后随便 按一个键(比如方向键 这样不会影响到输入结果),接着双击再单击。可以看到,成功注册完成。

注册机编写
C
#include "pch.h" |
Python
print("please input username") |