看雪提供的一个习题,
chap6-1-1-01,就是序列号第一个.
试着做了下,晕头转向的,追啊追看着004010B0 处的CALL超级不顺眼,在00401099下了
断,跟进了004010B0到了004010C9,然后是分析算法.
00401099 |. 6A 0A PUSH 0A ; /Count = A (10.)
0040109B |. 68 44304000 PUSH crackme.00403044 ; |Buffer = crackme.00403044
004010A0 |. 68 B80B0000 PUSH 0BB8 ; |ControlID = BB8 (3000.)
004010A5 |. FF35 54304000 PUSH DWORD PTR DS:[403054] ; |hWnd = NULL
004010AB |. E8 D2000000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
004010B0 |. E8 14000000 CALL crackme.004010C9
004010B5 |> EB 09 JMP SHORT crackme.004010C0
004010B7 |> B8 00000000 MOV EAX,0
004010BC |. C9 LEAVE
004010BD |. C2 1000 RET 10
004010C0 |> B8 01000000 MOV EAX,1
004010C5 |. C9 LEAVE
004010C6 \. C2 1000 RET 10
004010C9 /$ 56 PUSH ESI
004010CA |. 57 PUSH EDI
004010CB |. 51 PUSH ECX
004010CC |. 33F6 XOR ESI,ESI
004010CE |. 33FF XOR EDI,EDI
004010D0 |. B9 08000000 MOV ECX,8 ;定义循环次数
004010D5 |. BE 44304000 MOV ESI,crackme.00403044 ;载入输入的密码
004010DA |> 8036 32 /XOR BYTE PTR DS:[ESI],32 ;各个位进行与32的异或
004010DD |. 46 |INC ESI ;++
004010DE |.^ E2 FA \LOOPD SHORT crackme.004010DA ;+
004010E0 |. BE 44304000 MOV ESI,crackme.00403044 ;下面是把变化后的密码前后取异或
004010E5 |. B9 04000000 MOV ECX,4 ; 8变4
004010EA |> 8A06 /MOV AL,BYTE PTR DS:[ESI]
004010EC |. 8A5E 01 |MOV BL,BYTE PTR DS:[ESI+1]
004010EF |. 32C3 |XOR AL,BL
004010F1 |. 8887 4C304000 |MOV BYTE PTR DS:[EDI+40304C],AL
004010F7 |. 83C6 02 |ADD ESI,2
004010FA |. 47 |INC EDI
004010FB |.^ E2 ED \LOOPD SHORT crackme.004010EA ;END 异或.
004010FD |. BE 4C304000 MOV ESI,crackme.0040304C ;下面再次把变化后的四位进行前后异或
00401102 |. 8A06 MOV AL,BYTE PTR DS:[ESI] ;4位变2位
00401104 |. 8A5E 01 MOV BL,BYTE PTR DS:[ESI+1]
00401107 |. 32C3 XOR AL,BL
00401109 |. 8A5E 02 MOV BL,BYTE PTR DS:[ESI+2]
0040110C |. 8A4E 03 MOV CL,BYTE PTR DS:[ESI+3]
0040110F |. 32D9 XOR BL,CL
00401111 |. 32C3 XOR AL,BL ;终于2位变成一个了.....
00401113 |. B9 08000000 MOV ECX,8 ; 然后再同上面异或过32的8个数异或
00401118 |. BE 44304000 MOV ESI,crackme.00403044
0040111D |> 3006 /XOR BYTE PTR DS:[ESI],AL
0040111F |. 46 |INC ESI
00401120 |.^ E2 FB \LOOPD SHORT crackme.0040111D ;终于异或结束...汗
00401122 |. B9 08000000 MOV ECX,8 ;下面是比较
00401127 |. BE 44304000 MOV ESI,crackme.00403044 ;取上面异或过的八个数
0040112C |. BF 08304000 MOV EDI,crackme.00403008 ;取真正数
00401131 |> 8A06 /MOV AL,BYTE PTR DS:[ESI] ;
00401133 |. 3A07 |CMP AL,BYTE PTR DS:[EDI] ;比较咯...
00401135 |. 75 1D |JNZ SHORT crackme.00401154 ;不等就跳,跳就死~~爆破把这句NOP了就行吧.
00401137 |. 46 |INC ESI
00401138 |. 47 |INC EDI
00401139 |.^ E2 F6 \LOOPD SHORT crackme.00401131 ;循环比较
0040113B |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040113D |. 68 35304000 PUSH crackme.00403035 ; |Title = "Crackme 1.0"
00401142 |. 68 10304000 PUSH crackme.00403010 ; |Text = "Good Work Cracker"
00401147 |. FF35 54304000 PUSH DWORD PTR DS:[403054] ; |hOwner = NULL
0040114D |. E8 3C000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
00401152 |. EB 17 JMP SHORT crackme.0040116B
00401154 |> 6A 30 PUSH 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401156 |. 68 35304000 PUSH crackme.00403035 ; |Title = "Crackme 1.0"
0040115B |. 68 22304000 PUSH crackme.00403022 ; |Text = "Bad Serial, Sorry!"
00401160 |. FF35 54304000 PUSH DWORD PTR DS:[403054] ; |hOwner = NULL
00401166 |. E8 23000000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
0040116B |> 5F POP EDI
0040116C |. 5E POP ESI
0040116D |. 59 POP ECX
0040116E \. C3 RET
算法是知道大概干什么了,可是怎么逆下去?我是搞不定了.看了看看雪的答案:
如果输入12345678
机器码 31 32 33 34 35 36 37 38
与32异或 03 00 01 06 07 04 05 0A ----(1)
8变4为 03 07 03 0F
4变2为 04 0C
2变1为 08 ----(2)
(1)与08取异或 0B 08 09 0E 0F 0C 0D 02
00403008 内正确的为 71 18 59 1B 79 42 45 4C
根据正确反推注册码: (关键是如何计算(2))
由算法可知(2)是由机器码反复取异或得到,其实由它的正确的密码重复这一算法也可求的(2),实验得出。缺少证明。
机器码 71 18 59 1B 79 42 45 4C
8变4为 69 42 3B 09
4变2为 2B 32
2变1为 19 ----正确的密码的(2)值应为19
接着反推正确的注册码:
机器码 71 18 59 1B 79 42 45 4C
与19取异或 68 01 40 02 60 5B 5C 55
与32取异或 5A 33 72 30 52 69 6E 67
查表得正确的注册码为: Z 3 r 0 R i n g (Z3r0Ring)
没看明白,为什么要用00403008的值进行反复异或....得到的怎么就是真的了..它也说缺少证明他是怎么知道的.晕
路漫漫啊.
望高人提点下吧.
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!