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 十进制 |