本帖最后由 海天一色001 于 2017-6-12 18:21 编辑
第11个CM程序,是andrénalin的第4个CM程序,比前3个要更复杂,只有一个Serial输入框,而且只能点击面板上的按钮来输入,输入不正确或者不输入时错误提示“UNREGISTRIERT(未注册)”已经显示在右侧了!应该是输入正确的注册码后右侧会显示正确提示吧!
没有确定之类的按钮,说明输入之后靠Timer控件来自动进行判断的。
先查壳:无壳,仍是VB编写的程序:
第一步,爆破:
程序载入OD中,习惯性地先查找字符串,找到了一堆这样的字符串!
“REGISTRIERT”是注册的意思,问题是怎么会有这么多呢?
而且上面还有一个长长的字符串“0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C”!这个字符串倒是有点像注册码的样子,可是在程序中无法输入字母啊!所以它可能只是一个注册码生成的结果来与它比较的字符串。
随意从中间点一个“REGISTRIERT”进入反汇编窗口:
注册成功的提示,那么向上查找关键跳:很快就看到了,这个VB的API函数__vbaVarTstEq的意思是是进行比较,如果两数不相等则跳过成功!
那么先在00406601处nop掉:
F9运行,程序已经显示“REGISTRIERT”了!
不会如此简单吧?先另存为Andrénalin.4”_nop_1.exe,再运行一下试试!
左侧是原程序运行的界面,是未注册的提示,右侧是爆破的程序,提示为注册!
又试了将其他地址处的跳转nop掉,效果和第1个爆破后的一样,估计是程序中的Timer控件会运行每一个判断,只要有一个是注册成功了,那么其他的判断都会被跳过吧,所以不需要把每个类似的跳转都nop掉。
第二步,追码:
在刚才爆破时地址004065F8处是调用MSVBVM60.__vbaVarTstEq函数进行比较,根据上两个CM的经验,那么每一个__vbaVarTstEq上面的循环(test eax,eax到jmp)就是程序Serial的算法。在循环头004064A8处下断,F9运行,程序马上中断,可我还没输入假码呢!再F9,仍然在此中断!所以先取消断点,F9运行,点击“8765432#”,再下断,再F9,程序断下来了,然后F8向下走,边走边检查寄存器、信息窗口、堆栈窗口的内容:
从堆栈窗口看到两处生成的字符串,一处是0012FADC处,下面0012FAEC处是每次所取字符转换来的16进制数值;
第二处是0012FB4C处,它的上方是输入的假码,下方是要比较的那一长串字符:
大致过程是取字符串前两位字符转换成浮点数值,存入堆栈SS:[0012FAAC]中;然后取假码的每一个字符,转换成10进制数值浮点数,加上前两位字符转换成的数值,再转换成16进制数值,把数值作为字符连接到一起,最前面加上“0”。
如我输入的“8765432#”,取前两位数值为87,加上“8”这个字符的10进制ASCII值为56,得143,再转换成16进制数值为0x8F,第二个字符为“7”,得到结果为142,16进制为0x8E;最终在整个连接的字符串加上“0”,就形成了“08F8E8D8C8B8A897A”这个字串。
和“0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C”相比,明显是不相等的。将这个注册码密钥字符串分开,得到如下16进制数值:“0x81;0x7E;0x74;0x7D;0x7A;0xFF;0x7C;0x7F;0x82;0x83;0x6D;0x74;0xRR;0x7A;0x7F;0x7E;0x7B;0x7C;0x7D;0x82;0x6D;0x81;0xKE;0x7B;0x7C”。等等!0xRR和0xKE是什么东西?这可不是16进制数啊!回到OD中,仔细查看中文搜索引擎窗口,才发现这么多的字符串中很多都不符合16进制数值的规则,连Z、G、K、U、V等字符都出来了!认真查看,只在004065E4处找到了一个符合规则的字符串“0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C”!双击进入反汇编窗口,注释的内容正常,信息窗口、堆栈窗口中字符串怎么又少了一位?返回中文搜索窗口,没错,最后有“C”。再次进入,还是少了一位!数了数,51个字符,可能在一行里显示不下吧。
可知对应关系为:
1—3D;2—3E;3—3F;4—40;5—41;6—42;7—43;8—44;9—45;0—3C;*—36;#—2F;这样的对应关系中没有一个能对上81的!
继续多输入几次新的注册码假码试一试:“9876543210*#”
1—9B;2--9A;3—99;4—98;5—97;6—96;7—95;8—94;9—93;0—92;*--8C;#--85;这样的对应关系也没有能对上81的;
多次试验,找到输入字符串存在堆栈0012FB3C处,生成的字符串存在0012FB4C处。由上面分析出的结果取字符串前两位的值加上第1位的值是第一个生成的字符串,所以反复输入两个数字,在堆栈中验证:
0012FB3C 00164AC4 UNICODE"8765432109*#"
0012FADC 00164BD4 UNICODE"08F8E8D8C8B8A89888790817A"
我开始输入的是“8765432109*#”,得到了“08F8E8D8C8B8A89888790817A”,第一个是8F,大于81。由于字符不多,得到的结果离81也很近,所以向下递减依次进行输入,结果也是依次减少1个,如下所示:
[Asm] 纯文本查看 复制代码 0012FB3C 00164AC4 UNICODE "87" 0012FB4C 00164AEC UNICODE "08F"
0012FB3C 00164AC4 UNICODE "86" 0012FB4C 00164B3C UNICODE "08E"
0012FB3C 00164AEC UNICODE "85" 0012FB4C 00164B64 UNICODE "08D"
0x8F-0x81=0xE(10进制就是14),那么87-14=73,输入73再试一试:
[Asm] 纯文本查看 复制代码 0012FB3C 00164B14 UNICODE "73" 0012FB4C 00164B64 UNICODE "080"
还不对,比81少了1,那么再换成“74”:
[Asm] 纯文本查看 复制代码 0012FB3C 00164B64 UNICODE "74" 0012FB4C 00164B14 UNICODE "081"
这次对上了!
74的值是74,“7”的10进制ASCII值是55,74+55=129,轮换成16进制数就是0x81!
相应的就可以算出其他字符对应的值了:7—0x81:8—0x82;9—0x83;6—0x80,这样计算挺麻烦,还是输入程序中看吧:
输入“74891234560*#”看看:
0012FB3C 00164B3C UNICODE"74891234560*#"
0012FB4C 00164B8C UNICODE"0817E82837B7C7D7E7F807A746D"
所以对应关系如下:0—7A;1—7B;2—7C;3—7D;4—7E;5—7F;6—80;7—81;8—82;9—83;*—74;#—6D。
注册码密钥为:“0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C”
注册码应该是:74*3032589#**0541238#7412。逐个点击输入,成功了!
计算方法用VB编程如下:
[Visual Basic] 纯文本查看 复制代码 Private Sub Command1_Click()
miyao ="817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C"
codice =""
For i = 1 To 50 Step 2
h16 = "&H" & Mid(miyao, i, 2)
asc10 = CInt(Val(h16))
code = Chr(asc10 - 74)
codice = codice & code
Next
Label2.Caption = "注册码(Serial)为:"& codice
End Sub
经过这些CM的练习,结合论坛中大神的建议,感觉CM程序作者基本上都未考虑界面美观或者是功能强大之类,界面本身都是非常简单的,汉化与否也都能大概知道意思,不必为了练习汉化拿这些CM入手,所以也就不再汉化了。
附件
011.rar
(16.27 KB, 下载次数: 20)
,含CM原程序、爆破程序及011注册机。
百度链接是:http://pan.baidu.com/s/1skMkJY9密码: 86pm,160个CM、我已练习过的前11个crackme程序都在里面。
|