【文章标题】: asdfslw第一个crackme算法分析+注册机
【文章作者】: patapon
【下载地址】: http://bbs.pediy.com/showthread.php?t=101115
【保护方式】: 简单的密码学保护
【使用工具】: PEID IDA OllyDbg
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
首先PEID查壳,显示为Nothing found *。由于cm作者提示使用了密码学算法,所以用插件KANAL看了下,发现有CRC32,MD5
和大数运算3种密码学算法。用IDA载入cm后,载入对应的sig文件输出为map,可以帮助我们在OD中更好的分析。OD载入后,
下断点bp GetDlgItemTextA,输入name:pediy,serial:12345678。点击Register,cm断下,F8单步分析如下:
00401120 /$ 55 push ebp
00401121 |. 8BEC mov ebp, esp
00401123 |. 83EC 1C sub esp, 1C
00401126 |. 53 push ebx
00401127 |. 56 push esi
00401128 |. 57 push edi
00401129 |. 6A 10 push 10
0040112B |. 6A 64 push 64
0040112D |. E8 DE100000 call 00402210
00401132 |. 83C4 08 add esp, 8
00401135 |. 8945 E4 mov dword ptr [ebp-1C], eax
00401138 |. 8B45 E4 mov eax, dword ptr [ebp-1C]
0040113B |. C780 34020000>mov dword ptr [eax+234], 10
00401145 |. 6A 00 push 0
00401147 |. E8 A40E0000 call <_mirvar>
0040114C |. 83C4 04 add esp, 4
0040114F |. 8945 FC mov dword ptr [ebp-4], eax
00401152 |. 6A 00 push 0
00401154 |. E8 970E0000 call <_mirvar>
00401159 |. 83C4 04 add esp, 4
0040115C |. 8945 F0 mov dword ptr [ebp-10], eax
0040115F |. 68 01000100 push 10001 e=10001h
00401164 |. E8 870E0000 call <_mirvar>
00401169 |. 83C4 04 add esp, 4
0040116C |. 8945 F4 mov dword ptr [ebp-C], eax
0040116F |. 6A 00 push 0
00401171 |. E8 7A0E0000 call <_mirvar>
00401176 |. 83C4 04 add esp, 4
00401179 |. 8945 E8 mov dword ptr [ebp-18], eax
0040117C |. 6A 15 push 15 ; /Count = 15 (21.)
0040117E |. 68 4C9D4000 push 00409D4C ; |Buffer = CrackMe.00409D4C
00401183 |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00401188 |. 8B4D 08 mov ecx, dword ptr [ebp+8] ; |
0040118B |. 51 push ecx ; |hWnd
0040118C |. FF15 44804000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
00401192 |. 8945 EC mov dword ptr [ebp-14], eax
00401195 |. 837D EC 00 cmp dword ptr [ebp-14], 0 ; 是否输入了name
00401199 |. 75 05 jnz short 004011A0
0040119B |. E9 67010000 jmp 00401307
004011A0 |> 68 F09C4000 push 00409CF0
004011A5 |. E8 16020000 call 004013C0 ; MD5_init
004011AA |. 83C4 04 add esp, 4
004011AD |. 8B55 EC mov edx, dword ptr [ebp-14]
004011B0 |. 52 push edx
004011B1 |. 68 4C9D4000 push 00409D4C
004011B6 |. 68 F09C4000 push 00409CF0
004011BB |. E8 30020000 call 004013F0 ; MD5_update
004011C0 |. 83C4 0C add esp, 0C
004011C3 |. 68 F09C4000 push 00409CF0
004011C8 |. E8 D3020000 call 004014A0 ; MD5_final
004011CD |. 83C4 04 add esp, 4
004011D0 |. 6A 21 push 21 ; /Count = 21 (33.)
004011D2 |. 68 649D4000 push 00409D64 ; |Buffer = CrackMe.00409D64
004011D7 |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
004011DC |. 8B45 08 mov eax, dword ptr [ebp+8] ; |
004011DF |. 50 push eax ; |hWnd
004011E0 |. FF15 44804000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
004011E6 |. 8945 EC mov dword ptr [ebp-14], eax
004011E9 |. 837D EC 00 cmp dword ptr [ebp-14], 0
004011ED |. 75 05 jnz short 004011F4
004011EF |. E9 13010000 jmp 00401307
004011F4 |> C745 F8 00000>mov dword ptr [ebp-8], 0
004011FB |. EB 09 jmp short 00401206
004011FD |> 8B4D F8 /mov ecx, dword ptr [ebp-8]
00401200 |. 83C1 01 |add ecx, 1
00401203 |. 894D F8 |mov dword ptr [ebp-8], ecx
00401206 |> 8B55 F8 mov edx, dword ptr [ebp-8]
00401209 |. 3B55 EC |cmp edx, dword ptr [ebp-14]
0040120C |. 73 1B |jnb short 00401229
0040120E |. 8B45 F8 |mov eax, dword ptr [ebp-8]
00401211 |. 0FBE88 649D40>|movsx ecx, byte ptr [eax+409D64]
00401218 |. 51 |push ecx ; /c
00401219 |. E8 E2610000 |call <isxdigit> ; \isxdigit
0040121E |. 83C4 04 |add esp, 4
00401221 |. 85C0 |test eax, eax
00401223 |. 75 02 |jnz short 00401227
00401225 |. EB 02 |jmp short 00401229
00401227 |>^ EB D4 \jmp short 004011FD 这里的循环检查每位serial的合法性
00401229 |> 8B55 F8 mov edx, dword ptr [ebp-8]
0040122C |. 3B55 EC cmp edx, dword ptr [ebp-14]
0040122F |. 74 05 je short 00401236
00401231 |. E9 D1000000 jmp 00401307
00401236 |> 68 649D4000 push 00409D64
0040123B |. 8B45 F0 mov eax, dword ptr [ebp-10]
0040123E |. 50 push eax
0040123F |. E8 AC2F0000 call <_cinstr> cinstr(y,serial)
00401244 |. 83C4 08 add esp, 8
00401247 |. 68 64904000 push 00409064 ; ASCII C707CFE4B36603079809554DA53BA22F"
0040124C |. 8B4D E8 mov ecx, dword ptr [ebp-18]
0040124F |. 51 push ecx
00401250 |. E8 9B2F0000 call <_cinstr> cinstr (z,"C707CFE4B36603079809554DA53BA22F")
00401255 |. 83C4 08 add esp, 8
00401258 |. 8B55 E8 mov edx, dword ptr [ebp-18]
0040125B |. 52 push edx
0040125C |. 8B45 F0 mov eax, dword ptr [ebp-10]
0040125F |. 50 push eax
00401260 |. E8 6B1C0000 call <_compare>
00401265 |. 83C4 08 add esp, 8
00401268 |. 83F8 FF cmp eax, -1
0040126B |. 7E 05 jle short 00401272
0040126D |. E9 95000000 jmp 00401307
00401272 |> 8B4D FC mov ecx, dword ptr [ebp-4]
00401275 |. 51 push ecx
00401276 |. 8B55 E8 mov edx, dword ptr [ebp-18]
00401279 |. 52 push edx
0040127A |. 8B45 F4 mov eax, dword ptr [ebp-C]
0040127D |. 50 push eax
0040127E |. 8B4D F0 mov ecx, dword ptr [ebp-10]
00401281 |. 51 push ecx
00401282 |. E8 39290000 call <_powmod> ; powmod(y,e,z,w)
00401287 |. 83C4 10 add esp, 10
0040128A |. 6A 00 push 0
0040128C |. 68 889D4000 push 00409D88
00401291 |. 8B55 FC mov edx, dword ptr [ebp-4]
00401294 |. 52 push edx
00401295 |. 6A 10 push 10
00401297 |. E8 D4260000 call <_big_to_bytes>
0040129C |. 83C4 10 add esp, 10
0040129F |. 8945 EC mov dword ptr [ebp-14], eax
004012A2 |. 56 push esi
004012A3 |. 57 push edi
004012A4 |. 8D35 889D4000 lea esi, dword ptr [409D88]
004012AA |. 8D3D F09C4000 lea edi, dword ptr [409CF0]
004012B0 |. B9 04000000 mov ecx, 4
004012B5 |. FC cld
004012B6 |. F3:A7 repe cmps dword ptr es:[edi], dword ptr [esi] 这里取MD5(name)和w进行比较
004012B8 |. 5F pop edi
004012B9 |. 5E pop esi
004012BA 75 16 jnz short 004012D2 关键跳
004012BC |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
004012BE |. 68 50904000 push 00409050 ; |Title = "congratulations!"
004012C3 |. 68 44904000 push 00409044 ; |Text = "good work!"
004012C8 |. 8B45 08 mov eax, dword ptr [ebp+8] ; |
004012CB |. 50 push eax ; |hOwner
004012CC |. FF15 2C804000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
到了这里这个cm的算法就很清晰了,即应该满足MD5(name) = (serial^e mod p)。我们可以用RSATool反算出d,然后就可以算
出serial了。最后贴上我的注册机源代码,第一次写密码学的注册机,跌跌撞撞总算是捣鼓出来了,希望各位大侠看了不要见笑
。。。
extern "C"
{
#include "miracl.h"
#include "mirdef.h"
#pragma comment( lib, "ms32.lib")
}
#if _DEBUG
#pragma comment(linker,"/NODEFAULTLIB:LIBC")
#endif
extern "C" void __iob_func()
{
return;
}
extern "C" void _alldvrm()
{
return;
}
#include<stdlib.h>
#include <Afx.h>
#include <stdio.h>
#include "MD5.h"
int main(int argc, char **argv)
{
char username[20];
CString name;
CString Hash;
char serial[50];
char Hash_out[50];
miracl *mip;
big x,y,z,w;
printf ("%s", "please input your username:");
scanf("%s", username);
name.Format("%s",username);
Hash = MD5_Caculate_String(username);
strncpy(Hash_out,(LPCTSTR)Hash,sizeof(Hash_out));
mip = mirsys(0x300, 16);
mip->IOBASE = 0x10;
x = mirvar(0);
y = mirvar(0);
z = mirvar(0);
w = mirvar(0);
cinstr(x,Hash_out);
cinstr(y,"C5393A8B1832A82025CA3614A6385C81");
cinstr(z,"C707CFE4B36603079809554DA53BA22F");
powmod(x, y, z,w);
cotstr(w,serial);
printf("your serial is:%s\n",serial);
system("pause");
mirkill(x);
mirkill(y);
mirkill(z);
mirkill(w);
mirexit();
return 0;
}
--------------------------------------------------------------------------------
【经验总结】
总得来说这个cm的确比较简单,不过分析了一下还是学到了不少东西。在此感谢asdfslw提供cm给我们练习,希望他能够提
供一份源代码。另外在注册机编写的过程中,得到了好友ximo老大和幻灭的大力帮助,在此也向他们表示感谢~~
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2009年11月16日 13:14:55
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课