-
-
[原创]MD5CrackMe.exe的破解
-
发表于: 2008-7-2 21:17 5984
-
【文章标题】: MD5CrackMe.exe的破解
【文章作者】: 北流浪子
【软件名称】: MD5CrackMe.exe
【下载页面】: http://bbs.pediy.com/showthread.php?t=47488
【加壳方式】: Microsoft Visual C++ 6.0 没加壳
【使用工具】: PEiD OD
【操作平台】: WINXP
【作者声明】: 新手的第一次,发帖以鼓励自己,有错误的地方希望前辈高手们不要笑话。
这个MD5CrackMe.exe是在http://bbs.pediy.com/showthread.php?t=47488下载的。
用OD载入后往下拉,看到对GetModuleHandleA的调用后,紧接下来的一个call就是对WinMain的调用了,用VC写的程序经常是这样的,
00403B36 |. 56 push esi
00403B37 |. 56 push esi ; /pModule
00403B38 |. FF15 08B04000 call dword ptr [<&KERNEL32.GetModuleH>; \GetModuleHandleA
00403B3E |. 50 push eax
00403B3F |. E8 4CEEFFFF call 00402990 ;WinMain,F7跟进去
来到这里,
00402990 /$ 6A 00 push 0 ; /pModule = NULL
00402992 |. FF15 08B04000 call dword ptr [<&KERNEL32.GetModuleH>; \GetModuleHandleA
00402998 |. 6A 00 push 0 ; /lParam = NULL
0040299A |. 68 B0274000 push 004027B0 ; |DlgProc = MD5Crack.004027B0,这便是对话框过程的地址
0040299F |. 6A 00 push 0 ; |hOwner = NULL
004029A1 |. 6A 66 push 66 ; |pTemplate = 66
004029A3 |. 50 push eax ; |hInst
004029A4 |. A3 6C014100 mov dword ptr [41016C], eax ; |
004029A9 |. FF15 E0B04000 call dword ptr [<&USER32.DialogBoxPar>; \DialogBoxParamA
004029AF |. 6A 00 push 0 ; /ExitCode = 0
004029B1 \. FF15 04B04000 call dword ptr [<&KERNEL32.ExitProces>; \ExitProcess
004029B7 . 33C0 xor eax, eax
004029B9 . C2 1000 retn 10
从DialogBoxParamA的原型
" int DialogBoxParam(
HINSTANCE hInstance, // handle to application instance
LPCTSTR lpTemplateName, // identifies dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // pointer to dialog box procedure
LPARAM dwInitParam // initialization value
); "
和向其传递的第二个参数可知,对话框过程的地址是004027B0,Ctrl+G到这里来看看,
004027B0 . 81EC 00030000 sub esp, 300
004027B6 . 55 push ebp
004027B7 . 56 push esi
004027B8 . 57 push edi
004027B9 . B9 3F000000 mov ecx, 3F
004027BE . 33C0 xor eax, eax
004027C0 . 8DBC24 0D0100>lea edi, dword ptr [esp+10D]
004027C7 . C68424 0C0100>mov byte ptr [esp+10C], 0
004027CF . C64424 0C 00 mov byte ptr [esp+C], 0
004027D4 . F3:AB rep stos dword ptr es:[edi]
004027D6 . 66:AB stos word ptr es:[edi]
004027D8 . AA stos byte ptr es:[edi]
004027D9 . B9 3F000000 mov ecx, 3F
004027DE . 33C0 xor eax, eax
004027E0 . 8D7C24 0D lea edi, dword ptr [esp+D]
004027E4 . C68424 0C0200>mov byte ptr [esp+20C], 0
004027EC . F3:AB rep stos dword ptr es:[edi]
004027EE . 66:AB stos word ptr es:[edi]
004027F0 . AA stos byte ptr es:[edi]
004027F1 . B9 3F000000 mov ecx, 3F
004027F6 . 33C0 xor eax, eax
004027F8 . 8DBC24 0D0200>lea edi, dword ptr [esp+20D]
004027FF . F3:AB rep stos dword ptr es:[edi]
00402801 . 66:AB stos word ptr es:[edi]
00402803 . AA stos byte ptr es:[edi]
00402804 . 8B8424 140300>mov eax, dword ptr [esp+314]
0040280B . 83E8 10 sub eax, 10 ; Switch (cases 10..111)
0040280E . 74 24 je short 00402834
00402810 . 2D 00010000 sub eax, 100
00402815 . 0F84 38010000 je 00402953
0040281B . 48 dec eax
0040281C . 75 26 jnz short 00402844
0040281E . 8B8424 180300>mov eax, dword ptr [esp+318] ; Case 111 (WM_COMMAND) of switch 0040280B
00402825 . 25 FFFF0000 and eax, 0FFFF
0040282A . 2D 59A10000 sub eax, 0A159 ; Switch (cases A159..A15A)
0040282F . 74 1F je short 00402850
00402831 . 48 dec eax
00402832 . 75 10 jnz short 00402844
00402834 > 8B8424 100300>mov eax, dword ptr [esp+310] ; Case A15A of switch 0040282A
0040283B . 6A 00 push 0 ; /Result = 0
0040283D . 50 push eax ; |hWnd
0040283E . FF15 CCB04000 call dword ptr [<&USER32.EndDialog>] ; \EndDialog
00402844 > 5F pop edi ; Default case of switch 0040282A
00402845 . 5E pop esi
00402846 . 33C0 xor eax, eax
00402848 . 5D pop ebp
00402849 . 81C4 00030000 add esp, 300
0040284F . C3 retn
00402850 > 8BB424 100300>mov esi, dword ptr [esp+310] ; Case A159 of switch 0040282A
00402857 . 8B2D D0B04000 mov ebp, dword ptr [<&USER32.GetDlgI>; USER32.GetDlgItemTextA
0040285D . 8D8C24 0C0100>lea ecx, dword ptr [esp+10C]
00402864 . 68 00010000 push 100 ; /Count = 100 (256.)
00402869 . 51 push ecx ; |Buffer
0040286A . 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
0040286F . 56 push esi ; |hWnd
00402870 . FFD5 call ebp ; \GetDlgItemTextA 用于获取用户名
00402872 . 8DBC24 0C0100>lea edi, dword ptr [esp+10C]
00402879 . 83C9 FF or ecx, FFFFFFFF ;这几条指令是求字符串长度的经典组合,
0040287C . 33C0 xor eax, eax ;下面还会多次见到的。
0040287E . F2:AE repne scas byte ptr es:[edi] ;求edi所指向的字符串的长度,
00402880 . F7D1 not ecx ;
00402882 . 49 dec ecx ;执行这条指令后ecx为edi所指向的字符串的长度。
00402883 . 83F9 01 cmp ecx, 1
00402886 . 73 1F jnb short 004028A7
00402888 . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040288A . 68 A4D14000 push 0040D1A4 ; |Title = ""D7,"",A2,"",B2,"崽崾?
0040288F . 68 8CD14000 push 0040D18C ; |Text = "用",BB,"?,B2,"",BB,"能为空请输入!"
00402894 . 56 push esi ; |hOwner
00402895 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
0040289B . 5F pop edi
0040289C . 5E pop esi
0040289D . 33C0 xor eax, eax
0040289F . 5D pop ebp
004028A0 . 81C4 00030000 add esp, 300
004028A6 . C3 retn
004028A7 > 8D5424 0C lea edx, dword ptr [esp+C]
004028AB . 68 00010000 push 100 ; /Count = 100 (256.)
004028B0 . 52 push edx ; |Buffer
004028B1 . 68 07040000 push 407 ; |ControlID = 407 (1031.)
004028B6 . 56 push esi ; |hWnd
004028B7 . FFD5 call ebp ; \GetDlgItemTextA 用于获取注册码
004028B9 . 8D7C24 0C lea edi, dword ptr [esp+C]
004028BD . 83C9 FF or ecx, FFFFFFFF
004028C0 . 33C0 xor eax, eax
004028C2 . F2:AE repne scas byte ptr es:[edi]
004028C4 . F7D1 not ecx
004028C6 . 49 dec ecx
004028C7 . 83F9 01 cmp ecx, 1
004028CA . 73 1F jnb short 004028EB
004028CC . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004028CE . 68 A4D14000 push 0040D1A4 ; |Title = ""D7,"",A2,"",B2,"崽崾?
004028D3 . 68 74D14000 push 0040D174 ; |Text = ""D7,"",A2,"",B2,"崧?,B2,"",BB,"能为空请输入!"
004028D8 . 56 push esi ; |hOwner
004028D9 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
004028DF . 5F pop edi
004028E0 . 5E pop esi
004028E1 . 33C0 xor eax, eax
004028E3 . 5D pop ebp
004028E4 . 81C4 00030000 add esp, 300
004028EA . C3 retn
004028EB > 8D8424 0C0200>lea eax, dword ptr [esp+20C]
004028F2 . 6A 00 push 0
004028F4 . 8D8C24 100100>lea ecx, dword ptr [esp+110]
004028FB . 50 push eax
004028FC . 51 push ecx
004028FD . E8 FEFCFFFF call 00402600 MD5HashStr("用户输入的用户名",&buffer,int unknown)
00402600 /$ 6A FF push -1
00402602 |. 68 A8A14000 push 0040A1A8 ; SE 处理程序安装
00402607 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040260D |. 50 push eax
0040260E |. 64:8925 00000>mov dword ptr fs:[0], esp
00402615 |. 81EC 2C010000 sub esp, 12C
0040261B |. 53 push ebx
0040261C |. 55 push ebp
0040261D |. 56 push esi
0040261E |. 57 push edi
0040261F |. 8D8C24 DC0000>lea ecx, dword ptr [esp+DC]
00402626 |. E8 15F2FFFF call 00401840
0040262B |. 8BAC24 540100>mov ebp, dword ptr [esp+154]
00402632 |. 33C0 xor eax, eax
00402634 |. 3BE8 cmp ebp, eax
00402636 |. 898424 440100>mov dword ptr [esp+144], eax
0040263D |. 8DB424 DC0000>lea esi, dword ptr [esp+DC]
00402644 |. 74 04 je short 0040264A
00402646 |. 8B7424 10 mov esi, dword ptr [esp+10]
0040264A |> 884424 14 mov byte ptr [esp+14], al
0040264E |. B9 10000000 mov ecx, 10
00402653 |. 33C0 xor eax, eax
00402655 |. 8D7C24 15 lea edi, dword ptr [esp+15]
00402659 |. F3:AB rep stos dword ptr es:[edi]
0040265B |. 8B06 mov eax, dword ptr [esi]
0040265D |. 8BCE mov ecx, esi
0040265F |. FF50 0C call dword ptr [eax+C]
00402662 |. 8B9424 4C0100>mov edx, dword ptr [esp+14C]
00402669 |. 83C9 FF or ecx, FFFFFFFF
0040266C |. 8BFA mov edi, edx
0040266E |. 33C0 xor eax, eax
00402670 |. F2:AE repne scas byte ptr es:[edi]
00402672 |. 8B1E mov ebx, dword ptr [esi]
00402674 |. F7D1 not ecx
00402676 |. 49 dec ecx
00402677 |. 51 push ecx
00402678 |. 52 push edx
00402679 |. 8BCE mov ecx, esi
0040267B |. FF53 04 call dword ptr [ebx+4]
0040267E |. 8B16 mov edx, dword ptr [esi]
00402680 |. 8D4424 14 lea eax, dword ptr [esp+14]
00402684 |. 50 push eax
00402685 |. 8BCE mov ecx, esi
00402687 |. FF52 08 call dword ptr [edx+8]
0040268A |. B9 20000000 mov ecx, 20
0040268F |. 33C0 xor eax, eax
00402691 |. 8D7C24 59 lea edi, dword ptr [esp+59]
00402695 |. C64424 58 00 mov byte ptr [esp+58], 0
0040269A |. F3:AB rep stos dword ptr es:[edi]
0040269C |. 5F pop edi
0040269D |. 5E pop esi
0040269E |. 85ED test ebp, ebp
004026A0 |. 5D pop ebp
004026A1 |. 5B pop ebx
004026A2 |. 75 14 jnz short 004026B8
004026A4 |. 8D4C24 48 lea ecx, dword ptr [esp+48]
004026A8 |. 8D5424 04 lea edx, dword ptr [esp+4]
004026AC |. 51 push ecx
004026AD |. 6A 10 push 10
004026AF |. 52 push edx
004026B0 |. E8 DBFEFFFF call 00402590
004026B5 |. 83C4 0C add esp, 0C
004026B8 |> 8B8C24 400100>mov ecx, dword ptr [esp+140]
004026BF |. 8D4424 48 lea eax, dword ptr [esp+48]
004026C3 |. 50 push eax ; /String2
004026C4 |. 51 push ecx ; |String1
004026C5 |. FF15 00B04000 call dword ptr [<&KERNEL32.lstrcpyA>] ; \lstrcpyA
004026CB |. 8B8C24 2C0100>mov ecx, dword ptr [esp+12C]
004026D2 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004026D9 |. 81C4 38010000 add esp, 138
004026DF \. C3 retn
上面这个汇编函数功能是求一个字符串的MD5散列值,并将这个MD5散列值转为字符串,并把它copy到另一个字符串中,用C语言写就像下面的形式:
void MD5HashStr(char *source,char *dest,int unknown)
{
strcpy(dest,HexToString(MD5Hash(source)));
}
00402902 . 8D9424 180200>lea edx, dword ptr [esp+218]
00402909 . 8D4424 18 lea eax, dword ptr [esp+18]
0040290D . 52 push edx
0040290E . 50 push eax
0040290F . E8 CCFDFFFF call 004026E0 ;相当于调用StrCompare("用户输入的注册码","用户名的HASH字符串");
004026E0 /$ 81EC 00020000 sub esp, 200
004026E6 |. 56 push esi
004026E7 |. 57 push edi
004026E8 |. B9 3F000000 mov ecx, 3F
004026ED |. 33C0 xor eax, eax
004026EF |. 8D7C24 09 lea edi, dword ptr [esp+9]
004026F3 |. C64424 08 00 mov byte ptr [esp+8], 0
004026F8 |. F3:AB rep stos dword ptr es:[edi]
004026FA |. 66:AB stos word ptr es:[edi]
004026FC |. AA stos byte ptr es:[edi]
004026FD |. B9 3F000000 mov ecx, 3F
00402702 |. 33C0 xor eax, eax
00402704 |. 8DBC24 090100>lea edi, dword ptr [esp+109]
0040270B |. C68424 080100>mov byte ptr [esp+108], 0
00402713 |. F3:AB rep stos dword ptr es:[edi]
00402715 |. 66:AB stos word ptr es:[edi]
00402717 |. 8B35 00B04000 mov esi, dword ptr [<&KERNEL32.lstrcpyA>] ; kernel32.lstrcpyA
0040271D |. 8D4C24 08 lea ecx, dword ptr [esp+8]
00402721 |. AA stos byte ptr es:[edi]
00402722 |. 8B8424 0C0200>mov eax, dword ptr [esp+20C]
00402729 |. 50 push eax ; /String2
0040272A |. 51 push ecx ; |String1
0040272B |. FFD6 call esi ; \lstrcpyA
0040272D |. 8B9424 100200>mov edx, dword ptr [esp+210]
00402734 |. 8D8424 080100>lea eax, dword ptr [esp+108]
0040273B |. 52 push edx ; /String2
0040273C |. 50 push eax ; |String1
0040273D |. FFD6 call esi ; \lstrcpyA
0040273F |. 8DBC24 080100>lea edi, dword ptr [esp+108]
00402746 |. 83C9 FF or ecx, FFFFFFFF
00402749 |. 33C0 xor eax, eax
0040274B |. F2:AE repne scas byte ptr es:[edi]
0040274D |. F7D1 not ecx
0040274F |. 49 dec ecx
00402750 |. 8D7C24 08 lea edi, dword ptr [esp+8]
00402754 |. 8BD1 mov edx, ecx
00402756 |. 83C9 FF or ecx, FFFFFFFF
00402759 |. F2:AE repne scas byte ptr es:[edi]
0040275B |. F7D1 not ecx
0040275D |. 49 dec ecx
0040275E |. 3BCA cmp ecx, edx
00402760 |. 75 40 jnz short 004027A2
00402762 |. 8D7C24 08 lea edi, dword ptr [esp+8]
00402766 |. 83C9 FF or ecx, FFFFFFFF
00402769 |. 33D2 xor edx, edx
0040276B |. F2:AE repne scas byte ptr es:[edi]
0040276D |. F7D1 not ecx
0040276F |. 49 dec ecx
00402770 |. 74 22 je short 00402794
00402772 |> 8A4414 08 /mov al, byte ptr [esp+edx+8]
00402776 |. 8A8C14 080100>|mov cl, byte ptr [esp+edx+108]
0040277D |. 3AC1 |cmp al, cl
0040277F |. 75 21 |jnz short 004027A2
00402781 |. 8D7C24 08 |lea edi, dword ptr [esp+8]
00402785 |. 83C9 FF |or ecx, FFFFFFFF
00402788 |. 33C0 |xor eax, eax
0040278A |. 42 |inc edx
0040278B |. F2:AE |repne scas byte ptr es:[edi]
0040278D |. F7D1 |not ecx
0040278F |. 49 |dec ecx
00402790 |. 3BD1 |cmp edx, ecx
00402792 |.^ 72 DE \jb short 00402772
00402794 |> 5F pop edi
00402795 |. B8 01000000 mov eax, 1
0040279A |. 5E pop esi
0040279B |. 81C4 00020000 add esp, 200
004027A1 |. C3 retn
004027A2 |> 5F pop edi
004027A3 |. 33C0 xor eax, eax
004027A5 |. 5E pop esi
004027A6 |. 81C4 00020000 add esp, 200
004027AC \. C3 retn
以上这个函数的功能是比较两个字符串,相等返回1否则返回0,我将它写成一个C函数,代码如下:
BOOL StrCompare(char *str1,char *str2)
{
char a[256]={0};
char b[256]={0};
unsigned int i;
strcpy(a,str1);
strcpy(b,str2);
if (strlen(b)!=strlen(a))
{
return FALSE;
}
for (i=0;i<strlen(a);i++)
{
if (a[i]!=b[i])
{
return FALSE;
}
}
return TRUE;
}
00402914 . 83C4 14 add esp, 14 ;根据上面函数返回的结果是否为1来判断注册码是否正确
00402917 . 83F8 01 cmp eax, 1 ;是1就正确,反之不正确。
0040291A . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040291C . 68 A4D14000 push 0040D1A4 ; |Title = ""D7,"",A2,"",B2,"崽崾?
00402921 75 18 jnz short 0040293B ;跳走则完蛋,爆破点,nop之则爆破。
00402923 . 68 60D14000 push 0040D160 ; |Text = "恭?,B2,"你?,AC,"",D7,"",A2,"",B2,"崧胝",B7,"!"
00402928 . 56 push esi ; |hOwner
00402929 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
0040292F . 5F pop edi
00402930 . 5E pop esi
00402931 . 33C0 xor eax, eax
00402933 . 5D pop ebp
00402934 . 81C4 00030000 add esp, 300
0040293A . C3 retn
0040293B > 68 48D14000 push 0040D148 ; |Text = ""D7,"",A2,"",B2,"崧?,B4,"砦螅",AC,"继续加油!"
00402940 . 56 push esi ; |hOwner
00402941 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
00402947 . 5F pop edi
00402948 . 5E pop esi
00402949 . 33C0 xor eax, eax
0040294B . 5D pop ebp
0040294C . 81C4 00030000 add esp, 300
00402952 . C3 retn
00402953 > 8B0D 6C014100 mov ecx, dword ptr [41016C] ; Case 110 (WM_INITDIALOG) of switch 0040280B
00402959 . 68 9A000000 push 9A ; /RsrcName = 154.
0040295E . 51 push ecx ; |hInst => NULL
0040295F . FF15 D8B04000 call dword ptr [<&USER32.LoadIconA>] ; \LoadIconA
00402965 . 8B9424 100300>mov edx, dword ptr [esp+310]
0040296C . 50 push eax ; /lParam
0040296D . 6A 01 push 1 ; |wParam = 1
0040296F . 68 80000000 push 80 ; |Message = WM_SETICON
00402974 . 52 push edx ; |hWnd
00402975 . A3 68014100 mov dword ptr [410168], eax ; |
0040297A . FF15 DCB04000 call dword ptr [<&USER32.SendMessageA>; \SendMessageA
00402980 . 5F pop edi
00402981 . 5E pop esi
00402982 . 33C0 xor eax, eax
00402984 . 5D pop ebp
00402985 . 81C4 00030000 add esp, 300
0040298B . C3 retn
经过上面的分析知只要输入的注册码为用户名经过MD5运算得到的HASH字符串,那么注册成功,反之注册失败。因此这个MD5CrackMe的注册机就是一个MD5计算器,
我把加密与解密(第二版)光盘中第6章的MD5计算器也放在附件里。
【文章作者】: 北流浪子
【软件名称】: MD5CrackMe.exe
【下载页面】: http://bbs.pediy.com/showthread.php?t=47488
【加壳方式】: Microsoft Visual C++ 6.0 没加壳
【使用工具】: PEiD OD
【操作平台】: WINXP
【作者声明】: 新手的第一次,发帖以鼓励自己,有错误的地方希望前辈高手们不要笑话。
这个MD5CrackMe.exe是在http://bbs.pediy.com/showthread.php?t=47488下载的。
用OD载入后往下拉,看到对GetModuleHandleA的调用后,紧接下来的一个call就是对WinMain的调用了,用VC写的程序经常是这样的,
00403B36 |. 56 push esi
00403B37 |. 56 push esi ; /pModule
00403B38 |. FF15 08B04000 call dword ptr [<&KERNEL32.GetModuleH>; \GetModuleHandleA
00403B3E |. 50 push eax
00403B3F |. E8 4CEEFFFF call 00402990 ;WinMain,F7跟进去
来到这里,
00402990 /$ 6A 00 push 0 ; /pModule = NULL
00402992 |. FF15 08B04000 call dword ptr [<&KERNEL32.GetModuleH>; \GetModuleHandleA
00402998 |. 6A 00 push 0 ; /lParam = NULL
0040299A |. 68 B0274000 push 004027B0 ; |DlgProc = MD5Crack.004027B0,这便是对话框过程的地址
0040299F |. 6A 00 push 0 ; |hOwner = NULL
004029A1 |. 6A 66 push 66 ; |pTemplate = 66
004029A3 |. 50 push eax ; |hInst
004029A4 |. A3 6C014100 mov dword ptr [41016C], eax ; |
004029A9 |. FF15 E0B04000 call dword ptr [<&USER32.DialogBoxPar>; \DialogBoxParamA
004029AF |. 6A 00 push 0 ; /ExitCode = 0
004029B1 \. FF15 04B04000 call dword ptr [<&KERNEL32.ExitProces>; \ExitProcess
004029B7 . 33C0 xor eax, eax
004029B9 . C2 1000 retn 10
从DialogBoxParamA的原型
" int DialogBoxParam(
HINSTANCE hInstance, // handle to application instance
LPCTSTR lpTemplateName, // identifies dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // pointer to dialog box procedure
LPARAM dwInitParam // initialization value
); "
和向其传递的第二个参数可知,对话框过程的地址是004027B0,Ctrl+G到这里来看看,
004027B0 . 81EC 00030000 sub esp, 300
004027B6 . 55 push ebp
004027B7 . 56 push esi
004027B8 . 57 push edi
004027B9 . B9 3F000000 mov ecx, 3F
004027BE . 33C0 xor eax, eax
004027C0 . 8DBC24 0D0100>lea edi, dword ptr [esp+10D]
004027C7 . C68424 0C0100>mov byte ptr [esp+10C], 0
004027CF . C64424 0C 00 mov byte ptr [esp+C], 0
004027D4 . F3:AB rep stos dword ptr es:[edi]
004027D6 . 66:AB stos word ptr es:[edi]
004027D8 . AA stos byte ptr es:[edi]
004027D9 . B9 3F000000 mov ecx, 3F
004027DE . 33C0 xor eax, eax
004027E0 . 8D7C24 0D lea edi, dword ptr [esp+D]
004027E4 . C68424 0C0200>mov byte ptr [esp+20C], 0
004027EC . F3:AB rep stos dword ptr es:[edi]
004027EE . 66:AB stos word ptr es:[edi]
004027F0 . AA stos byte ptr es:[edi]
004027F1 . B9 3F000000 mov ecx, 3F
004027F6 . 33C0 xor eax, eax
004027F8 . 8DBC24 0D0200>lea edi, dword ptr [esp+20D]
004027FF . F3:AB rep stos dword ptr es:[edi]
00402801 . 66:AB stos word ptr es:[edi]
00402803 . AA stos byte ptr es:[edi]
00402804 . 8B8424 140300>mov eax, dword ptr [esp+314]
0040280B . 83E8 10 sub eax, 10 ; Switch (cases 10..111)
0040280E . 74 24 je short 00402834
00402810 . 2D 00010000 sub eax, 100
00402815 . 0F84 38010000 je 00402953
0040281B . 48 dec eax
0040281C . 75 26 jnz short 00402844
0040281E . 8B8424 180300>mov eax, dword ptr [esp+318] ; Case 111 (WM_COMMAND) of switch 0040280B
00402825 . 25 FFFF0000 and eax, 0FFFF
0040282A . 2D 59A10000 sub eax, 0A159 ; Switch (cases A159..A15A)
0040282F . 74 1F je short 00402850
00402831 . 48 dec eax
00402832 . 75 10 jnz short 00402844
00402834 > 8B8424 100300>mov eax, dword ptr [esp+310] ; Case A15A of switch 0040282A
0040283B . 6A 00 push 0 ; /Result = 0
0040283D . 50 push eax ; |hWnd
0040283E . FF15 CCB04000 call dword ptr [<&USER32.EndDialog>] ; \EndDialog
00402844 > 5F pop edi ; Default case of switch 0040282A
00402845 . 5E pop esi
00402846 . 33C0 xor eax, eax
00402848 . 5D pop ebp
00402849 . 81C4 00030000 add esp, 300
0040284F . C3 retn
00402850 > 8BB424 100300>mov esi, dword ptr [esp+310] ; Case A159 of switch 0040282A
00402857 . 8B2D D0B04000 mov ebp, dword ptr [<&USER32.GetDlgI>; USER32.GetDlgItemTextA
0040285D . 8D8C24 0C0100>lea ecx, dword ptr [esp+10C]
00402864 . 68 00010000 push 100 ; /Count = 100 (256.)
00402869 . 51 push ecx ; |Buffer
0040286A . 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
0040286F . 56 push esi ; |hWnd
00402870 . FFD5 call ebp ; \GetDlgItemTextA 用于获取用户名
00402872 . 8DBC24 0C0100>lea edi, dword ptr [esp+10C]
00402879 . 83C9 FF or ecx, FFFFFFFF ;这几条指令是求字符串长度的经典组合,
0040287C . 33C0 xor eax, eax ;下面还会多次见到的。
0040287E . F2:AE repne scas byte ptr es:[edi] ;求edi所指向的字符串的长度,
00402880 . F7D1 not ecx ;
00402882 . 49 dec ecx ;执行这条指令后ecx为edi所指向的字符串的长度。
00402883 . 83F9 01 cmp ecx, 1
00402886 . 73 1F jnb short 004028A7
00402888 . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040288A . 68 A4D14000 push 0040D1A4 ; |Title = ""D7,"",A2,"",B2,"崽崾?
0040288F . 68 8CD14000 push 0040D18C ; |Text = "用",BB,"?,B2,"",BB,"能为空请输入!"
00402894 . 56 push esi ; |hOwner
00402895 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
0040289B . 5F pop edi
0040289C . 5E pop esi
0040289D . 33C0 xor eax, eax
0040289F . 5D pop ebp
004028A0 . 81C4 00030000 add esp, 300
004028A6 . C3 retn
004028A7 > 8D5424 0C lea edx, dword ptr [esp+C]
004028AB . 68 00010000 push 100 ; /Count = 100 (256.)
004028B0 . 52 push edx ; |Buffer
004028B1 . 68 07040000 push 407 ; |ControlID = 407 (1031.)
004028B6 . 56 push esi ; |hWnd
004028B7 . FFD5 call ebp ; \GetDlgItemTextA 用于获取注册码
004028B9 . 8D7C24 0C lea edi, dword ptr [esp+C]
004028BD . 83C9 FF or ecx, FFFFFFFF
004028C0 . 33C0 xor eax, eax
004028C2 . F2:AE repne scas byte ptr es:[edi]
004028C4 . F7D1 not ecx
004028C6 . 49 dec ecx
004028C7 . 83F9 01 cmp ecx, 1
004028CA . 73 1F jnb short 004028EB
004028CC . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004028CE . 68 A4D14000 push 0040D1A4 ; |Title = ""D7,"",A2,"",B2,"崽崾?
004028D3 . 68 74D14000 push 0040D174 ; |Text = ""D7,"",A2,"",B2,"崧?,B2,"",BB,"能为空请输入!"
004028D8 . 56 push esi ; |hOwner
004028D9 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
004028DF . 5F pop edi
004028E0 . 5E pop esi
004028E1 . 33C0 xor eax, eax
004028E3 . 5D pop ebp
004028E4 . 81C4 00030000 add esp, 300
004028EA . C3 retn
004028EB > 8D8424 0C0200>lea eax, dword ptr [esp+20C]
004028F2 . 6A 00 push 0
004028F4 . 8D8C24 100100>lea ecx, dword ptr [esp+110]
004028FB . 50 push eax
004028FC . 51 push ecx
004028FD . E8 FEFCFFFF call 00402600 MD5HashStr("用户输入的用户名",&buffer,int unknown)
00402600 /$ 6A FF push -1
00402602 |. 68 A8A14000 push 0040A1A8 ; SE 处理程序安装
00402607 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040260D |. 50 push eax
0040260E |. 64:8925 00000>mov dword ptr fs:[0], esp
00402615 |. 81EC 2C010000 sub esp, 12C
0040261B |. 53 push ebx
0040261C |. 55 push ebp
0040261D |. 56 push esi
0040261E |. 57 push edi
0040261F |. 8D8C24 DC0000>lea ecx, dword ptr [esp+DC]
00402626 |. E8 15F2FFFF call 00401840
0040262B |. 8BAC24 540100>mov ebp, dword ptr [esp+154]
00402632 |. 33C0 xor eax, eax
00402634 |. 3BE8 cmp ebp, eax
00402636 |. 898424 440100>mov dword ptr [esp+144], eax
0040263D |. 8DB424 DC0000>lea esi, dword ptr [esp+DC]
00402644 |. 74 04 je short 0040264A
00402646 |. 8B7424 10 mov esi, dword ptr [esp+10]
0040264A |> 884424 14 mov byte ptr [esp+14], al
0040264E |. B9 10000000 mov ecx, 10
00402653 |. 33C0 xor eax, eax
00402655 |. 8D7C24 15 lea edi, dword ptr [esp+15]
00402659 |. F3:AB rep stos dword ptr es:[edi]
0040265B |. 8B06 mov eax, dword ptr [esi]
0040265D |. 8BCE mov ecx, esi
0040265F |. FF50 0C call dword ptr [eax+C]
00402662 |. 8B9424 4C0100>mov edx, dword ptr [esp+14C]
00402669 |. 83C9 FF or ecx, FFFFFFFF
0040266C |. 8BFA mov edi, edx
0040266E |. 33C0 xor eax, eax
00402670 |. F2:AE repne scas byte ptr es:[edi]
00402672 |. 8B1E mov ebx, dword ptr [esi]
00402674 |. F7D1 not ecx
00402676 |. 49 dec ecx
00402677 |. 51 push ecx
00402678 |. 52 push edx
00402679 |. 8BCE mov ecx, esi
0040267B |. FF53 04 call dword ptr [ebx+4]
0040267E |. 8B16 mov edx, dword ptr [esi]
00402680 |. 8D4424 14 lea eax, dword ptr [esp+14]
00402684 |. 50 push eax
00402685 |. 8BCE mov ecx, esi
00402687 |. FF52 08 call dword ptr [edx+8]
0040268A |. B9 20000000 mov ecx, 20
0040268F |. 33C0 xor eax, eax
00402691 |. 8D7C24 59 lea edi, dword ptr [esp+59]
00402695 |. C64424 58 00 mov byte ptr [esp+58], 0
0040269A |. F3:AB rep stos dword ptr es:[edi]
0040269C |. 5F pop edi
0040269D |. 5E pop esi
0040269E |. 85ED test ebp, ebp
004026A0 |. 5D pop ebp
004026A1 |. 5B pop ebx
004026A2 |. 75 14 jnz short 004026B8
004026A4 |. 8D4C24 48 lea ecx, dword ptr [esp+48]
004026A8 |. 8D5424 04 lea edx, dword ptr [esp+4]
004026AC |. 51 push ecx
004026AD |. 6A 10 push 10
004026AF |. 52 push edx
004026B0 |. E8 DBFEFFFF call 00402590
004026B5 |. 83C4 0C add esp, 0C
004026B8 |> 8B8C24 400100>mov ecx, dword ptr [esp+140]
004026BF |. 8D4424 48 lea eax, dword ptr [esp+48]
004026C3 |. 50 push eax ; /String2
004026C4 |. 51 push ecx ; |String1
004026C5 |. FF15 00B04000 call dword ptr [<&KERNEL32.lstrcpyA>] ; \lstrcpyA
004026CB |. 8B8C24 2C0100>mov ecx, dword ptr [esp+12C]
004026D2 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004026D9 |. 81C4 38010000 add esp, 138
004026DF \. C3 retn
上面这个汇编函数功能是求一个字符串的MD5散列值,并将这个MD5散列值转为字符串,并把它copy到另一个字符串中,用C语言写就像下面的形式:
void MD5HashStr(char *source,char *dest,int unknown)
{
strcpy(dest,HexToString(MD5Hash(source)));
}
00402902 . 8D9424 180200>lea edx, dword ptr [esp+218]
00402909 . 8D4424 18 lea eax, dword ptr [esp+18]
0040290D . 52 push edx
0040290E . 50 push eax
0040290F . E8 CCFDFFFF call 004026E0 ;相当于调用StrCompare("用户输入的注册码","用户名的HASH字符串");
004026E0 /$ 81EC 00020000 sub esp, 200
004026E6 |. 56 push esi
004026E7 |. 57 push edi
004026E8 |. B9 3F000000 mov ecx, 3F
004026ED |. 33C0 xor eax, eax
004026EF |. 8D7C24 09 lea edi, dword ptr [esp+9]
004026F3 |. C64424 08 00 mov byte ptr [esp+8], 0
004026F8 |. F3:AB rep stos dword ptr es:[edi]
004026FA |. 66:AB stos word ptr es:[edi]
004026FC |. AA stos byte ptr es:[edi]
004026FD |. B9 3F000000 mov ecx, 3F
00402702 |. 33C0 xor eax, eax
00402704 |. 8DBC24 090100>lea edi, dword ptr [esp+109]
0040270B |. C68424 080100>mov byte ptr [esp+108], 0
00402713 |. F3:AB rep stos dword ptr es:[edi]
00402715 |. 66:AB stos word ptr es:[edi]
00402717 |. 8B35 00B04000 mov esi, dword ptr [<&KERNEL32.lstrcpyA>] ; kernel32.lstrcpyA
0040271D |. 8D4C24 08 lea ecx, dword ptr [esp+8]
00402721 |. AA stos byte ptr es:[edi]
00402722 |. 8B8424 0C0200>mov eax, dword ptr [esp+20C]
00402729 |. 50 push eax ; /String2
0040272A |. 51 push ecx ; |String1
0040272B |. FFD6 call esi ; \lstrcpyA
0040272D |. 8B9424 100200>mov edx, dword ptr [esp+210]
00402734 |. 8D8424 080100>lea eax, dword ptr [esp+108]
0040273B |. 52 push edx ; /String2
0040273C |. 50 push eax ; |String1
0040273D |. FFD6 call esi ; \lstrcpyA
0040273F |. 8DBC24 080100>lea edi, dword ptr [esp+108]
00402746 |. 83C9 FF or ecx, FFFFFFFF
00402749 |. 33C0 xor eax, eax
0040274B |. F2:AE repne scas byte ptr es:[edi]
0040274D |. F7D1 not ecx
0040274F |. 49 dec ecx
00402750 |. 8D7C24 08 lea edi, dword ptr [esp+8]
00402754 |. 8BD1 mov edx, ecx
00402756 |. 83C9 FF or ecx, FFFFFFFF
00402759 |. F2:AE repne scas byte ptr es:[edi]
0040275B |. F7D1 not ecx
0040275D |. 49 dec ecx
0040275E |. 3BCA cmp ecx, edx
00402760 |. 75 40 jnz short 004027A2
00402762 |. 8D7C24 08 lea edi, dword ptr [esp+8]
00402766 |. 83C9 FF or ecx, FFFFFFFF
00402769 |. 33D2 xor edx, edx
0040276B |. F2:AE repne scas byte ptr es:[edi]
0040276D |. F7D1 not ecx
0040276F |. 49 dec ecx
00402770 |. 74 22 je short 00402794
00402772 |> 8A4414 08 /mov al, byte ptr [esp+edx+8]
00402776 |. 8A8C14 080100>|mov cl, byte ptr [esp+edx+108]
0040277D |. 3AC1 |cmp al, cl
0040277F |. 75 21 |jnz short 004027A2
00402781 |. 8D7C24 08 |lea edi, dword ptr [esp+8]
00402785 |. 83C9 FF |or ecx, FFFFFFFF
00402788 |. 33C0 |xor eax, eax
0040278A |. 42 |inc edx
0040278B |. F2:AE |repne scas byte ptr es:[edi]
0040278D |. F7D1 |not ecx
0040278F |. 49 |dec ecx
00402790 |. 3BD1 |cmp edx, ecx
00402792 |.^ 72 DE \jb short 00402772
00402794 |> 5F pop edi
00402795 |. B8 01000000 mov eax, 1
0040279A |. 5E pop esi
0040279B |. 81C4 00020000 add esp, 200
004027A1 |. C3 retn
004027A2 |> 5F pop edi
004027A3 |. 33C0 xor eax, eax
004027A5 |. 5E pop esi
004027A6 |. 81C4 00020000 add esp, 200
004027AC \. C3 retn
以上这个函数的功能是比较两个字符串,相等返回1否则返回0,我将它写成一个C函数,代码如下:
BOOL StrCompare(char *str1,char *str2)
{
char a[256]={0};
char b[256]={0};
unsigned int i;
strcpy(a,str1);
strcpy(b,str2);
if (strlen(b)!=strlen(a))
{
return FALSE;
}
for (i=0;i<strlen(a);i++)
{
if (a[i]!=b[i])
{
return FALSE;
}
}
return TRUE;
}
00402914 . 83C4 14 add esp, 14 ;根据上面函数返回的结果是否为1来判断注册码是否正确
00402917 . 83F8 01 cmp eax, 1 ;是1就正确,反之不正确。
0040291A . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040291C . 68 A4D14000 push 0040D1A4 ; |Title = ""D7,"",A2,"",B2,"崽崾?
00402921 75 18 jnz short 0040293B ;跳走则完蛋,爆破点,nop之则爆破。
00402923 . 68 60D14000 push 0040D160 ; |Text = "恭?,B2,"你?,AC,"",D7,"",A2,"",B2,"崧胝",B7,"!"
00402928 . 56 push esi ; |hOwner
00402929 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
0040292F . 5F pop edi
00402930 . 5E pop esi
00402931 . 33C0 xor eax, eax
00402933 . 5D pop ebp
00402934 . 81C4 00030000 add esp, 300
0040293A . C3 retn
0040293B > 68 48D14000 push 0040D148 ; |Text = ""D7,"",A2,"",B2,"崧?,B4,"砦螅",AC,"继续加油!"
00402940 . 56 push esi ; |hOwner
00402941 . FF15 D4B04000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
00402947 . 5F pop edi
00402948 . 5E pop esi
00402949 . 33C0 xor eax, eax
0040294B . 5D pop ebp
0040294C . 81C4 00030000 add esp, 300
00402952 . C3 retn
00402953 > 8B0D 6C014100 mov ecx, dword ptr [41016C] ; Case 110 (WM_INITDIALOG) of switch 0040280B
00402959 . 68 9A000000 push 9A ; /RsrcName = 154.
0040295E . 51 push ecx ; |hInst => NULL
0040295F . FF15 D8B04000 call dword ptr [<&USER32.LoadIconA>] ; \LoadIconA
00402965 . 8B9424 100300>mov edx, dword ptr [esp+310]
0040296C . 50 push eax ; /lParam
0040296D . 6A 01 push 1 ; |wParam = 1
0040296F . 68 80000000 push 80 ; |Message = WM_SETICON
00402974 . 52 push edx ; |hWnd
00402975 . A3 68014100 mov dword ptr [410168], eax ; |
0040297A . FF15 DCB04000 call dword ptr [<&USER32.SendMessageA>; \SendMessageA
00402980 . 5F pop edi
00402981 . 5E pop esi
00402982 . 33C0 xor eax, eax
00402984 . 5D pop ebp
00402985 . 81C4 00030000 add esp, 300
0040298B . C3 retn
经过上面的分析知只要输入的注册码为用户名经过MD5运算得到的HASH字符串,那么注册成功,反之注册失败。因此这个MD5CrackMe的注册机就是一个MD5计算器,
我把加密与解密(第二版)光盘中第6章的MD5计算器也放在附件里。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [求助]为什么调用URLDownloadToCacheFile出错? 6226
- [注意]安焦网站被假冒来骗钱了 3862
- [原创]pediy answer 14441
- [原创]MD5CrackMe.exe的破解 5985
看原图
赞赏
雪币:
留言: