【文章标题】: 趣味crackme1 简单分析
【文章作者】: netwind
【下载地址】: 自己搜索下载
【作者声明】: 自残一下,希望对大家有帮助!
--------------------------------------------------------------------------------
【详细过程】
我们以0654321作为key串来进行跟踪
直接进入主题 来到401800处 往下有代码如下:
00401844 |> /8B4D 0C /mov ecx, dword ptr [ebp+C] ; 取key串
00401847 |. |034D B8 |add ecx, dword ptr [ebp-48]
0040184A |. |0FBE11 |movsx edx, byte ptr [ecx]
0040184D |. |83EA 30 |sub edx, 30
00401850 |. |85D2 |test edx, edx ; 是否为0
00401852 |. |7C 1C |jl short 00401870 ; 小于0则跳出循环
00401854 |. |8B45 0C |mov eax, dword ptr [ebp+C]
00401857 |. |0345 B8 |add eax, dword ptr [ebp-48]
0040185A |. |0FBE08 |movsx ecx, byte ptr [eax]
0040185D |. |83E9 30 |sub ecx, 30
00401860 |. |83F9 09 |cmp ecx, 9 ; 是否大于9
00401863 |. |7F 0B |jg short 00401870 ; 跳出循环
00401865 |. |8B55 B8 |mov edx, dword ptr [ebp-48]
00401868 |. |83C2 01 |add edx, 1 ; edx在记数
0040186B |. |8955 B8 |mov dword ptr [ebp-48], edx
0040186E |.^\EB D4 \jmp short 00401844 ; 根据以上信息 很明显在判断每个字符是不是数字0-9之间的
00401870 |> 837D B8 07 cmp dword ptr [ebp-48], 7
00401874 |. 7D 23 jge short 00401899 ; 如果这样的字符的个数大于7 就继续
00401876 |. 6A 00 push 0
00401878 |. 6A 00 push 0
0040187A |. 68 68354000 push 00403568 ; ASCII "wrong key!"
0040187F |. E8 1E090000 call <jmp.&MFC42.#1200_AfxMessage>
00401884 |. FF15 0C304000 call dword ptr [<&KERNEL32.GetCur>; [GetCurrentProcess
0040188A |. 8945 B0 mov dword ptr [ebp-50], eax
0040188D |. 6A 00 push 0 ; /ExitCode = 0
0040188F |. 8B45 B0 mov eax, dword ptr [ebp-50] ; |
00401892 |. 50 push eax ; |hProcess
00401893 |. FF15 00304000 call dword ptr [<&KERNEL32.Termin>; \TerminateProcess
00401899 |> 8D4D EC lea ecx, dword ptr [ebp-14] ; 取出字符串ABCDEF
0040189C |. 51 push ecx ; /s
0040189D |. E8 84090000 call <jmp.&MSVCRT.strlen> ; \strlen
004018A2 |. 83C4 04 add esp, 4
004018A5 |. 83E8 01 sub eax, 1
004018A8 |. 8945 B8 mov dword ptr [ebp-48], eax
004018AB |> 837D B4 14 /cmp dword ptr [ebp-4C], 14 ; 判断是否大于20
004018AF |. 7F 26 |jg short 004018D7
004018B1 |. 8B55 B8 |mov edx, dword ptr [ebp-48]
004018B4 |. 0FBE4415 EC |movsx eax, byte ptr [ebp+edx-14] ; 从ABCDEF最后一位开始取字符
004018B9 |. 83C0 03 |add eax, 3 ; 把取出的字符加3
004018BC |. 8B4D B4 |mov ecx, dword ptr [ebp-4C]
004018BF |. 88440D BC |mov byte ptr [ebp+ecx-44], al ; 把字符放入内存 我们这时注意观察该处内存地址12f710里数据的变化
004018C3 |. 8B55 B8 |mov edx, dword ptr [ebp-48]
004018C6 |. 83EA 01 |sub edx, 1
004018C9 |. 8955 B8 |mov dword ptr [ebp-48], edx
004018CC |. 8B45 B4 |mov eax, dword ptr [ebp-4C]
004018CF |. 83C0 04 |add eax, 4 ; 把字符放入内存后 内存地址往后移4位
004018D2 |. 8945 B4 |mov dword ptr [ebp-4C], eax
004018D5 |.^ EB D4 \jmp short 004018AB ; 当循环结束时我们可以看到每间隔4个字符 都放入了新字符
内存数据:
0012F710 49 B0 DD 73 48 00 00 00 47 BD 80 7C 46 FE 12 00 I拜sH...G絸|F?.
0012F720 45 FE 12 00 44 00 00 00 E?.D...
004018D7 |> \8D4D EC lea ecx, dword ptr [ebp-14]
004018DA |. 51 push ecx ; /s
004018DB |. E8 46090000 call <jmp.&MSVCRT.strlen> ; \strlen
004018E0 |. 83C4 04 add esp, 4
004018E3 |. 83E8 01 sub eax, 1
004018E6 |. 8945 B8 mov dword ptr [ebp-48], eax
004018E9 |. C745 B4 01000>mov dword ptr [ebp-4C], 1
004018F0 |. 8B55 0C mov edx, dword ptr [ebp+C]
004018F3 |. 52 push edx ; /s
004018F4 |. E8 2D090000 call <jmp.&MSVCRT.strlen> ; \strlen
004018F9 |. 83C4 04 add esp, 4
004018FC |. 83F8 10 cmp eax, 10 ; 如果key 长度大于16 就over
004018FF |. 76 23 jbe short 00401924
00401901 |. 6A 00 push 0
00401903 |. 6A 00 push 0
00401905 |. 68 50354000 push 00403550 ; ASCII "key string too long!"
0040190A |. E8 93080000 call <jmp.&MFC42.#1200_AfxMessage>
0040190F |. FF15 0C304000 call dword ptr [<&KERNEL32.GetCur>; [GetCurrentProcess
00401915 |. 8945 AC mov dword ptr [ebp-54], eax
00401918 |. 6A 00 push 0 ; /ExitCode = 0
0040191A |. 8B45 AC mov eax, dword ptr [ebp-54] ; |
0040191D |. 50 push eax ; |hProcess
0040191E |. FF15 00304000 call dword ptr [<&KERNEL32.Termin>; \TerminateProcess
00401924 |> 8B4D 08 mov ecx, dword ptr [ebp+8]
00401927 |. 83C1 08 add ecx, 8
0040192A |. 894D A8 mov dword ptr [ebp-58], ecx
0040192D |> 837D B4 15 /cmp dword ptr [ebp-4C], 15 ; 这个循环依然跟上一个 类似在那段内存地址放入新字符,我们直接断在循环结束看结果
00401931 |. 7F 26 |jg short 00401959
00401933 |. 8B55 B8 |mov edx, dword ptr [ebp-48]
00401936 |. 0FBE4415 EC |movsx eax, byte ptr [ebp+edx-14]
0040193B |. 83C0 03 |add eax, 3
0040193E |. 8B4D B4 |mov ecx, dword ptr [ebp-4C]
00401941 |. 88440D BC |mov byte ptr [ebp+ecx-44], al
00401945 |. 8B55 B8 |mov edx, dword ptr [ebp-48]
00401948 |. 83EA 01 |sub edx, 1
0040194B |. 8955 B8 |mov dword ptr [ebp-48], edx
0040194E |. 8B45 B4 |mov eax, dword ptr [ebp-4C]
00401951 |. 83C0 04 |add eax, 4
00401954 |. 8945 B4 |mov dword ptr [ebp-4C], eax
00401957 |.^ EB D4 \jmp short 0040192D
内存数据:
0012F710 49 49 DD 73 48 48 00 00 47 47 80 7C 46 46 12 00 II輘HH..GG€|FF.
0012F720 45 45 12 00 44 44 00 00 EE.DD..
后面两个循环都是这样 它在产生新串:
我们把内存数据变化放在一起比较下
0012F710 49 B0 DD 73 48 00 00 00 47 BD 80 7C 46 FE 12 00 I拜sH...G絸|F?.
0012F720 45 FE 12 00 44 00 00 00 E?.D...
0012F710 49 49 DD 73 48 48 00 00 47 47 80 7C 46 46 12 00 II輘HH..GG€|FF.
0012F720 45 45 12 00 44 44 00 00 EE.DD..
0012F710 49 49 49 73 48 48 48 00 47 47 47 7C 46 46 46 00 IIIsHHH.GGG|FFF.
0012F720 45 45 45 00 44 44 44 00 EEE.DDD.
0012F710 49 49 49 49 48 48 48 48 47 47 47 47 46 46 46 46 IIIIHHHHGGGGFFFF
0012F720 45 45 45 45 44 44 44 44 EEEEDDDD
ok就是在生成串 IIIIHHHHGGGGFFFFEEEEDDDD
00401A2B |> /8B45 9C /mov eax, dword ptr [ebp-64]
00401A2E |. |83C0 01 |add eax, 1
00401A31 |. |3945 B8 |cmp dword ptr [ebp-48], eax
00401A34 |. |74 51 |je short 00401A87
00401A36 |. |8B4D 0C |mov ecx, dword ptr [ebp+C]
00401A39 |. |034D 9C |add ecx, dword ptr [ebp-64]
00401A3C |. |0FBE11 |movsx edx, byte ptr [ecx] ; 取key串里的第7个开始的字符
00401A3F |. |8D8495 F8FEFF>|lea eax, dword ptr [ebp+edx*4-1>
00401A46 |. |8945 90 |mov dword ptr [ebp-70], eax
00401A49 |. |8B4D 90 |mov ecx, dword ptr [ebp-70]
00401A4C |. |51 |push ecx
00401A4D |. |8B55 0C |mov edx, dword ptr [ebp+C]
00401A50 |. |0355 B8 |add edx, dword ptr [ebp-48]
00401A53 |. |0FBE02 |movsx eax, byte ptr [edx] ; 取key串里的第2个开始的字符
00401A56 |. |8B4D B8 |mov ecx, dword ptr [ebp-48]
00401A59 |. |8D9481 3CFFFF>|lea edx, dword ptr [ecx+eax*4-C>
00401A60 |. |8D4415 BB |lea eax, dword ptr [ebp+edx-45]
00401A64 |. |8945 8C |mov dword ptr [ebp-74], eax
00401A67 |. |8B4D 8C |mov ecx, dword ptr [ebp-74]
00401A6A |. |51 |push ecx
00401A6B |. |8B55 B8 |mov edx, dword ptr [ebp-48]
00401A6E |. |83C2 01 |add edx, 1
00401A71 |. |8955 B8 |mov dword ptr [ebp-48], edx
00401A74 |. |8B45 9C |mov eax, dword ptr [ebp-64]
00401A77 |. |83E8 01 |sub eax, 1
00401A7A |. |8945 9C |mov dword ptr [ebp-64], eax
00401A7D |. |E8 4EFDFFFF |call 004017D0 ; 把新串4个一组以从key串里取出的数字为下标进行字符交换
00401A82 |. |83C4 08 |add esp, 8
00401A85 |.^\EB A4 \jmp short 00401A2B ; 循环结束将得到一个新串
0012F710 44 49 49 49 45 48 48 48 46 47 47 47 46 46 47 46 DIIIEHHHFGGGFFGF
0012F720 45 48 45 45 49 44 44 44 EHEEIDDD
这里就是得到的新串 这个串也就是用key作为下标把IIIIHHHHGGGGFFFFEEEEDDDD 进行一次排列的结果 在排列时只移动了每组的部分字符。
比如把第一个d跟第一个i交换 把第二个e跟第一个H 交换 这样 可以不让cracker那么容易看出在进行什么操作。
在fun2里检查 字符D E F G H I是否按从小到大顺序排列
好了再进入call 00401730 也就是fun2
00401751 |> /837D FC 06 /cmp dword ptr [ebp-4], 6
00401755 |. |7D 23 |jge short 0040177A
00401757 |. |8B45 FC |mov eax, dword ptr [ebp-4]
0040175A |. |0FBE88 EC4040>|movsx ecx, byte ptr [eax+4040EC]
00401761 |. |8B55 FC |mov edx, dword ptr [ebp-4]
00401764 |. |0FBE82 ED4040>|movsx eax, byte ptr [edx+4040ED]
0040176B |. |3BC8 |cmp ecx, eax ; 这里判断
0040176D |. |7D 0B |jge short 0040177A
0040176F |. |8B4D FC |mov ecx, dword ptr [ebp-4]
00401772 |. |83C1 01 |add ecx, 1
00401775 |. |894D FC |mov dword ptr [ebp-4], ecx
00401778 |.^\EB D7 \jmp short 00401751 ; 这里检查新串里的某些字符是不是按从小到大排列
0040177A |> 837D FC 06 cmp dword ptr [ebp-4], 6
0040177E |. 74 15 je short 00401795 ; 满足时计数为6
00401780 |. 6A 04 push 4 ; /maxlen = 4
00401782 |. 8B55 0C mov edx, dword ptr [ebp+C] ; |
00401785 |. 52 push edx ; |src
00401786 |. 8B45 08 mov eax, dword ptr [ebp+8] ; |
00401789 |. 50 push eax ; |dest
0040178A |. FF15 D0314000 call dword ptr [<&MSVCRT.strncpy>>; \这里把messagebox参数改成了fun2地址就不弹框了
00401790 |. 83C4 0C add esp, 0C
00401793 |. EB 14 jmp short 004017A9
00401795 |> 6A 04 push 4 ; /maxlen = 4
00401797 |. 68 F2404000 push 004040F2 ; |src = ""88,"?,12,""
0040179C |. 8B4D 08 mov ecx, dword ptr [ebp+8] ; |
0040179F |. 51 push ecx ; |dest
004017A0 |. FF15 D0314000 call dword ptr [<&MSVCRT.strncpy>>; \恢复messagebox 参数
可以参照以下c代码进行分析
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)