菜鸟 学注册机编写之 “查表”
生活随笔
收集整理的這篇文章主要介紹了
菜鸟 学注册机编写之 “查表”
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
測試環境
系統: xp sp3
調試器 :od 1.10
? ? 高手不要見笑,僅供小菜玩樂,有不對或不足的地方還請多多指教,不勝感激!
1.首先運行程序隨便輸入用戶與注冊碼如下圖所示:
2.載入OD通過下MessageBoxA函數, F9運行程序, 隨便輸入用戶名與注冊碼, 點ok后斷下,如下圖所示:
3.然后堆棧回溯,來到如下關鍵地方
00415BB0 6A FF push -0x100415BB2 68 58514200 push ahead_dv.0042515800415BB7 64:A1 00000000 mov eax,dword ptr fs:[0]00415BBD 50 push eax00415BBE 64:8925 0000000>mov dword ptr fs:[0],esp00415BC5 83EC 08 sub esp,0x800415BC8 56 push esi00415BC9 8BF1 mov esi,ecx00415BCB 8D4C24 04 lea ecx,dword ptr ss:[esp+0x4]00415BCF E8 74C90000 call <jmp.&MFC42.#??0CString@@QAE@XZ_540>00415BD4 6A 01 push 0x100415BD6 8BCE mov ecx,esi00415BD8 C74424 18 00000>mov dword ptr ss:[esp+0x18],0x000415BE0 E8 7BC90000 call <jmp.&MFC42.#?UpdateData@CWnd@@QAEHH@Z_6334> ; ----獲得注冊碼00415BE5 E8 8EC90000 call <jmp.&MFC42.#?AfxGetModuleState@@YGPAVAFX_MODULE_ST>00415BEA 8B48 04 mov ecx,dword ptr ds:[eax+0x4]00415BED E8 44CF0000 call <jmp.&MFC42.#?BeginWaitCursor@CCmdTarget@@QAEXXZ_16>00415BF2 8B46 64 mov eax,dword ptr ds:[esi+0x64]00415BF5 8B4E 60 mov ecx,dword ptr ds:[esi+0x60]00415BF8 50 push eax ; ----注冊碼00415BF9 51 push ecx ; ----用戶名00415BFA C64424 1C 01 mov byte ptr ss:[esp+0x1C],0x100415BFF E8 CCFCFFFF call ahead_dv.004158D0 ; 關鍵CALL 注冊碼相同則返回100415C04 83C4 08 add esp,0x800415C07 85C0 test eax,eax00415C09 75 18 jnz short ahead_dv.00415C23 ; 關鍵跳00415C0B 6A 40 push 0x4000415C0D 68 6C294300 push ahead_dv.0043296C ; ASCII "Sorry"00415C12 68 40294300 push ahead_dv.00432940 ; ASCII "Invalid username or registration code "00415C17 8BCE mov ecx,esi00415C19 E8 82CB0000 call <jmp.&MFC42.#?MessageBoxA@CWnd@@QAEHPBD0I@Z_4224> ; 提示無效注冊碼00415C1E E9 BB000000 jmp ahead_dv.00415CDE?
4.分析關鍵CALL 004158D0 ; 關鍵CALL 注冊碼相同則返回1
004158D0 53 push ebx004158D1 55 push ebp004158D2 8B6C24 0C mov ebp,dword ptr ss:[esp+0xC]004158D6 56 push esi004158D7 57 push edi004158D8 BE 60354300 mov esi,ahead_dv.00433560004158DD 8BC5 mov eax,ebp004158DF 8A10 mov dl,byte ptr ds:[eax] ; ---取用戶名1字節004158E1 8A1E mov bl,byte ptr ds:[esi]004158E3 8ACA mov cl,dl ; ---用戶名第1字節004158E5 3AD3 cmp dl,bl ; ---判斷是否為0004158E7 75 1E jnz short ahead_dv.00415907004158E9 84C9 test cl,cl004158EB 74 16 je short ahead_dv.00415903004158ED 8A50 01 mov dl,byte ptr ds:[eax+0x1]004158F0 8A5E 01 mov bl,byte ptr ds:[esi+0x1]004158F3 8ACA mov cl,dl004158F5 3AD3 cmp dl,bl004158F7 75 0E jnz short ahead_dv.00415907004158F9 83C0 02 add eax,0x2004158FC 83C6 02 add esi,0x2004158FF 84C9 test cl,cl00415901 ^ 75 DC jnz short ahead_dv.004158DF00415903 33C0 xor eax,eax00415905 EB 05 jmp short ahead_dv.0041590C00415907 1BC0 sbb eax,eax00415909 83D8 FF sbb eax,-0x10041590C 85C0 test eax,eax0041590E 74 51 je short ahead_dv.0041596100415910 8B7C24 18 mov edi,dword ptr ss:[esp+0x18] ; --注冊碼00415914 BE 60354300 mov esi,ahead_dv.0043356000415919 8BC7 mov eax,edi0041591B 8A10 mov dl,byte ptr ds:[eax] ; ---取注冊碼1字節0041591D 8A1E mov bl,byte ptr ds:[esi]0041591F 8ACA mov cl,dl ; 注冊碼第1字節00415921 3AD3 cmp dl,bl ; ---判斷是否為000415923 75 1E jnz short ahead_dv.0041594300415925 84C9 test cl,cl00415927 74 16 je short ahead_dv.0041593F00415929 8A50 01 mov dl,byte ptr ds:[eax+0x1]0041592C 8A5E 01 mov bl,byte ptr ds:[esi+0x1]0041592F 8ACA mov cl,dl00415931 3AD3 cmp dl,bl00415933 75 0E jnz short ahead_dv.0041594300415935 83C0 02 add eax,0x200415938 83C6 02 add esi,0x20041593B 84C9 test cl,cl0041593D ^ 75 DC jnz short ahead_dv.0041591B0041593F 33C0 xor eax,eax00415941 EB 05 jmp short ahead_dv.0041594800415943 1BC0 sbb eax,eax00415945 83D8 FF sbb eax,-0x100415948 85C0 test eax,eax0041594A 74 15 je short ahead_dv.004159610041594C 57 push edi ; 注冊碼0041594D 55 push ebp ; 用戶名0041594E E8 3DFDFFFF call ahead_dv.00415690 ; 算法5.算法分析00415690 6A FF push -0x100415692 68 C0504200 push ahead_dv.004250C000415697 64:A1 00000000 mov eax,dword ptr fs:[0]0041569D 50 push eax0041569E 64:8925 0000000>mov dword ptr fs:[0],esp004156A5 83EC 14 sub esp,0x14004156A8 8B4424 24 mov eax,dword ptr ss:[esp+0x24] ; 用戶名004156AC 53 push ebx004156AD 55 push ebp004156AE 56 push esi004156AF 57 push edi004156B0 50 push eax004156B1 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18] ; 用戶名004156B5 E8 50D00000 call <jmp.&MFC42.#??0CString@@QAE@PBD@Z_537>004156BA 33F6 xor esi,esi004156BC 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]004156C0 897424 2C mov dword ptr ss:[esp+0x2C],esi004156C4 E8 67D40000 call <jmp.&MFC42.#?TrimLeft@CString@@QAEXXZ_6282> ; CString::TrimLeft 刪除用戶名的空格、換行符等004156C9 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]004156CD E8 58D40000 call <jmp.&MFC42.#?TrimRight@CString@@QAEXXZ_6283>004156D2 6A 20 push 0x20004156D4 8D4C24 18 lea ecx,dword ptr ss:[esp+0x18]004156D8 E8 93D00000 call <jmp.&MFC42.#?GetBuffer@CString@@QAEPADH@Z_2915> ; CString::GetBuffer 用戶名004156DD 8B4C24 38 mov ecx,dword ptr ss:[esp+0x38]004156E1 8BD8 mov ebx,eax004156E3 51 push ecx004156E4 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]004156E8 E8 1DD00000 call <jmp.&MFC42.#??0CString@@QAE@PBD@Z_537>004156ED 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]004156F1 C64424 2C 01 mov byte ptr ss:[esp+0x2C],0x1004156F6 E8 35D40000 call <jmp.&MFC42.#?TrimLeft@CString@@QAEXXZ_6282> ; CString::TrimLeft 刪除注冊碼的空格、換行符等004156FB 8D4C24 10 lea ecx,dword ptr ss:[esp+0x10]004156FF E8 26D40000 call <jmp.&MFC42.#?TrimRight@CString@@QAEXXZ_6283>00415704 6A 20 push 0x2000415706 8D4C24 14 lea ecx,dword ptr ss:[esp+0x14]0041570A E8 61D00000 call <jmp.&MFC42.#?GetBuffer@CString@@QAEPADH@Z_2915> ; CString::GetBuffer 注冊碼0041570F 8BD0 mov edx,eax00415711 83C9 FF or ecx,0xFFFFFFFF00415714 8BFA mov edi,edx00415716 33C0 xor eax,eax00415718 F2:AE repne scas byte ptr es:[edi]0041571A F7D1 not ecx0041571C 49 dec ecx ; ---注冊碼長度0041571D 8BFB mov edi,ebx0041571F 8BE9 mov ebp,ecx00415721 83C9 FF or ecx,0xFFFFFFFF00415724 F2:AE repne scas byte ptr es:[edi]00415726 F7D1 not ecx00415728 49 dec ecx ; 用戶名長度00415729 895424 20 mov dword ptr ss:[esp+0x20],edx ; ---注冊碼地址0041572D 3BCD cmp ecx,ebp ; --用戶名長度與注冊碼長度比較0041572F 0F87 64010000 ja ahead_dv.0041589900415735 8BFB mov edi,ebx00415737 83C9 FF or ecx,0xFFFFFFFF0041573A F2:AE repne scas byte ptr es:[edi]0041573C F7D1 not ecx0041573E 49 dec ecx ; 用戶名長度0041573F 0F84 54010000 je ahead_dv.0041589900415745 8BFA mov edi,edx00415747 83C9 FF or ecx,0xFFFFFFFF0041574A F2:AE repne scas byte ptr es:[edi]0041574C F7D1 not ecx0041574E 49 dec ecx ; 注冊碼長度0041574F 0F84 44010000 je ahead_dv.0041589900415755 897424 38 mov dword ptr ss:[esp+0x38],esi00415759 8B5424 38 mov edx,dword ptr ss:[esp+0x38]0041575D 8D4C24 34 lea ecx,dword ptr ss:[esp+0x34] ; 用戶名地址00415761 8A82 C0284300 mov al,byte ptr ds:[edx+0x4328C0] ; 字符sdR00415767 884424 18 mov byte ptr ss:[esp+0x18],al0041576B E8 D8CD0000 call <jmp.&MFC42.#??0CString@@QAE@XZ_540>00415770 8BFB mov edi,ebx00415772 83C9 FF or ecx,0xFFFFFFFF00415775 33C0 xor eax,eax00415777 33ED xor ebp,ebp00415779 F2:AE repne scas byte ptr es:[edi]0041577B F7D1 not ecx0041577D 49 dec ecx ; 用戶名長度0041577E C64424 2C 02 mov byte ptr ss:[esp+0x2C],0x200415783 74 50 je short ahead_dv.004157D5 ; --查表開始00415785 8A0C2B mov cl,byte ptr ds:[ebx+ebp] ; ---取用戶名1字節00415788 33F6 xor esi,esi0041578A B8 58284300 mov eax,ahead_dv.00432858 ; ASCII "aGbEcVdmelfSgmhkiEjckxlsmtnYobpkqDrtsatfuwvlwjxDyIzPAZBXCPDoEKFgGyHmItJaKrLqMNNQOUPuQGRJSLTnUbVCWFXH"0041578F 3A08 cmp cl,byte ptr ds:[eax] ; --用戶名1字節與表1字節相比較00415791 74 0D je short ahead_dv.004157A0 ; --是否相等00415793 83C0 02 add eax,0x2 ; ---表往后移2個元素00415796 46 inc esi ; 計數加100415797 3D C0284300 cmp eax,ahead_dv.004328C0 ; 判斷表是否到了結尾 ("sdR")0041579C ^ 7C F1 jl short ahead_dv.0041578F0041579E EB 11 jmp short ahead_dv.004157B1004157A0 8A0C75 59284300 mov cl,byte ptr ds:[esi*2+0x432859] ; ----取表中與用戶名1字節相等的后一個元素004157A7 51 push ecx004157A8 8D4C24 38 lea ecx,dword ptr ss:[esp+0x38]004157AC E8 93D10000 call <jmp.&MFC42.#??YCString@@QAEABV0@D@Z_940> ; ---存放查表后的結果004157B1 83FE 34 cmp esi,0x34 ; ---判斷計數是否為0x34004157B4 75 0E jnz short ahead_dv.004157C4004157B6 8B5424 18 mov edx,dword ptr ss:[esp+0x18] ; ---在表中沒查到情況004157BA 8D4C24 34 lea ecx,dword ptr ss:[esp+0x34]004157BE 52 push edx004157BF E8 80D10000 call <jmp.&MFC42.#??YCString@@QAEABV0@D@Z_940> ; 存放數字004157C4 8BFB mov edi,ebx004157C6 83C9 FF or ecx,0xFFFFFFFF004157C9 33C0 xor eax,eax004157CB 45 inc ebp004157CC F2:AE repne scas byte ptr es:[edi]004157CE F7D1 not ecx004157D0 49 dec ecx ; 用戶名長度004157D1 3BE9 cmp ebp,ecx ; ---判斷是否查表完成004157D3 ^ 72 B0 jb short ahead_dv.00415785004157D5 8B4424 34 mov eax,dword ptr ss:[esp+0x34] ; ----根據用戶名從表中查出的字符004157D9 8B48 F8 mov ecx,dword ptr ds:[eax-0x8] ; ---長度004157DC 83F9 10 cmp ecx,0x10 ; 判斷是否大于等于0x10004157DF 7D 3A jge short ahead_dv.0041581B ; 當用戶名查表完后注冊碼長度不大于等于0x10,就自動填充004157E1 8BC1 mov eax,ecx004157E3 B9 10000000 mov ecx,0x10004157E8 2BC8 sub ecx,eax004157EA 8D5424 1C lea edx,dword ptr ss:[esp+0x1C]004157EE 51 push ecx004157EF 52 push edx004157F0 B9 04374300 mov ecx,ahead_dv.00433704004157F5 E8 88CF0000 call <jmp.&MFC42.#?Left@CString@@QBE?AV1@H@Z_4129>004157FA 50 push eax ; 自動填充的字符004157FB 8D4C24 38 lea ecx,dword ptr ss:[esp+0x38]004157FF C64424 30 03 mov byte ptr ss:[esp+0x30],0x300415804 E8 69CD0000 call <jmp.&MFC42.#??YCString@@QAEABV0@ABV0@@Z_939> ; 與查表后的字符連接00415809 8D4C24 1C lea ecx,dword ptr ss:[esp+0x1C]0041580D C64424 2C 02 mov byte ptr ss:[esp+0x2C],0x200415812 E8 1FCD0000 call <jmp.&MFC42.#??1CString@@QAE@XZ_800>00415817 8B4424 34 mov eax,dword ptr ss:[esp+0x34] ; 連接后的注冊碼0041581B 8B4C24 20 mov ecx,dword ptr ss:[esp+0x20] ; 輸入的注冊碼0041581F 51 push ecx00415820 50 push eax00415821 FF15 94784200 call dword ptr ds:[<&MSVCRT._mbscmp>] ; 比較注冊碼是否相同00415827 83C4 08 add esp,0x80041582A 85C0 test eax,eax0041582C 74 24 je short ahead_dv.00415852?
6.分析總結
a)?? 判斷輸入的用戶名與注冊碼第1字節是否為空
b)?? 取輸入的用戶名循環在表中查找是否有該元素,如果有,則取表中該元素后一個元素做為注冊碼。
c)?? 如果在表中沒有查找到元素,則注冊碼給值為字符’s’,這里會出現萬能注冊碼,只要輸入的用戶名為0-9的數字,注冊碼都為 “ssssssssssssssss”。
d)?? 如果根用戶名查找獲得的注冊碼長度小于0x10則用固定字符填充。
7. 算法分析明白,就開始寫注冊機
#include "stdafx.h"#include <stdio.h>#include <windows.h>//-密碼表char *Table = "aGbEcVdmelfSgmhkiEjckxlsmtnYobpkqDrtsatfuwvlwjxDyIzPAZBXCPDoEKFgGyHmItJaKrLqMNNQOUPuQGRJSLTnUbVCWFXHYoZwsdR";//表結束標志char tag[4] = "sdR";//當查表后注冊碼不足16位長度時會用下面數據填充char *AtuoCode = "OgEScVdhYoalmbwp";int main(int argc, char* argv[]){char UserName[256] = {0};char License[256] = {0};printf("--------------Ahead DVD Copy 注冊機------------------------\n\n");printf("請輸入用戶名: ");scanf("%s",UserName);if (0x10 < strlen(UserName)-1){printf("用戶名不能超過16位,請重新輸入!\n");memset(UserName, 0, strlen(UserName));scanf("%s",UserName);}//-判斷用戶名是否為空if (0 == UserName[0]){printf("請輸入用戶名\n");return -1;}for (int i=0; i<strlen(UserName); i++){int index = 0;//--開始找表for (int n=0; n<= strlen(Table); n +=2){//--如果在表中查到用戶名數字if (UserName[i] == Table[n]){////-------取表下一位數字做注冊碼 License[i] = Table[index*2+1];break;}//--判斷表是否結束if (!strncmp(Table+n, tag, 3)){break;}index++;}//---判斷表是否查找完if (0x34 == index){License[i] = 's';}}//--------當用戶名查表完后注冊碼長度不等于0x10,就用固定字符填充if (0x10 != strlen(License)-1){//--填充注冊碼 strncpy(License+i, AtuoCode, strlen(AtuoCode)-strlen(License));}printf("\n");printf("注冊碼:%s\n",License);system("pause");return 0;}?
8.??? 測試注冊機
輸入用戶名test
如下圖:
9.運行軟件輸入注冊碼測試,如下圖
10.點確定后注冊成功,如下圖
完成。
樣本及注冊機源碼下載
http://yunpan.cn/cAFXm3tRsHJRU (提取碼:2cac)
轉載于:https://www.cnblogs.com/2014asm/p/4104313.html
總結
以上是生活随笔為你收集整理的菜鸟 学注册机编写之 “查表”的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java创建access数据库_使用Ja
- 下一篇: [EDI 案例] 汽车地带/Autozo