【破文标题】crackme破解分析
【破文作者】逍遥风
【破解工具】OD
【破解平台】WINXP
【软件简介】Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows
Language: Borland Delphi
----------------------------------------------------------------------
用OD 载入这个CRACKME
根据提示信息很容易来到以下关键代码处;
0045383E |. 8B86 FC020000 mov eax, [esi+2FC]
00453844 |. E8 03F2FDFF call 00432A4C ; 取注册名位数
00453849 |. 8D95 D8D8FFFF lea edx, [ebp-2728]
0045384F |. 8B86 00030000 mov eax, [esi+300]
00453855 |. E8 F2F1FDFF call 00432A4C ; 取输入的注册码的位数
0045385A |. 8B85 D8D8FFFF mov eax, [ebp-2728] ; 使EAX等于输入的注册码
00453860 |. E8 B745FBFF call 00407E1C ; 将注册码转换成对应的16进制
00453865 |. 8945 EC mov [ebp-14], eax ; 将16进制数保存
00453868 |. 8B45 FC mov eax, [ebp-4] ; 使EAX等于注册名
0045386B |. E8 9C08FBFF call 0040410C ; 取注册名 的位数
00453870 |. 8945 F4 mov [ebp-C], eax ; 保存注册名的位数
00453873 |. 8D45 F8 lea eax, [ebp-8]
00453876 |. BA 543A4500 mov edx, 00453A54 ; ;;;;;;;;;;;;;**====,,=,,========*=**=*=**=*=**=*=*=* (字符串1)
0045387B |. E8 6406FBFF call 00403EE4 ; 使EDX等于固定字符串1
00453880 |. 8B45 F8 mov eax, [ebp-8] ; 使EAX等于字符串1
00453883 |. E8 8408FBFF call 0040410C ; 取字符串1 的位数
00453888 |. 8BF0 mov esi, eax ; 使ESI=EAX等于字符串1的位数
这时可以得到一个字符串
;;;;;;;;;;;;;**====,,=,,========*=**=*=**=*=**=*=*=*
设它为字符串1
0045388A |. 85F6 test esi, esi
0045388C |. 7E 1E jle short 004538AC
0045388E |. BB 01000000 mov ebx, 1
00453893 |> 8D45 F8 /lea eax, [ebp-8] ; EAX等于字符串1
00453896 |. E8 C90AFBFF |call 00404364
0045389B |. 8B55 F8 |mov edx, [ebp-8] ; EDX等于字符串1
0045389E |. 0FB6541A FF |movzx edx, byte ptr [edx+ebx-1] ; 取字符串1每一位的ASCII码
004538A3 |. 42 |inc edx ; 每一位的ASCII码加1,结果设为A
004538A4 |. 885418 FF |mov [eax+ebx-1], dl ; 保存计算结果A,并用相应的A去替换字符串1中的相应字符
004538A8 |. 43 |inc ebx ; 每计算一次EBX+1
004538A9 |. 4E |dec esi ; 每计算一次ESI减1
004538AA |.^ 75 E7 \jnz short 00453893 ; 循环计算
004538AC |> 837D F4 00 cmp dword ptr [ebp-C], 0 ; 注册名位数与0比较
004538B0 |. 0F8E 25010000 jle 004539DB
004538B6 |. 837D F4 0A cmp dword ptr [ebp-C], 0A ; 注册名位数与10比较
004538BA |. 0F8D 1B010000 jge 004539DB
004538C0 |. 8B45 F8 mov eax, [ebp-8] ; 使EAX等于字符串2
004538C3 |. E8 4408FBFF call 0040410C ; 取字符串2的位数
004538C8 |. 8BF0 mov esi, eax ; ESI等于字符串2的位数
经过替换后得到一个新的字符串
<<<<<<<<<<<<<++>>>>-->-->>>>>>>>+>++>+>++>+>++>+>+>+!
设为字符串2
004538CA |. 85F6 test esi, esi
004538CC |. 7E 19 jle short 004538E7
004538CE |. BB 01000000 mov ebx, 1 ; 使EBX等于1
004538D3 |. 8D85 DCD8FFFF lea eax, [ebp-2724]
004538D9 |> 8B55 F8 /mov edx, [ebp-8] ; 使EDX等于字符串2
004538DC |. 8A541A FF |mov dl, [edx+ebx-1] ; 取字符串2每一位的ASCII码
004538E0 |. 8810 |mov [eax], dl ; 保存每一位的ASCII码
004538E2 |. 43 |inc ebx ; 每计算一次EBX加1
004538E3 |. 40 |inc eax
004538E4 |. 4E |dec esi ; 每计算一次ESI减1
004538E5 |.^ 75 F2 \jnz short 004538D9 ; 循环计算
004538E7 |> 8B75 F4 mov esi, [ebp-C] ; 使ESI等于注册名位数
004538EA |. 85F6 test esi, esi
004538EC |. 7E 21 jle short 0045390F
004538EE |. BB 01000000 mov ebx, 1 ; 使EBX等于1
004538F3 |> 8B45 F8 /mov eax, [ebp-8] ; 使EAX等于字符串2
004538F6 |. E8 1108FBFF |call 0040410C ; 取字符串2的位数
004538FB |. 03C3 |add eax, ebx ; EAX=EAX+EBX,即EAX等于字符串2的位数加计算次数n
004538FD |. 8B55 FC |mov edx, [ebp-4] ; 使EDX等于注册名
00453900 |. 8A541A FF |mov dl, [edx+ebx-1] ; 取注册名每一位的ASCII码,保存在DL中
00453904 |. 889405 DCD8FF>|mov [ebp+eax-2724], dl ; 保存注册名每一位的ASCII码
0045390B |. 43 |inc ebx ; 每计算一次EBX加1
0045390C |. 4E |dec esi ; 每计算一次ESI减1
0045390D |.^ 75 E4 \jnz short 004538F3 ; 循环计算,保存注册名每一位的ASCII码。作为表1
0045390F |> 8B45 F8 mov eax, [ebp-8] ; 使EAX等于字符串2
00453912 |. E8 F507FBFF call 0040410C ; 取字符串2的位数
00453917 |. 83C0 02 add eax, 2 ; 字符串2的位数加2
0045391A |. 8945 F0 mov [ebp-10], eax
0045391D |. B8 01000000 mov eax, 1 ; 使EAX等于1
00453922 |. 33D2 xor edx, edx ; EDX清零
00453924 |> /8A8C05 DBD8FF>/mov cl, [ebp+eax-2725]
0045392B |. |81E1 FF000000 |and ecx, 0FF
00453931 |. |83F9 3C |cmp ecx, 3C ; Switch (cases 21..5D)
00453934 |. |7F 1A |jg short 00453950
00453936 |. |74 2E |je short 00453966
00453938 |. |83E9 21 |sub ecx, 21
0045393B |. |0F84 8E000000 |je 004539CF
00453941 |. |83E9 0A |sub ecx, 0A
00453944 |. |74 25 |je short 0045396B
00453946 |. |83E9 02 |sub ecx, 2
00453949 |. |74 38 |je short 00453983
0045394B |. |E9 81000000 |jmp 004539D1
00453950 |> |83E9 3E |sub ecx, 3E
00453953 |. |74 0C |je short 00453961
00453955 |. |83E9 1D |sub ecx, 1D
00453958 |. |74 41 |je short 0045399B
0045395A |. |83E9 02 |sub ecx, 2
0045395D |. |74 56 |je short 004539B5
0045395F |. |EB 70 |jmp short 004539D1
00453961 |> |FF45 F0 |inc dword ptr [ebp-10] ; Case 3E ('>') of switch 00453931
00453964 |. |EB 6B |jmp short 004539D1
00453966 |> |FF4D F0 |dec dword ptr [ebp-10] ; Case 3C ('<') of switch 00453931
00453969 |. |EB 66 |jmp short 004539D1
0045396B |> |8B4D F0 |mov ecx, [ebp-10] ; Case 2B ('+') of switch 00453931
0045396E |. |0FB68C0D DBD8>|movzx ecx, byte ptr [ebp+ecx-2725>
00453976 |. |41 |inc ecx ; 将注册名每一位的ASCII码+1
00453977 |. |8B5D F0 |mov ebx, [ebp-10] ; 用ASCII码+1后的值去替换注册名中相应的字符
0045397A |. |888C1D DBD8FF>|mov [ebp+ebx-2725], cl ; 组成新的表,设为表2
这里过程十分麻烦
00453981 |. |EB 4E |jmp short 004539D1
00453983 |> |8B4D F0 |mov ecx, [ebp-10] ; Case 2D ('-') of switch 00453931
00453986 |. |0FB68C0D DBD8>|movzx ecx, byte ptr [ebp+ecx-2725>
0045398E |. |49 |dec ecx
0045398F |. |8B5D F0 |mov ebx, [ebp-10]
00453992 |. |888C1D DBD8FF>|mov [ebp+ebx-2725], cl
00453999 |. |EB 36 |jmp short 004539D1
0045399B |> |8B4D F0 |mov ecx, [ebp-10] ; Case 5B ('[') of switch 00453931
0045399E |. |80BC0D DBD8FF>|cmp byte ptr [ebp+ecx-2725], 0
004539A6 |. |75 29 |jnz short 004539D1
004539A8 |> |40 |/inc eax
004539A9 |. |80BC05 DBD8FF>||cmp byte ptr [ebp+eax-2725], 5>
004539B1 |.^|75 F5 |\jnz short 004539A8
004539B3 |. |EB 1C |jmp short 004539D1
004539B5 |> |8B4D F0 |mov ecx, [ebp-10] ; Case 5D (']') of switch 00453931
004539B8 |. |80BC0D DBD8FF>|cmp byte ptr [ebp+ecx-2725], 0
004539C0 |. |74 0F |je short 004539D1
004539C2 |> |48 |/dec eax
004539C3 |. |80BC05 DBD8FF>||cmp byte ptr [ebp+eax-2725], 5>
004539CB |.^|75 F5 |\jnz short 004539C2
004539CD |. |EB 02 |jmp short 004539D1
004539CF |> |B2 01 |mov dl, 1 ; Case 21 ('!') of switch 00453931
004539D1 |> |40 |inc eax ; Default case of switch 00453931
004539D2 |. |80FA 01 |cmp dl, 1
004539D5 |.^\0F85 49FFFFFF \jnz 00453924 ; 对字符串2进行格式检验
并按照不同的情况,对注册名采取不同的变化方法.主要方法是注册名ASCII码的加1计算,但是根据不同情况,对注册名不同位上的字符计算次数不同.
详细过程不多分析
生成了第2张表,设为表2
它是有注册名每一位的ASCII码加按条件加1得来的来得
例如:注册名lovetc,那么:
表1就是lovetc
表2就是mqwivd
终于来到了算法的核心部分
004539DB |> \BB 01000000 mov ebx, 1 ; 使EBX等于1
004539E0 |> 8B45 F8 /mov eax, [ebp-8] ; 使EAX等于字符串2
004539E3 |. E8 2407FBFF |call 0040410C ; 取字符串2的位数
004539E8 |. 03C3 |add eax, ebx ; 字符串2的位数加计算次数n
004539EA |. 0FB68405 DBD8>|movzx eax, byte ptr [ebp+eax-2725>
004539F2 |. 03F8 |add edi, eax ; EDI=EDI+EAX (EAX=字符串2位数+计算次数n)
004539F4 |. 43 |inc ebx ; 每计算一次EBX加1
004539F5 |. 83FB 0A |cmp ebx, 0A ; 计算10次
004539F8 |.^ 75 E6 \jnz short 004539E0
004539FA |. 3B7D EC cmp edi, [ebp-14] ; EDI累加后的结果必须等于注册码的16进制
004539FD |. 75 0C jnz short 00453A0B ; 才能注册成功
004539FF |. B8 943A4500 mov eax, 00453A94 ; well done!
00453A04 |. E8 6339FDFF call 0042736C
00453A09 |. EB 0A jmp short 00453A15
00453A0B |> B8 A83A4500 mov eax, 00453AA8 ; wrong
总结一些这段代码的意义
1)取字符串2的位数。。。35(16进制)。计算次数设为n (N1=1)
2)EAX=35+n 指向表中对应的数据
例如:第一次计算35+1=36 ,指向[ebp+eax-2725]中的数据,即
[ebp+eax-2725]=0012F64C+36-2725=12CF5D
查看12CF5D处的内容“ D 12CF5D” 发现所指向的就是上文所提到的表1
表1第一位是0,所以此时 EAX=0
[ebp+eax-2725]=0012F64C+(位数+n)-2725
| | |
定值 定值 定值
可以看出,只有n是变化的.
可以说明对于表中的数据,是按表中字符顺序依次取得的。即 EAX(1)=0,EAX(2)=6D。。。m
EAX(3)=71。。。q 依次类推。。。
3)所以EDI中的指就是:
定值:12F7C8+EAX(1)+EAX(2)+。。。EAX(10)=最后结果
4)这个最后结果必须要等于注册码的16进制数,方能注册成功
根据EDI最后的累加结果12FA60,可以推出
lovetc
1243744
----------------------------------------------------------------------
大概的过程就是上文所说的
但是根据注册名计算的出表2的过程比较麻烦,需要结合字符串2的情况进行分情况讨论
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!