破解教程 第20课 预备篇-----注册算法分析

Cruehead CrackMe v1.0教程
Cruehead CrackMe v1.0/v2.0 & v3.0 - CrackMe软件包下载(180k).
推荐大家做这几个CrackMe, Cruehead通过它介绍了最简单的算法概念 ,尤其是异或XOR运算. 运行CrackMe,输入你的注册信息,下中断bpx Hmemcpy 或 GetDlgItemTextA,F10步进或F12来到下面
:00401223 CMP EAX,00000000<--输名字了没有
:00401226 JE 004011E6 <-- 没有输名字就跳走,这里不能跳
:00401228 PUSH 0040218E <-- 输入的名字存入40218E
:0040122D CALL 0040137E <-- 一会儿追入研究
:00401232 PUSH EAX <-- 根据名字运算及XOR后的结果存入EAX
:00401233 PUSH 0040217E <-- 输入的注册码存入40217E
:00401238 CALL 004013D8 <-- 一会儿追入研究
:0040123D ADD ESP,04 <-- 清空栈
:00401240 POP EAX <--EAX出栈
:00401241 CMP EAX,EBX <-- 关键比较
:00401243 JZ 0040124C <-- 相等跳向成功处
此程序就这样很容易就被破解了, 但我们的目的是研究此CrackMe的算法。因此我们需要追入0040137E和 004013D8.
:0040137E MOV ESI,[ESP+04] <--输入的名字
:00401382 PUSH ESI <-- 进栈
:00401383 MOV AL,[ESI] <-- AL = 姓名的第1个字母
:00401385 TEST AL,AL <-- 判断是否等于0.
:00401387 JZ 0040139C <-- 等于0就跳
:00401389 CMP AL,41 <-- 将它与41 或 'A'进行比较
:0040138B JB 004013AC <-- 小于'A'就跳
:0040138D CMP AL,5A <-- 将它与5A 或 'Z'进行比较.
:0040138F JNB 00401394 <-- 不小于'Z'就跳.
:00401391 INC ESI <-- 姓名的计数器.
:00401392 JMP 00401383 <-- 重复测试
:00401394 CALL 004013D2 <-- 大于 'Z'跳到这里.
:00401399 INC ESI <-- 姓名的计数器
:0040139A JMP 00401383 <-- 重复测试.
这段代码检查输入姓名中的字母是否介于A和Z之间,如果是小写字母就执行00401394处的CALL,它包含经典的 SUB AL,20大写化程式。到这里我们的名字完全成了大写,继续向下追踪 (仍然在 0040137E的CALL 里面) 直到004013C2.
:004013C2 XOR EDI,EDI <-- EDI=0.
:004013C4 XOR EBX,EBX <-- EBX=0.
:004013C6 MOV BL, BYTE PTR [ESI] <-- 指针指向姓名
:004013C8 TEST BL,BL <-- 检查姓名是否已结束
:004013CA JZ 004013D1 <-- 循环结束则跳走
:004013CC ADD EDI,EBX <-- EDI+EBX,结果存入EDI
:004013CE INC ESI <-- 计数器
:004013CF JMP 004013C6 <-- 再此循环
所以,上面就是将姓名的所有字母的ASCII码相加,相加的结果存入EDI. 对我而言,就是:
CRACKZ = 43 + 52 + 41 + 43 + 4B + 5A = 19Eh.  h表示十六进制
最后的重要操作:
:004013A2 XOR EDI,00005678 <-- 姓名字符的和 XOR 5678
:004013A8 MOV EAX,EDI <-- 赋给EAX.
对我而言,XOR后的结果是57E6h。
现在追入004013D8:
:004013D8 XOR EAX,EAX <-- EAX=0.
:004013DA XOR EDI,EDI <-- EDI=0.
:004013DC XOR EBX,EBX <-- EBX=0.
:004013DE MOV ESI,[ESP+04] <-- 输入的序列号
:004013E2 MOV AL,0A <-- AL=10.
:004013E4 MOV BL, BYTE PTR [ESI] <--指针指向ESI.
:004013E6 TEST BL,BL <-- 检查注册码是否已结束.
:004013E8 JZ 004013F5 <-- 循环结束则跳走
:004013EA SUB BL,30
:004013ED IMUL EDI,EAX
:004013F0 ADD EDI,EBX <-- EDI储存运算的结果
:004013F2 INC ESI <-- 序列号的计数器
:004013F3 JMP 004013E2 <-- 循环重复.
:004013F5 XOR EDI,00001234 <-- 最后的XOR运算.
:004013FB MOV EBX,EDI <-- 存入EBX , return 返回进行比较.
有事一个循环的操作, 它实际上是将十进制的序列号转化为十六进制HEX, 序列号123456算出结果是1e240h ,它 XOR 00001234得到1f074h. 因此,正确序列号运算后的结果必须等于57e6h (根据姓名算出来的,看上面)
我的序列号是:
57E6h XOR 1234h = 45D2h = 17874
XOR - 简介
a和b XOR的结果计为x:
a b x
0 0 0
0 1 1
1 0 1
1 1 0

5 7 E 6 = (binary) 0101 0111 1110 0110
1 2 3 4 = (binary) 0001 0010 0011 0100
> XOR的结果 = 0100 0101 1101 0010 = 45D2h = 17874 十进制

 

你可能感兴趣的:(c,算法,测试,byte,破解,hex)