首页 > 代码库 > 分析一个delphi程序
分析一个delphi程序
系统 : Windows xp
程序 : k4n6
程序下载地址 :https://pan.baidu.com/s/1pLANxyj
要求 : 注册机编写
使用工具 : OD & DeDe
可在看雪论坛中查找关于此程序的破文,传送门
首先在DeDe找到激发按钮点击事件的 代码:
0044435C 55 push ebp0044435D 8BEC mov ebp, esp0044435F 33C9 xor ecx, ecx00444361 51 push ecx00444362 51 push ecx00444363 51 push ecx00444364 51 push ecx00444365 51 push ecx00444366 51 push ecx00444367 51 push ecx00444368 51 push ecx00444369 53 push ebx0044436A 56 push esi0044436B 57 push edi0044436C 8BD8 mov ebx, eax0044436E 33C0 xor eax, eax00444370 55 push ebp* Possible String Reference to: ‘閒铥朕_^[嬪]?|00444371 680D454400 push $0044450D***** TRY|00444376 64FF30 push dword ptr fs:[eax]00444379 648920 mov fs:[eax], esp0044437C 8D55E4 lea edx, [ebp-$1C]* Reference to control Edit3 : TEdit|0044437F 8B83D8020000 mov eax, [ebx+$02D8]* Reference to: controls.TControl.GetText(TControl):TCaption;|00444385 E892F9FDFF call 00423D1C0044438A 8B45E4 mov eax, [ebp-$1C]* Reference to: system.@LStrLen:Integer;| or: system.@DynArrayLength;| or: system.DynArraySize(Pointer):Integer;|0044438D E8CEF7FBFF call 00403B6000444392 48 dec eax00444393 0F8C4C010000 jl 004444E500444399 8D55E8 lea edx, [ebp-$18]* Reference to control Edit3 : TEdit|0044439C 8B83D8020000 mov eax, [ebx+$02D8]
....略
看到提供的很多Call dede都提供了参考,再用od载入程序查看该段代码:
0044435C . 55 push ebp ; Button1Click0044435D . 8BEC mov ebp, esp0044435F . 33C9 xor ecx, ecx00444361 . 51 push ecx00444362 . 51 push ecx00444363 . 51 push ecx00444364 . 51 push ecx00444365 . 51 push ecx00444366 . 51 push ecx00444367 . 51 push ecx00444368 . 51 push ecx00444369 . 53 push ebx0044436A . 56 push esi0044436B . 57 push edi0044436C . 8BD8 mov ebx, eax0044436E . 33C0 xor eax, eax00444370 . 55 push ebp00444371 . 68 0D454400 push 0044450D00444376 . 64:FF30 push dword ptr fs:[eax]00444379 . 64:8920 mov dword ptr fs:[eax], esp0044437C . 8D55 E4 lea edx, dword ptr [ebp-1C]0044437F . 8B83 D8020000 mov eax, dword ptr [ebx+2D8]00444385 . E8 92F9FDFF call 00423D1C0044438A . 8B45 E4 mov eax, dword ptr [ebp-1C] ; 获取密钥0044438D . E8 CEF7FBFF call 00403B60 ; 取长度00444392 . 48 dec eax00444393 . 0F8C 4C010000 jl 004444E5 ; 字符串为空则跳出判断00444399 . 8D55 E8 lea edx, dword ptr [ebp-18]0044439C . 8B83 D8020000 mov eax, dword ptr [ebx+2D8]004443A2 . E8 75F9FDFF call 00423D1C004443A7 . 8D55 F0 lea edx, dword ptr [ebp-10]004443AA . 8B83 D0020000 mov eax, dword ptr [ebx+2D0]004443B0 . E8 67F9FDFF call 00423D1C004443B5 . 8D55 EC lea edx, dword ptr [ebp-14]004443B8 . 8B83 D4020000 mov eax, dword ptr [ebx+2D4]004443BE . E8 59F9FDFF call 00423D1C004443C3 . 8B45 F0 mov eax, dword ptr [ebp-10] ; 获取用户名004443C6 . E8 95F7FBFF call 00403B60 ; 取长度004443CB . 83F8 04 cmp eax, 4 ; 小于4则跳出判断004443CE . 0F8C 11010000 jl 004444E5004443D4 . 8B45 EC mov eax, dword ptr [ebp-14] ; 获取公司名004443D7 . E8 84F7FBFF call 00403B60 ; 取长度004443DC . 83F8 03 cmp eax, 3 ; 小于3则跳出判断004443DF . 0F8C 00010000 jl 004444E5004443E5 . 8B45 F0 mov eax, dword ptr [ebp-10] ; 取用户名004443E8 . 0FB600 movzx eax, byte ptr [eax] ; 取第一个字符004443EB . 0FB680 DF5944>movzx eax, byte ptr [eax+4459DF] ; 按照字符的值取出 表里的值,这里用插件取出表004443F2 . 8945 F4 mov dword ptr [ebp-C], eax004443F5 . 8B45 F0 mov eax, dword ptr [ebp-10]004443F8 . 0FB640 02 movzx eax, byte ptr [eax+2] ; 取第三个字符004443FC . 0FB6B0 DF5944>movzx esi, byte ptr [eax+4459DF] ; 按照字符的值取出 表里的值00444403 . 8B45 EC mov eax, dword ptr [ebp-14] ; 再取公司名00444406 . E8 55F7FBFF call 00403B60 ; 获取公司名长度0044440B . 8B55 EC mov edx, dword ptr [ebp-14] ; 保存公司名0044440E . 0FB64402 FE movzx eax, byte ptr [edx+eax-2] ; 取倒数第二个字符00444413 . 0FB6B8 DF5944>movzx edi, byte ptr [eax+4459DF] ; 按照字符的值取出 表里的值0044441A . 8B45 EC mov eax, dword ptr [ebp-14]0044441D . E8 3EF7FBFF call 00403B6000444422 . 8B55 EC mov edx, dword ptr [ebp-14]00444425 . 0FB64402 FF movzx eax, byte ptr [edx+eax-1] ; 取倒数第一个字符0044442A . 0FB680 DF5944>movzx eax, byte ptr [eax+4459DF] ; 按照字符的值取出 表里的值00444431 . 8B55 F0 mov edx, dword ptr [ebp-10]00444434 . 0FB652 03 movzx edx, byte ptr [edx+3] ; 取用户名第四个字符00444438 . 0FB692 DF5944>movzx edx, byte ptr [edx+4459DF] ; 按照字符的值取出 表里的值0044443F . 8B4D EC mov ecx, dword ptr [ebp-14]00444442 . 0FB649 02 movzx ecx, byte ptr [ecx+2] ; 取公司名第三个字符00444446 . 0FB689 DF5944>movzx ecx, byte ptr [ecx+4459DF] ; 按照字符的值取出 表里的值0044444D . 0FAFD1 imul edx, ecx00444450 . 8955 F8 mov dword ptr [ebp-8], edx ; 保存相乘结果00444453 . 8B55 F4 mov edx, dword ptr [ebp-C] ; 用户名第一个字符在表中对应的值00444456 . 0FAFD6 imul edx, esi00444459 . 0FAFD7 imul edx, edi0044445C . 0FAFD0 imul edx, eax0044445F . 0355 F8 add edx, dword ptr [ebp-8]00444462 . 8955 FC mov dword ptr [ebp-4], edx00444465 . 8B45 FC mov eax, dword ptr [ebp-4]00444468 . 35 D8280000 xor eax, 28D80044446D . 05 7D4A8D28 add eax, 288D4A7D00444472 . 8945 FC mov dword ptr [ebp-4], eax ; 结果保存00444475 . 8B45 FC mov eax, dword ptr [ebp-4]00444478 . B9 39300000 mov ecx, 30390044447D . C1C1 06 rol ecx, 6 ; 循环左移00444480 . 35 14970000 xor eax, 971400444485 . C1C8 02 ror eax, 200444488 . C1F8 03 sar eax, 3 ; 算数右移0044448B . 01C8 add eax, ecx0044448D . 0345 F8 add eax, dword ptr [ebp-8]00444490 . 40 inc eax00444491 . 66:F7D0 not ax00444494 . 09C1 or ecx, eax00444496 . 05 9A020000 add eax, 29A0044449B . 8945 FC mov dword ptr [ebp-4], eax ; 结果保存0044449E . 33C0 xor eax, eax004444A0 . 55 push ebp004444A1 . 68 DB444400 push 004444DB004444A6 . 64:FF30 push dword ptr fs:[eax]004444A9 . 64:8920 mov dword ptr fs:[eax], esp004444AC . 8D55 E0 lea edx, dword ptr [ebp-20]004444AF . 8B83 D8020000 mov eax, dword ptr [ebx+2D8]004444B5 . E8 62F8FDFF call 00423D1C ; 获取密钥004444BA . 8B45 E0 mov eax, dword ptr [ebp-20]004444BD . E8 4E36FCFF call 00407B10 ; StrToInt004444C2 . 3B45 FC cmp eax, dword ptr [ebp-4] ; 和结果是否相同?004444C5 . 75 0A jnz short 004444D1004444C7 . B8 24454400 mov eax, 00444524 ; good , this number come from your keygen ?004444CC . E8 A3FAFFFF call 00443F74 ; ShowMessage004444D1 > 33C0 xor eax, eax004444D3 . 5A pop edx004444D4 . 59 pop ecx004444D5 . 59 pop ecx
代码分析完毕,虽然变量操作很多很复杂,但耐下心来做的话还是觉得比较简单的。
打开http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,向着界面上多加一个编辑框和标签用来输入公司名。
ID: IDC_EDIT_COMPANY | TYPE:BUTTONID: IDC_STATIC | TYPE:Label | Caption:公司名
修改OnBtnDecrypt函数如下:
void CKengen_TemplateDlg::OnBtnDecrypt() { // TODO: Add your control notification handler code here CString name; GetDlgItemText( IDC_EDIT_NAME,name ); //获取用户名字串基本信息。 CString company; GetDlgItemText( IDC_EDIT_COMPANY,company ); //获取用户名字串基本信息。 if ( name.GetLength() >= 4 && company.GetLength() >= 3 ){ //格式控制。 int table[] = { 0x00, 0x10, 0x39, 0x44, 0x00, 0x24, 0x39, 0x44, 0x00, 0x0C, 0xAF, 0x40, 0x00, 0x14, 0xAF, 0x40, 0x00, 0x1C, 0xAF, 0x40, 0x00, 0x24, 0xAF, 0x40, 0x00, 0x34, 0xAF, 0x40, 0x00, 0x3C, 0xAF, 0x40, 0x00, 0x44, 0xAF, 0x40, 0x00, 0x4C, 0xAF, 0x40, 0x00, 0x54, 0xAF, 0x40, 0x00, 0x5C, 0xAF, 0x40, 0x00, 0x2C, 0xAF, 0x40, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x61, 0x23, 0x47, 0x0E, 0x26, 0x61, 0x20, 0x31, 0x49, 0x36, 0x24, 0x2B, 0x42, 0x31, 0x63, 0x0E, 0x29, 0x5E, 0x30, 0x4B, 0x38, 0x2A, 0x33, 0x44, 0x3D }; unsigned int ch = table[name[0]]; unsigned int ch2 = table[name[2]]; unsigned int ch3 = table[ company[company.GetLength() - 2] ]; unsigned int ch4 = table[ company[company.GetLength() - 1] ]; unsigned int ch5 = table[ name[3] ]; unsigned int ch6 = table[ company[2] ]; unsigned int res = ch5 * ch6; unsigned int res2 = ch * ch2 * ch3 * ch4 + res; unsigned int res3; //左移异或这些操作直接拷贝源汇编代码改改 __asm{ push eax push ecx mov eax, res2 xor eax, 0x28D8 add eax, 0x288D4A7D mov ecx, 0x3039 rol ecx, 6 xor eax, 0x9714 ror eax, 2 sar eax, 3 add eax, ecx add eax, res inc eax not ax or ecx, eax add eax, 0x29A mov res3, eax pop ecx pop eax } CString PassWord; PassWord.Format( "%lu",res3 ); SetDlgItemText( IDC_EDIT_PASSWORD2,PassWord ); } else MessageBox( "用户名格式错误!" );}
再将OnBtnCopy函数改成:
void CKengen_TemplateDlg::OnBtnCopy() { // TODO: Add your control notification handler code here CString cmd; GetDlgItemText( IDC_BTN_COPY,cmd ); if ( OpenClipboard() ){ //打开剪贴板 CString str; HANDLE hClip; char *pBuf; EmptyClipboard(); if ( cmd == "拷贝用户名" ) //如果命令是拷贝用户名 GetDlgItemText( IDC_EDIT_NAME,str ); else{ if ( cmd == "拷贝公司名" ) GetDlgItemText( IDC_EDIT_COMPANY,str ); else GetDlgItemText( IDC_EDIT_PASSWORD2,str ); } hClip = GlobalAlloc( GMEM_MOVEABLE,str.GetLength() + 1 ); pBuf = (char*)GlobalLock( hClip ); strcpy( pBuf,str ); GlobalUnlock( hClip ); SetClipboardData( CF_TEXT,hClip ); CloseClipboard(); if ( cmd == "拷贝用户名" ){ //变换命令 SetDlgItemText( IDC_BTN_COPY,"拷贝公司名" ); SetDlgItemText( IDC_STC_MSG,"拷贝用户名成功!" ); //提示成功 } else{ if ( cmd == "拷贝公司名" ){ SetDlgItemText( IDC_BTN_COPY,"拷贝序列号" ); SetDlgItemText( IDC_STC_MSG,"拷贝公司名成功!" ); } else{ SetDlgItemText( IDC_BTN_COPY,"拷贝用户名" ); SetDlgItemText( IDC_STC_MSG,"拷贝序列号成功!" ); } } } else SetDlgItemText( IDC_STC_MSG,"拷贝失败!" );}
再在OnInitDialog中添加此代码修改标题:SetWindowText(_T("Keygen"));
运行效果:
分析一个delphi程序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。