『逆向』CrackMe007 逆向分析
工具安装
程序分析
点击help,可以看到提示:破解目标是使所有的按钮消失,让程序下面的蓝色logo完整显现出来,不允许爆破。
逆向分析
脱壳
用Exeinfo PE工具查看该程序,得到信息如下图,可知该程序没有加壳,用Delphi语言编写。
并不需要脱壳处理
DarkDe查看事件控件
因为是delphi的程序,先用Delphi的专用反编译工具DarkDe搜索涉及到的控件和事件函数信息
事件信息:
控件信息:
可以看到程序有以下几个事件:
- Cancella按钮的点击事件
- About按钮的点击事件
- Registerz按钮的点击事件
- Again按钮的点击事件
总共四个按钮事件。
在程序最开始并没有看到Again按钮,猜测为一个隐藏按钮。最开始只有一个Register按钮,因此我们后续就从Registerz按钮的点击事件开始分析。
爆破
将程序拖入ollydbg
分别在前面发现的事件对应的位置:00442B98,00442F28,004430BC上下断点
首先在Registerz按钮点击事件的位置 00442F28
下断点
运行程序,随便输入name = 123,Codice = 123,F8向下单步执行。
可以看到这里有两个calll,调用了两个函数,去对应的地址看一下,第一个函数为获取codice,第二个函数检测codice是否为纯数字。
继续单步执行,走到下面的 je
跳转代码后,跳转到了 00442F9D
。
分析下面的 je
跳转代码,可以知道这里对codice进行了验证,如果codice是纯数字则跳转到 00442F9D
继续执行,如果不是纯数字则会弹窗 "You MUST insert a valid Long Integer Value in the Code Editor... Thank you :)"
所以正常情况下应该执行 00442F9D
,观察 00442F9D
后的代码,可以看到走到 00442F9F
又会跳转到 00442FFB
,但是这个跳转处的注释为 “Please… The Code Must be >0”,很明显这是一个异常提示的跳转,所以在这里未发生跳转为程序正常执行
继续查看未发生跳转部分的汇编代码,可以看到 00442FC0
处存在第三个跳转到 00442FF2
,从 00442FF2
处向下看经过了 00442FFB
处也就是错误提示的字符串,所以在 00442FC0
处我们不让程序发生跳转,将 je 改为NOP
F9继续运行程序,可以看到register按钮消失,出现了新的按钮again,直接点击again,可以看到停在了我们前面打的断点 004430BC
处。
向下翻看代码发现和前面的register按钮函数类似,我们执行同样的操作,将找到的位置 00443159
改为NOPs。
F9继续运行,可以看到已经成功实现了logo的还原,成功爆破。
序号生成算法分析
根据前面的爆破可以知道,register按钮和again按钮消失的逻辑分别出现在 00442F9F
和 00443159
之后。
所以首先对register按钮的 00442F9F
进行分析,分析后面的代码可以知道 00442FB9
为算法函数
crtl + G 跟进到 00442FB9
查看算法函数,可以看到要求用户名要大于4个字符
在算法后续的计算中涉及到了 eax ,回到前面可以发现在00442FB9
的前面有一个对 eax进行赋值的操作: 00442FB4
位置对eax进行了赋值,将地址445830的数值赋给了eax。
再检查在什么地方对地址445830进行了赋值,在地址442FB4处[右键]-[查找参考]-[地址常量],可以查找到程序中所有涉及到这个地址常量的位置。
可以看到这个地址前面存在一个对445830进行赋值的操作,双击查看
可以看到,当Codice输入的不全是数字时才对[0x445830] 赋值操作,而所赋的值为 00442F81
处调用函数 00442A8C
的返回值
对00442A8C进行进一步分析,可以知道对应的[0x445830] 赋值方法
发现存在逻辑:
当第一次输入的密码不为纯数字的时候,程序会根据密码生成一个值 [0x445830]
,后续密码不为纯数字时需要根据这个值来进行运算,所以第一次输入的时候,密码一定要为纯字母,不然无法注册成功。
接下来进行了两层循环,计算的是用户名的第一位和最后一位的乘积,然后再乘以 [0x445830]
。外层循环变换用户名最后一位,每次往前移动一位。内层循环变换用户名第一位,每次往后移动一位。接着将结果保存到eax。
- 将eax对
0xA2C2A
取模,记为结果1 - 将输入的密码除以 0x59 加上密码mod0x50,结果再加1,记为结果2
- 比较结果1和结果2是否相等。相等则返回1,消失按钮。不相等则返回0。
again 按钮的函数算法类似
注册机
1 | import sys |
随便构造纯数字的name和全字母的codice
产生报错,用上面的注册机生成密码
输入生成的第一个codice,可以看到register按钮消失
再输入前面固定的字符串,点击again按钮
再输入前面注册机得到的codice,成功显现所有的Logo,完成破解