好友
阅读权限10
听众
最后登录1970-1-1
|
小子贼野
发表于 2009-10-8 19:30
本帖最后由 小子贼野 于 2009-10-8 19:38 编辑
【文章标题】: 大菜一号CM算法分析及注册机源码
【文章作者】: 小子贼野
【作者主页】: Http://Hi.BaiDu.Com/XiAoZi5
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
声明:此CM是大菜一号在我刚开始学习破解的时候专门为我写的,算法简单的不得了,以前也有发过这个CM的分析,但是
当时分析的很片面,因为当时啥也不懂,因为实在是太无聊了,所以才有的这篇文章,而且也好久没有发过文章了 ,所以就写了一下,这个CM让我想起了以前,想起了非常多的事情。。。
感谢大菜一号
今天心情非常烂
在写注册机的时候我只写出了控制台版本,Windows下的写的错误多多,感谢小伟的帮忙
第一次在52发文章,希望各位大牛不要笑话我
密码表:Q!W@E#$%RT^Y&U*()POI_+|-=\zXcV~!
RegName:xiaozi56 RegCode:=T!(zT#$
00401071 . B9 08000000 mov ecx,8
00401076 . BE 78604000 mov esi,CrAckME.00406078 ; q!w@e#$%rt^y&u*()poi_+|-=\zxcv~!//这里是密码表
0040107B . 8D7C24 74 lea edi,dword ptr ss:[esp+74]
0040107F . 33C0 xor eax,eax
00401081 . F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi>
00401083 . A4 movs byte ptr es:[edi],byte ptr ds:[esi]
00401084 . B9 19000000 mov ecx,19
00401089 . 8DBC24 FC000000 lea edi,dword ptr ss:[esp+FC]
00401090 . F3:AB rep stos dword ptr es:[edi]
00401092 . B9 19000000 mov ecx,19
00401097 . 8D7C24 10 lea edi,dword ptr ss:[esp+10]
0040109B . 8BAC24 64010000 mov ebp,dword ptr ss:[esp+164]
004010A2 . 8B1D 9C504000 mov ebx,dword ptr ds:[<&USER32.GetDlgItemText>; USER32.GetDlgItemTextA
004010A8 . F3:AB rep stos dword ptr es:[edi]
004010AA . B9 19000000 mov ecx,19
004010AF . 8DBC24 98000000 lea edi,dword ptr ss:[esp+98]
004010B6 . F3:AB rep stos dword ptr es:[edi]
004010B8 . 8D4424 10 lea eax,dword ptr ss:[esp+10]
004010BC . 6A FF push -1 ; /Count = FFFFFFFF (-1.)
004010BE . 50 push eax ; |Buffer
004010BF . 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
004010C4 . 55 push ebp ; |hWnd
004010C5 . 33F6 xor esi,esi ; |
004010C7 . FFD3 call ebx ; \GetDlgItemTextA来获取输入的用户名
004010C9 . 8D7C24 10 lea edi,dword ptr ss:[esp+10]
004010CD . 83C9 FF or ecx,FFFFFFFF
004010D0 . 33C0 xor eax,eax
004010D2 . F2:AE repne scas byte ptr es:[edi]
004010D4 . F7D1 not ecx
004010D6 . 49 dec ecx
004010D7 . 83F9 08 cmp ecx,8 ; 用户名长度为8
004010DA . 75 35 jnz short CrAckME.00401111
004010DC . 8D8C24 98000000 lea ecx,dword ptr ss:[esp+98]
004010E3 . 6A FF push -1 ; /Count = FFFFFFFF (-1.)
004010E5 . 51 push ecx ; |Buffer
004010E6 . 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
004010EB . 55 push ebp ; |hWnd
004010EC . FFD3 call ebx ; \GetDlgItemTextA来获取输入的注册码
004010EE . 8DBC24 98000000 lea edi,dword ptr ss:[esp+98]
004010F5 . 83C9 FF or ecx,FFFFFFFF
004010F8 . 33C0 xor eax,eax
004010FA . F2:AE repne scas byte ptr es:[edi]
004010FC . F7D1 not ecx
004010FE . 49 dec ecx
004010FF . 8D7C24 10 lea edi,dword ptr ss:[esp+10]
00401103 . 8BD1 mov edx,ecx
00401105 . 83C9 FF or ecx,FFFFFFFF
00401108 . F2:AE repne scas byte ptr es:[edi]
0040110A . F7D1 not ecx
0040110C . 49 dec ecx
0040110D . 3BD1 cmp edx,ecx ; 这里是比较用户名和注册码的位数
0040110F . 74 23 je short CrAckME.00401134 ; 用户名和注册码的位数必须相等
00401111 > 6A 30 push 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401113 . 68 6C604000 push CrAckME.0040606C ; |sorry..!
00401118 . 68 54604000 push CrAckME.00406054 ; |不对不对,再加油!^o^
0040111D . 55 push ebp ; |hOwner
0040111E . FF15 A0504000 call dword ptr ds:[<&USER32.MessageBoxA>] ; \MessageBoxA
00401124 . 5F pop edi
00401125 . 5E pop esi
00401126 . 5D pop ebp
00401127 . B8 01000000 mov eax,1
0040112C . 5B pop ebx
0040112D . 81C4 50010000 add esp,150
00401133 . C3 retn
00401134 > 8A4434 10 mov al,byte ptr ss:[esp+esi+10]
00401138 . 8B3D A0504000 mov edi,dword ptr ds:[<&USER32.MessageBoxA>] ; USER32.MessageBoxA
0040113E . 3C 30 cmp al,30
00401140 . 7C 0C jl short CrAckME.0040114E ; 注册码大于0x30
00401142 . 3C 7D cmp al,7D
00401144 . 7F 08 jg short CrAckME.0040114E ; 注册码大于0x7D
00401146 . 46 inc esi
00401147 . 83FE 08 cmp esi,8
0040114A .^ 7C E8 jl short CrAckME.00401134 ; 这个循环就是用户名必须是数字和字母
0040114C . EB 0F jmp short CrAckME.0040115D
0040114E > 6A 30 push 30
00401150 . 68 6C604000 push CrAckME.0040606C ; sorry..!
00401155 . 68 54604000 push CrAckME.00406054 ; 不对不对,再加油!^o^
0040115A . 55 push ebp
0040115B . FFD7 call edi
0040115D > 33C9 xor ecx,ecx ; ECX == 0
0040115F > 0FBE440C 10 movsx eax,byte ptr ss:[esp+ecx+10] ; 用户名的Ascii
00401164 . 99 cdq
00401165 . BE 30000000 mov esi,30 ; ESI == 30
0040116A . F7FE idiv esi ; 取余,EAX为商,EDX为余数
0040116C . 41 inc ecx ; 计数器加1
0040116D . 83F9 08 cmp ecx,8 ; 比较是否计算完成
00401170 . 8A4414 74 mov al,byte ptr ss:[esp+edx+74] ; 从表中取余数位置的字符到al,纪为Sn[n]
00401174 . 88840C FB000000 mov byte ptr ss:[esp+ecx+FB],al ; Sn[n]放到内存缓冲区
0040117B .^ 7C E2 jl short CrAckME.0040115F
0040117D . 8DB424 98000000 lea esi,dword ptr ss:[esp+98]
00401184 . 8D8424 FC000000 lea eax,dword ptr ss:[esp+FC]
0040118B > 8A10 mov dl,byte ptr ds:[eax]
0040118D . 8A1E mov bl,byte ptr ds:[esi]
0040118F . 8ACA mov cl,dl
00401191 . 3AD3 cmp dl,bl
00401193 . 75 1E jnz short CrAckME.004011B3
00401195 . 84C9 test cl,cl
00401197 . 74 16 je short CrAckME.004011AF
00401199 . 8A50 01 mov dl,byte ptr ds:[eax+1]
0040119C . 8A5E 01 mov bl,byte ptr ds:[esi+1]
0040119F . 8ACA mov cl,dl
004011A1 . 3AD3 cmp dl,bl
004011A3 . 75 0E jnz short CrAckME.004011B3
004011A5 . 83C0 02 add eax,2
004011A8 . 83C6 02 add esi,2
004011AB . 84C9 test cl,cl
004011AD .^ 75 DC jnz short CrAckME.0040118B
004011AF > 33C0 xor eax,eax
004011B1 . EB 05 jmp short CrAckME.004011B8
004011B3 > 1BC0 sbb eax,eax
004011B5 . 83D8 FF sbb eax,-1
004011B8 > 85C0 test eax,eax
004011BA . 6A 30 push 30
004011BC . 75 1D jnz short CrAckME.004011DB
004011BE . 68 4C604000 push CrAckME.0040604C ; 恭喜..!
004011C3 . 68 30604000 push CrAckME.00406030 ; oh,yeah~~小子,你又进步了!
004011C8 . 55 push ebp
004011C9 . FFD7 call edi
004011CB . 5F pop edi
004011CC . 5E pop esi
004011CD . 5D pop ebp
004011CE . B8 01000000 mov eax,1
004011D3 . 5B pop ebx
004011D4 . 81C4 50010000 add esp,150
004011DA . C3 retn
004011DB > 68 6C604000 push CrAckME.0040606C ; sorry..!
004011E0 . 68 54604000 push CrAckME.00406054 ; 不对不对,再加油!^o^
004011E5 . 55 push ebp
004011E6 . FFD7 call edi
004011E8 . 5F pop edi
004011E9 . 5E pop esi
004011EA . 5D pop ebp
004011EB . B8 01000000 mov eax,1
004011F0 . 5B pop ebx
004011F1 . 81C4 50010000 add esp,150
004011F7 . C3 retn
注册机源码:算法函数:
void GetSn( char *lpszStr, char *lpszRegCode )
{
char Table[] = "Q!W@E#$%RT^Y&U*()POI_+|-=\\zXcV~!";
int i = 0, n = 0, x = 0;
if ( strlen(lpszStr) != 8)
{
MessageBox( NULL, "请输入8个字符,仅支持数字与字母!", "提示", MB_ICONINFORMATION );
return;
}
for ( i; i < strlen(lpszStr); i++ )
{
n = lpszStr[i];
x = n % 0x30;
lpszRegCode[i] = Table[x];
}
}
窗口函数:
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
DialogBoxParam( hInstance, MAKEINTRESOURCE(IDD_FORMVIEW), NULL, MainDlgProc, NULL );
return 0;
}
BOOL CALLBACK MainDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
char szName[MAX_PATH] = {0};
char szRegCode[MAX_PATH] = {0};
switch ( uMsg )
{
case WM_COMMAND:
if (wParam == IDC_BUTTON1)
{
GetDlgItemText( hDlg, IDC_EDIT1, szName, MAX_PATH );
GetSn(szName,szRegCode);
SetDlgItemText( hDlg, IDC_EDIT2, szRegCode );
}
if (wParam == IDC_BUTTON2)
{
EndDialog( hDlg, 0 );
}
break;
case WM_CLOSE:
EndDialog( hDlg, 0 );
break;
}
return FALSE;
}
--------------------------------------------------------------------------------
【经验总结】
算法总结:
1、取用户名的Ascii,记为nAscii;
2、nAscii与0x30取余,余数记为x;
3、在密码表中找位置x的字符串,记为szRegCode;
以上计算以用户名的长度为步长,需要注意的是用户名只能是数字和字母
--------------------------------------------------------------------------------
【版权声明】: 本文纯属技术交流,转载请注明作者并保持文章的完整,谢谢!
2009年10月08日 下午 06:41:12 |
-
|