这里前几天那个ROR CRACKME的算法的一小部分,说实话下面的不是我不说,是我实在解不出来了.有朋友给我发信问算法怎么看出来的,其实是蒙出来的:D,把我蒙算法的过程贴出来,让高手笑话了.
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004031D0(U)
|
:00402AA0 64A100000000 mov eax, dword ptr fs:[00000000]
:00402AA6 6AFF push FFFFFFFF
:00402AA8 68FF534200 push 004253FF
:00402AAD 50 push eax
:00402AAE 64892500000000 mov dword ptr fs:[00000000], esp
:00402AB5 81ECE0000000 sub esp, 000000E0
:00402ABB 57 push edi
:00402ABC 8BF9 mov edi, ecx
:00402ABE 6800010000 push 00000100
:00402AC3 6890FE4200 push 0042FE90
:00402AC8 8D8FC0000000 lea ecx, dword ptr [edi+000000C0]
:00402ACE E82CDE0100 call 004208FF ;GetWindowText得用户名
:00402AD3 6800010000 push 00000100
:00402AD8 6888FD4200 push 0042FD88
:00402ADD 8D4F70 lea ecx, dword ptr [edi+70]
:00402AE0 E81ADE0100 call 004208FF ;GetWindowText得注册码
:00402AE5 A198FF4200 mov eax, dword ptr [0042FF98]
:00402AEA C70594FF420000000000 mov dword ptr [0042FF94], 00000000
:00402AF4 C7803402000010000000 mov dword ptr [ebx+00000234], 00000010
:00402AFE B890FE4200 mov eax, 0042FE90
:00402B03 8D5001 lea edx, dword ptr [eax+01]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B0B(C)
|
:00402B06 8A08 mov cl, byte ptr [eax]
:00402B08 40 inc eax
:00402B09 84C9 test cl, cl
:00402B0B 75F9 jne 00402B06
:00402B0D 2BC2 sub eax, edx ;用这种方法得到用户名长度
:00402B0F 89442404 mov dword ptr [esp+04], eax
:00402B13 7529 jne 00402B3E ;长度不能为0
:00402B15 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Enter a Name"
|
:00402B17 68A46A4200 push 00426AA4
* Possible StringData Ref from Data Obj ->"You need a name!"
|
:00402B1C 68906A4200 push 00426A90
:00402B21 8BCF mov ecx, edi
:00402B23 E80DB50100 call 0041E035
:00402B28 5F pop edi
:00402B29 8B8C24E0000000 mov ecx, dword ptr [esp+000000E0]
:00402B30 64890D00000000 mov dword ptr fs:[00000000], ecx
:00402B37 81C4EC000000 add esp, 000000EC
:00402B3D C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B13(C)
|
:00402B3E B888FD4200 mov eax, 0042FD88
:00402B43 8D5001 lea edx, dword ptr [eax+01]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B4B(C)
|
:00402B46 8A08 mov cl, byte ptr [eax]
:00402B48 40 inc eax
:00402B49 84C9 test cl, cl
:00402B4B 75F9 jne 00402B46
:00402B4D 2BC2 sub eax, edx ;注册码长度
:00402B4F 89442404 mov dword ptr [esp+04], eax
:00402B53 7529 jne 00402B7E ;不能为0
:00402B55 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Try KG me"
|
:00402B57 68846A4200 push 00426A84
* Possible StringData Ref from Data Obj ->"You need a valid SN, keep going!"
|
:00402B5C 68606A4200 push 00426A60
:00402B61 8BCF mov ecx, edi
:00402B63 E8CDB40100 call 0041E035
:00402B68 5F pop edi
:00402B69 8B8C24E0000000 mov ecx, dword ptr [esp+000000E0]
:00402B70 64890D00000000 mov dword ptr fs:[00000000], ecx
:00402B77 81C4EC000000 add esp, 000000EC
:00402B7D C3 ret
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B53(C)
|
:00402B7E B888FD4200 mov eax, 0042FD88
:00402B83 8D5001 lea edx, dword ptr [eax+01]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402B8B(C)
|
:00402B86 8A08 mov cl, byte ptr [eax]
:00402B88 40 inc eax
:00402B89 84C9 test cl, cl
:00402B8B 75F9 jne 00402B86
:00402B8D 2BC2 sub eax, edx ;注册码长度
:00402B8F 83F81D cmp eax, 0000001D
:00402B92 53 push ebx
:00402B93 0F8589050000 jne 00403122 ;必须等于1Dh,即29
:00402B99 A08DFD4200 mov al, byte ptr [0042FD8D]
:00402B9E B32D mov bl, 2D
:00402BA0 3AC3 cmp al, bl
:00402BA2 0F857A050000 jne 00403122
:00402BA8 381D93FD4200 cmp byte ptr [0042FD93], bl
:00402BAE 0F856E050000 jne 00403122
:00402BB4 381D99FD4200 cmp byte ptr [0042FD99], bl
:00402BBA 0F8562050000 jne 00403122
:00402BC0 381D9FFD4200 cmp byte ptr [0042FD9F], bl
:00402BC6 0F8556050000 jne 00403122 ;比较第6,12,18,24位是否'-'
:00402BCC 56 push esi ;即注册码格式为xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
:00402BCD 6A00 push 00000000
:00402BCF 8D4C2418 lea ecx, dword ptr [esp+18]
:00402BD3 E898F8FFFF call 00402470
:00402BD8 B888FD4200 mov eax, 0042FD88
:00402BDD C78424F400000000000000 mov dword ptr [esp+000000F4], 00000000
:00402BE8 33F6 xor esi, esi
:00402BEA 8D5001 lea edx, dword ptr [eax+01]
:00402BED 8D4900 lea ecx, dword ptr [ecx+00]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402BF5(C)
|
:00402BF0 8A08 mov cl, byte ptr [eax]
:00402BF2 40 inc eax
:00402BF3 84C9 test cl, cl
:00402BF5 75F9 jne 00402BF0
:00402BF7 2BC2 sub eax, edx
:00402BF9 8944240C mov dword ptr [esp+0C], eax
:00402BFD 7473 je 00402C72
:00402BFF 90 nop
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402C70(C)
|
:00402C00 389E88FD4200 cmp byte ptr [esi+0042FD88], bl;开始一个循环,依次取注册码每位
:00402C06 7454 je 00402C5C ;如果是'-'则忽略
:00402C08 6A18 push 00000018 ;这里压入一个18
:00402C0A 8D4C2418 lea ecx, dword ptr [esp+18]
:00402C0E E89DF8FFFF call 004024B0 ;这个CALL里面很麻烦,我没看懂,但猜出来了,应该是高精度乘法的计算.
:00402C13 0FB68E88FD4200 movzx ecx, byte ptr [esi+0042FD88]
:00402C1A 51 push ecx
:00402C1B 6888674200 push 00426788
:00402C20 E82BD70000 call 00410350 ;这个CALL是在上面串里找注册码字符
:00402C25 83C408 add esp, 00000008
:00402C28 85C0 test eax, eax
:00402C2A 7426 je 00402C52 ;找不到EAX=0,跳了
:00402C2C 0FB69688FD4200 movzx edx, byte ptr [esi+0042FD88]
:00402C33 52 push edx
:00402C34 6888674200 push 00426788
:00402C39 E812D70000 call 00410350 ;还是上面的查找CALL
:00402C3E 83C408 add esp, 00000008 ;找到会返回一个指向字串中该字符的地址
:00402C41 2D88674200 sub eax, 00426788 ;减去首字符的地址就是这个字符的"相对位置"
:00402C46 50 push eax ;压入这个相对位置
:00402C47 8D4C2418 lea ecx, dword ptr [esp+18]
:00402C4B E840F8FFFF call 00402490 ;这个是高精度加法,结果仍在CC1E5C
:00402C50 EB0A jmp 00402C5C ;如找到就跳过下一句
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402C2A(C)
|
:00402C52 C70594FF420001000000 mov dword ptr [0042FF94], 00000001 ;找不到来这里[42FF94]=1
;重要标志,见下
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402C06(C), :00402C50(U)
|
:00402C5C B888FD4200 mov eax, 0042FD88
:00402C61 46 inc esi
:00402C62 8D5001 lea edx, dword ptr [eax+01]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402C6A(C)
|
:00402C65 8A08 mov cl, byte ptr [eax]
:00402C67 40 inc eax
:00402C68 84C9 test cl, cl
:00402C6A 75F9 jne 00402C65
:00402C6C 2BC2 sub eax, edx
:00402C6E 3BF0 cmp esi, eax ;得到长度作比较
:00402C70 728E jb 00402C00 ;取完每一个字符为止
这是判断的最后阶段:
:00402FD8 8D4C2408 lea ecx, dword ptr [esp+08]
:00402FDC 51 push ecx
:00402FDD 8D542420 lea edx, dword ptr [esp+20]
:00402FE1 52 push edx
:00402FE2 C68424F800000015 mov byte ptr [esp+000000F8], 15
:00402FEA E8E1F4FFFF call 004024D0 ;不知道干的啥,关键CALL
:00402FEF 83C408 add esp, 00000008
:00402FF2 85C0 test eax, eax
:00402FF4 7417 je 0040300D ;EAX=0就死
:00402FF6 A194FF4200 mov eax, dword ptr [0042FF94] ;这里,上面的标志[42FF94]
:00402FFB 85C0 test eax, eax
:00402FFD 750E jne 0040300D ;不等0就死,所以我说注册码必须在那个字符串内
:00402FFF 6A30 push 00000030
* Possible StringData Ref from Data Obj ->"Congratulations!"
|
:00403001 684C6A4200 push 00426A4C
* Possible StringData Ref from Data Obj ->"You did it, send the keygen and "
->"src to [email]rorteam@hotbox.ru[/email] to get "
->"access to TEAM ROR"
|
:00403006 68F8694200 push 004269F8
:0040300B EB0C jmp 00403019
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00402FF4(C), :00402FFD(C)
|
:0040300D 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Keep going!"
|
:0040300F 68E4694200 push 004269E4
* Possible StringData Ref from Data Obj ->"You almost there, check it carefully"
|
:00403014 68BC694200 push 004269BC
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040300B(U)
|
:00403019 8BCF mov ecx, edi
:0040301B E815B00100 call 0041E035
关于那个CALL的高精度计算看不懂又怎么猜出来的,这个我想应该说是"直觉"吧.第一次过这个CALL的时候因为全是0,乘18还是0,所以什么也没发现.然后往下走,那个查找字符的CALL好说一些,看明白了,(其实也完全可以猜出来)然后就到了那个402C48的CALL,因为上面有一个ECX,我直觉感到它应该和CALL返回值的地址有关,进了CALL还是很乱,出来以后看ECX,ECX=CC1E50没发现什么,但ECX后面有一个CC1E5C,这个地方出现了一个29.因为我第一个字符输入的'2',在那个字串中的相对位置为11,上面又压入了一个参数18,呵呵~~~~,发现了吧,就是一个加法喽!接着又返回去,又压入一个18,到了402C0E处的CALL,出来后CC1E5C处又变了,但这回要大好多,不可能是加法的,那是什么呢?是乘以18吗?验证一下,果然是!有前辈说到CRACK是需要一点运气的,确实没错.
然后就好说了,为什么乘法加法要那么复杂呢,因为要进行大整数的运算,只是18的25次方就够大了吧.最后我的注册码计算结果是15个字节,也就是120位的数.:)
后面就看不明白了,我的运气也不管用了,还请高手解决.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)