文章目录
- 前言
- 题目分析
- 破解过程
- Serial/Name验证方式
- 爆破
- 注册机 追码
- Serial验证
前言
想开个系列,160个Crackme的练习,这个在52pojie上有个精华帖总结,写的特别好,推荐!写这个系列主要还是记录一下自己的学习记录,目前就完成了几十个,还有好多/(ㄒoㄒ)/~~,加油。坚持每天至少练一题,希望可以帮到你。
52pojie上用的是OD,OD很老了已经,而且我自己之前练的时候照着做也有几次出bug解决不了,后面改用的xdbg,所以推荐用xdbg来调试。
CrackMe 翻译是 破解我 ,我觉得蛮有趣的,可以很好的锻炼到逆向思维和动态调试能理,最主要的还是好玩,毕竟我觉得学习还是要以兴趣为主的。
题目在52pojie可以免费下载。
https://www.52pojie.cn/thread-709699-1-1.html
题目分析
- 文件位数:32bit
- 编程语言:Delphi
- 壳:无壳
要逆向或者破解一个程序,首先要了解它,先运行程序看看
俩个窗口,第一个无关紧要,第二个窗口有俩种验证方式。分别是:
- Serial/Name
- Serial
破解过程
Serial/Name验证方式
爆破
随便输入点东西运行看一下
打开x32dbg,搜索字符串,也可以点击上面工具栏。找到输入错误的提示。
双击过去,可以看到我们进入的位置是 0042FA63,我们一直往上翻可以找到一个 push ebp,对于一个程序的入口,一般都是push ebp,我们在程序入口打个断点方便调试。
打完断点就可以 Ctrl + F2 重启一下程序了,这次输入 sciurdae 123456看看,F9运行
点击 check后就会发现程序断在了 push ebp处。
这个时候就 F8 单步走,边走边看。
走到第一处错误信息,也是cmp 和 jge处
这里上面一直在调用sciurdae ,下面 cmp 用eax 和 4比较, jge 是大于等于就跳转的指令, 这里小于4的话就会直接错误了,可以知道这里是在要求name的长度要大于等于4。(爆破的话,讲jge改成jmp无条件跳转(按空格就可以修改))
再一直往下
这里可以看到我们输入的密码,和一串很可疑的字符串。
并且下面就是正确结果,有一个call 和一个 jne 跳转 ;jne指令的意思是 不等于就跳转
(我们也知道我们输入的肯定不是正确的serial,所以这里 就是 用 正确的和我们 的比较,最后验证会失败)
爆破就是将jne指令直接nop掉就好。
注册机 追码
刚刚在爆破的过程中,我们发现了一串可以的字符串,用它也可以完成注册;但是如果我们换一下name,这串serial就没有用了,说明,serial 是在程序中动态生成了,那么问题就来了?
如何在不改变程序的情况下,成功破解程序呢,这就是注册机了。
Keygen(注册机)是短语密钥生成器的缩写形式。这是一个小型程序,可为软件生成有效的CD密钥或序列号(注册)。
如何来实现这个注册机。
输入 123456 的name 方便调试。继续运行程序,让程序断在 push ebp处。
0042FA87 | 8B45 F0 | mov eax,dword ptr ss:[ebp-10] | [dword ptr ss:[ebp-10]]:"123456"
0042FA8A | 0FB600 | movzx eax,byte ptr ds:[eax] | 这里就是取了 '1' 出来存到 eax中;
0042FA8D | F72D 50174300 | imul dword ptr ds:[431750] | 用0x31('1') 去乘以 29 (ds:[431750]中的值)
0042FA93 | A3 50174300 | mov dword ptr ds:[431750],eax |
0042FA98 | A1 50174300 | mov eax,dword ptr ds:[431750] |
0042FA9D | 0105 50174300 | add dword ptr ds:[431750],eax | 前面用eax覆盖了ds:[431750]中,现在又加上eax,实际上就是 * 2 的操作
0042FAA3 | 8D45 FC | lea eax,dword ptr ss:[ebp-4] |
0042FAA6 | BA ACFB4200 | mov edx,acid burn.42FBAC | 42FBAC:"CW"
0042FAAB | E8 583CFDFF | call acid burn.403708 |
0042FAB0 | 8D45 F8 | lea eax,dword ptr ss:[ebp-8] | # 这里就是 连接上这俩个字符串
0042FAB3 | BA B8FB4200 | mov edx,acid burn.42FBB8 | 42FBB8:"CRACKED"
刚执行完 movzx后,的情况。
小端序存储,所以要读 07D9 ; 07D9 等于 0x29 * 0x31
执行add后, 0FB2 ; 0FB2 等于 07D9 * 2; 0x0FB2转换为十进制就是 4018
往下看验证一下,
没有问题!
Keygen:
def keygen(serial):
key = ord(serial[:1])
print(key)
if key > 0x21: # 要可见字符
key = key * 0x29 * 2
print(f"Serial: CW-{key}-CRACKED")
else:
print('input error !')
if __name__ == '__main__':
serial = input('please input something here:')
keygen(serial)
之前用C写的,试一试用 python写。
Serial验证
也是通过搜索字符串。往上看push ebp
爆破的话就是nop掉 jne 不让它跳到报错去就好。 这里serial也已经给出来了。
这个验证是固定的验证码,不用keygen了。
搞定。