系統 : Windows xpphp
程序 : KeyGenMe-iNF1html
程序下載地址 :https://pan.baidu.com/s/1nvfLBIh
算法
要求 : 編寫Keygen框架
使用工具 : OD函數
可在看雪論壇中查找關於此程序的破文:傳送門工具
打開od,根據字符串「Serial is Correct!!!\nNow make a keygen」找到關鍵算法:spa
00401530 /$ 8B4C24 04 mov ecx,dword ptr ss:[esp+0x4] 00401534 |. 8D4424 04 lea eax,dword ptr ss:[esp+0x4] 00401538 |. 50 push eax 00401539 |. 68 20304000 push KeyGenMe.00403020 ; |%x
0040153E |. 51 push ecx ; |s
0040153F |. FF15 A4214000 call dword ptr ds:[<&MSVCRT.sscanf>] ; \sscanf
00401545 |. 8B4424 10 mov eax,dword ptr ss:[esp+0x10] ; 將密碼從字符串形式轉換成十六進制
00401549 |. 83C4 0C add esp,0xC ; 平衡堆棧
0040154C \. C3 retn
0040154D 90 nop
0040154E 90 nop
0040154F 90 nop
00401550 . 83EC 2C sub esp,0x2C 00401553 . 8D4424 0C lea eax,dword ptr ss:[esp+0xC] 00401557 . 53 push ebx 00401558 . 56 push esi 00401559 . 57 push edi 0040155A . 6A 1F push 0x1F 0040155C . 50 push eax 0040155D . 8BF9 mov edi,ecx 0040155F . 68 E8030000 push 0x3E8 00401564 . E8 29030000 call <jmp.&MFC42.#3098> ; 獲取字符串
00401569 . 8D4C24 0C lea ecx,dword ptr ss:[esp+0xC] 0040156D . 6A 0A push 0xA 0040156F . 51 push ecx 00401570 . 68 E9030000 push 0x3E9 00401575 . 8BCF mov ecx,edi 00401577 . E8 16030000 call <jmp.&MFC42.#3098> ; 獲取字符串
0040157C . BE 3C314000 mov esi,KeyGenMe.0040313C
00401581 . 8D4424 18 lea eax,dword ptr ss:[esp+0x18] 00401585 > 8A10 mov dl,byte ptr ds:[eax] ; 存儲用戶名字符串首字符
00401587 . 8A1E mov bl,byte ptr ds:[esi] 00401589 . 8ACA mov cl,dl 0040158B . 3AD3 cmp dl,bl 0040158D . 75 1E jnz XKeyGenMe.004015AD ; 首字符不等於00則進行跳轉
0040158F . 84C9 test cl,cl 00401591 . 74 16 je XKeyGenMe.004015A9
00401593 . 8A50 01 mov dl,byte ptr ds:[eax+0x1] 00401596 . 8A5E 01 mov bl,byte ptr ds:[esi+0x1] 00401599 . 8ACA mov cl,dl 0040159B . 3AD3 cmp dl,bl 0040159D . 75 0E jnz XKeyGenMe.004015AD
0040159F . 83C0 02 add eax,0x2 004015A2 . 83C6 02 add esi,0x2 004015A5 . 84C9 test cl,cl 004015A7 .^ 75 DC jnz XKeyGenMe.00401585
004015A9 > 33C0 xor eax,eax 004015AB . EB 05 jmp XKeyGenMe.004015B2
004015AD > 1BC0 sbb eax,eax 004015AF . 83D8 FF sbb eax,-0x1 004015B2 > 85C0 test eax,eax ; 若是eax等於 0,則跳轉
004015B4 . 0F84 A1000000 je KeyGenMe.0040165B
004015BA . BE 3C314000 mov esi,KeyGenMe.0040313C
004015BF . 8D4424 0C lea eax,dword ptr ss:[esp+0xC] ; 取密碼
004015C3 > 8A10 mov dl,byte ptr ds:[eax] ; 取密碼首字符
004015C5 . 8A1E mov bl,byte ptr ds:[esi] 004015C7 . 8ACA mov cl,dl 004015C9 . 3AD3 cmp dl,bl 004015CB . 75 1E jnz XKeyGenMe.004015EB
004015CD . 84C9 test cl,cl 004015CF . 74 16 je XKeyGenMe.004015E7
004015D1 . 8A50 01 mov dl,byte ptr ds:[eax+0x1] 004015D4 . 8A5E 01 mov bl,byte ptr ds:[esi+0x1] 004015D7 . 8ACA mov cl,dl 004015D9 . 3AD3 cmp dl,bl 004015DB . 75 0E jnz XKeyGenMe.004015EB
004015DD . 83C0 02 add eax,0x2 004015E0 . 83C6 02 add esi,0x2 004015E3 . 84C9 test cl,cl 004015E5 .^ 75 DC jnz XKeyGenMe.004015C3
004015E7 > 33C0 xor eax,eax 004015E9 . EB 05 jmp XKeyGenMe.004015F0
004015EB > 1BC0 sbb eax,eax 004015ED . 83D8 FF sbb eax,-0x1 004015F0 > 85C0 test eax,eax ; 若是eax等於 0,則跳轉
004015F2 . 74 67 je XKeyGenMe.0040165B
004015F4 . 8D4424 0C lea eax,dword ptr ss:[esp+0xC] 004015F8 . 50 push eax ; 取密碼
004015F9 . E8 B2FEFFFF call KeyGenMe.004014B0
004015FE . 83C4 04 add esp,0x4 00401601 . 85C0 test eax,eax 00401603 . 74 66 je XKeyGenMe.0040166B ; call結果爲0則爲不正確
00401605 . 8D4C24 0C lea ecx,dword ptr ss:[esp+0xC] 00401609 . 51 push ecx 0040160A . E8 21FFFFFF call KeyGenMe.00401530
0040160F . 8D5424 1C lea edx,dword ptr ss:[esp+0x1C] ; 取用戶名
00401613 . 8BF0 mov esi,eax 00401615 . 52 push edx ; 傳入 密碼、用戶名
00401616 . E8 55FEFFFF call KeyGenMe.00401470 ; F(用戶名)
0040161B . 05 8F020000 add eax,0x28F 00401620 . B9 34120000 mov ecx,0x1234 00401625 . 99 cdq
00401626 . F7F9 idiv ecx 00401628 . B9 01000100 mov ecx,0x10001 0040162D . 83C4 08 add esp,0x8 00401630 . 8BC2 mov eax,edx 00401632 . 0FAFC6 imul eax,esi ; eax * 密碼 = 10002
00401635 . 99 cdq
00401636 . F7F9 idiv ecx 00401638 . B8 01000000 mov eax,0x1 0040163D . 2BC2 sub eax,edx ; 結果算出來edx等於1
0040163F . 75 2A jnz XKeyGenMe.0040166B
00401641 . 6A 00 push 0x0 00401643 . 68 60304000 push KeyGenMe.00403060 ; Good Work
00401648 . 68 38304000 push KeyGenMe.00403038 ; Serial is Correct!!!\nNow make a keygen
0040164D . 8BCF mov ecx,edi 0040164F . E8 38020000 call <jmp.&MFC42.#4224> 00401654 . 5F pop edi 00401655 . 5E pop esi 00401656 . 5B pop ebx 00401657 . 83C4 2C add esp,0x2C 0040165A . C3 retn
0040165B > 6A 00 push 0x0 0040165D . 6A 00 push 0x0 0040165F . 68 24304000 push KeyGenMe.00403024 ; Insufficient Info
00401664 . 8BCF mov ecx,edi 00401666 . E8 21020000 call <jmp.&MFC42.#4224> 0040166B > 5F pop edi 0040166C . 5E pop esi 0040166D . 5B pop ebx 0040166E . 83C4 2C add esp,0x2C 00401671 . C3 retn
跟入f(用戶名):code
00401470 /$ 8B5424 04 mov edx,dword ptr ss:[esp+0x4] 00401474 |. B8 9A020000 mov eax,0x29A 00401479 |. 8A0A mov cl,byte ptr ds:[edx] ; 取首字符
0040147B |. 84C9 test cl,cl 0040147D |. 74 2E je XKeyGenMe.004014AD ; 爲空則直接退出call
0040147F |. 56 push esi 00401480 |> 0FBEC9 /movsx ecx,cl 00401483 |. 8BF1 |mov esi,ecx 00401485 |. 81F6 DADA0000 |xor esi,0xDADA ; 字符與固定值異或
0040148B |. 03F0 |add esi,eax ; 再加上固定值
0040148D |. 8BC1 |mov eax,ecx ; 再取用戶名的字符
0040148F |. 35 BEBA0000 |xor eax,0xBABE 00401494 |. 81F1 01F00000 |xor ecx,0xF001 0040149A |. F7D0 |not eax 0040149C |. 8D04B0 |lea eax,dword ptr ds:[eax+esi*4] 0040149F |. C1F8 03 |sar eax,0x3 ; 算數右移
004014A2 |. 03C1 |add eax,ecx 004014A4 |. 8A4A 01 |mov cl,byte ptr ds:[edx+0x1] ; 取下一個
004014A7 |. 42 |inc edx 004014A8 |. 84C9 |test cl,cl ; 是否已經迭代完畢
004014AA |.^ 75 D4 \jnz XKeyGenMe.00401480
004014AC |. 5E pop esi 004014AD \> C3 retn
根據以上彙編代碼,能夠很容易地寫出註冊機。orm
直接打開http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,修改OnBtnDecrypt函數以下:htm
void CKeygenDlg::OnBtnDecrypt() { // TODO: Add your control notification handler code here
CString Name = ""; GetDlgItemText( IDC_EDIT_NAME,Name ); if ( Name.GetLength() == 0 ){ MessageBox( "用戶名不能爲空!" ); return ; } unsigned int ESI = 0; unsigned int a = 0x29A; unsigned int ECX = 0; for ( int i = 0 ; i != Name.GetLength() ; i++ ){ ESI = (Name[i] ^ 0xDADA) + a; a = (Name[i] ^ 0xBABE); ECX = Name[i] ^ 0xF001; __asm{ push eax mov eax,a not eax mov a,eax pop eax } a = a + ESI * 4; a = a>>3; a += ECX; } a = ( a + 0x28F ) % 0x1234; for ( int j = 1 ; j != 1000000 ; j++ ) if ( (j*a) % 0x10001 == 1 ) break; CString PassWord; PassWord.Format( "%x",j ); SetDlgItemText( IDC_EDIT_SERIAL,PassWord ); }
再在OnInitDialog中添加此代碼修改標題:SetWindowText(_T("Keygen"));
運行效果: