-
-
[原创]一个CRACKME的算法分析
-
发表于:
2006-7-3 20:44
5947
-
【作者邮箱】: bxm78@163.com
【保护方式】: name、serial
【编写语言】: Borland C++
【使用工具】: od peid
【操作平台】: xinxp
【作者声明】: 只是感兴趣,失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
用peid查壳,无壳,用OD载入,运行,下断点GetWindowTextA,填入name与serial,成功断在下面:
00401097 |. E8 129C0000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA
0040109C |. 6A 68 push 68 ; /ControlID = 68 (104.)
0040109E |. 53 push ebx ; |hWnd
0040109F |. E8 FE9B0000 call <jmp.&USER32.GetDlgItem> ; \GetDlgItem
004010A4 |. 6A 64 push 64 ; /Count = 64 (100.)
004010A6 |. 8D8D E4FEFFFF lea ecx, [ebp-11C] ; |
004010AC |. 51 push ecx ; |Buffer
004010AD |. 50 push eax ; |hWnd
004010AE |. E8 FB9B0000 call <jmp.&USER32.GetWindowTextA> ; \GetWindowTextA
004010B3 |. 6A 67 push 67 ; /ControlID = 67 (103.)
004010B5 |. 53 push ebx ; |hWnd
004010B6 |. E8 E79B0000 call <jmp.&USER32.GetDlgItem> ; \GetDlgItem
004010BB |. 8BF0 mov esi, eax
004010BD |. 8D85 48FFFFFF lea eax, [ebp-B8]
004010C3 |. 50 push eax
004010C4 |. E8 67050000 call 00401630
004010C9 |. 59 pop ecx
004010CA |. 8945 D8 mov [ebp-28], eax
004010CD |. 8D95 E4FEFFFF lea edx, [ebp-11C]
004010D3 |. 52 push edx
004010D4 |. E8 57050000 call 00401630
004010D9 |. 59 pop ecx
004010DA |. 68 EAB04000 push 0040B0EA
004010DF |. E8 4C050000 call 00401630
004010E4 |. 59 pop ecx
004010E5 |. 68 0EB14000 push 0040B10E
004010EA |. E8 41050000 call 00401630
004010EF |. 59 pop ecx
004010F0 |. 837D D8 03 cmp dword ptr [ebp-28], 3 ; name长度<4 ?
004010F4 |. 7E 7B jle short 00401171 ; 是,出错提示
004010F6 |. 90 nop
004010F7 |. 90 nop
004010F8 |. 90 nop
004010F9 |. 90 nop
004010FA |. 33C9 xor ecx, ecx
004010FC |. 33D2 xor edx, edx
004010FE |. 33DB xor ebx, ebx
00401100 |. 33C0 xor eax, eax
00401102 |. 837D D8 32 cmp dword ptr [ebp-28], 32 ; name长度>50 ?
00401106 |. 7D 69 jge short 00401171 ; 是,出错提示
00401108 |. 90 nop
00401109 |. 90 nop
0040110A |. 90 nop
0040110B |. 90 nop
0040110C |> 0FBE840D 48FF>/movsx eax, byte ptr [ebp+ecx-B8] ; 循环调入每个字符到EAX
00401114 |. 41 |inc ecx
00401115 |. 33C1 |xor eax, ecx ; ECX xor EAX,结果存入EAX
00401117 |. 03D8 |add ebx, eax ; eax累加于ebx
00401119 |. 3B4D D8 |cmp ecx, [ebp-28] ; 取完字符没有?
0040111C |.^ 75 EE \jnz short 0040110C ; 没取完继续
0040111E |. 6BC0 06 imul eax, eax, 6 ; (name最后一个字符 xor 长度)*6
00401121 |. C1E3 07 shl ebx, 7 ; 左移7位
00401124 |. 03C3 add eax, ebx ; 累加于eax
00401126 |. 8945 C8 mov [ebp-38], eax ; 最终累加和存入[ebp-38]
00401129 |. FF75 C8 push dword ptr [ebp-38] ; /Arg3
0040112C |. 68 38B44000 push 0040B438 ; |Arg2 = 0040B438 ASCII "%lX"
00401131 |. 8D8D 80FEFFFF lea ecx, [ebp-180] ; |
00401137 |. 51 push ecx ; |Arg1
00401138 |. E8 873D0000 call 00404EC4 ; \把十六进制数转换成字符串,即注册码
0040113D |. 83C4 0C add esp, 0C
00401140 |. 8D85 80FEFFFF lea eax, [ebp-180]
00401146 |. 50 push eax ; /String2
00401147 |. 8D95 E4FEFFFF lea edx, [ebp-11C] ; |
0040114D |. 52 push edx ; |String1
0040114E |. E8 339C0000 call <jmp.&KERNEL32.lstrcmpA> ; \假码与真码比较
00401153 |. 85C0 test eax, eax
00401155 |. 75 0D jnz short 00401164 ; 跳,则完蛋
00401157 |. 68 3CB44000 push 0040B43C ; /Text = "Congratulations! IF this number comes *FROM YOUR* keygen, Write a tutorial dude ;)."
0040115C |. 56 push esi ; |hWnd
0040115D |. E8 289B0000 call <jmp.&USER32.SetWindowTextA> ; \SetWindowTextA
00401162 |. EB 18 jmp short 0040117C
00401164 |> 68 90B44000 push 0040B490 ; /Text = "This serial is *NOT* Valid!! Try again... : UNREGISTERED"
00401169 |. 56 push esi ; |hWnd
0040116A |. E8 1B9B0000 call <jmp.&USER32.SetWindowTextA> ; \SetWindowTextA
0040116F |. EB 0B jmp short 0040117C
00401171 |> 68 C9B44000 push 0040B4C9 ; /Text = "Name must contain more than 4 chars and less than 50 chars !!"
00401176 |. 56 push esi ; |hWnd
00401177 |. E8 0E9B0000 call <jmp.&USER32.SetWindowTextA> ; \SetWindowTextA
算法小结:
用name 的每个字符依次与1、2、3、……异或并累加,然后左移7位,记为A;最后一位异或后乘6记为B,A+B记为C,最后把C转换成十六进制的大写字母即成注册码!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年07月03日 下午 08:41:28
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)