• 菜鸟 学注册机编写之 “查表”


    测试环境

    系统: xp sp3

    调试器 :od 1.10

        高手不要见笑,仅供小菜玩乐,有不对或不足的地方还请多多指教,不胜感激!

    1.首先运行程序随便输入用户与注册码如下图所示:

    2.载入OD通过下MessageBoxA函数, F9运行程序, 随便输入用户名与注册码, 点ok后断下,如下图所示:

    3.然后堆栈回溯,来到如下关键地方

    00415BB0                    6A FF           push -0x1
    
    00415BB2                    68 58514200     push ahead_dv.00425158
    
    00415BB7                    64:A1 00000000  mov eax,dword ptr fs:[0]
    
    00415BBD                    50              push eax
    
    00415BBE                    64:8925 0000000>mov dword ptr fs:[0],esp
    
    00415BC5                    83EC 08         sub esp,0x8
    
    00415BC8                    56              push esi
    
    00415BC9                    8BF1            mov esi,ecx
    
    00415BCB                    8D4C24 04       lea ecx,dword ptr ss:[esp+0x4]
    
    00415BCF                    E8 74C90000     call <jmp.&MFC42.#??0CString@@QAE@XZ_540>
    
    00415BD4                    6A 01           push 0x1
    
    00415BD6                    8BCE            mov ecx,esi
    
    00415BD8                    C74424 18 00000>mov dword ptr ss:[esp+0x18],0x0
    
    00415BE0                    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],0x1
    
    00415BFF                    E8 CCFCFFFF     call ahead_dv.004158D0                                   ; 关键CALL 注册码相同则返回1
    
    00415C04                    83C4 08         add esp,0x8
    
    00415C07                    85C0            test eax,eax
    
    00415C09                    75 18           jnz short ahead_dv.00415C23                              ; 关键跳
    
    00415C0B                    6A 40           push 0x40
    
    00415C0D                    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,esi
    
    00415C19                    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 ebx
    
    004158D1                55              push ebp
    
    004158D2                8B6C24 0C       mov ebp,dword ptr ss:[esp+0xC]
    
    004158D6                56              push esi
    
    004158D7                57              push edi
    
    004158D8                BE 60354300     mov esi,ahead_dv.00433560
    
    004158DD                8BC5            mov eax,ebp
    
    004158DF                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                                                ; ---判断是否为0
    
    004158E7                75 1E           jnz short ahead_dv.00415907
    
    004158E9                84C9            test cl,cl
    
    004158EB                74 16           je short ahead_dv.00415903
    
    004158ED                8A50 01         mov dl,byte ptr ds:[eax+0x1]
    
    004158F0                8A5E 01         mov bl,byte ptr ds:[esi+0x1]
    
    004158F3                8ACA            mov cl,dl
    
    004158F5                3AD3            cmp dl,bl
    
    004158F7                75 0E           jnz short ahead_dv.00415907
    
    004158F9                83C0 02         add eax,0x2
    
    004158FC                83C6 02         add esi,0x2
    
    004158FF                84C9            test cl,cl
    
    00415901              ^ 75 DC           jnz short ahead_dv.004158DF
    
    00415903                33C0            xor eax,eax
    
    00415905                EB 05           jmp short ahead_dv.0041590C
    
    00415907                1BC0            sbb eax,eax
    
    00415909                83D8 FF         sbb eax,-0x1
    
    0041590C                85C0            test eax,eax
    
    0041590E                74 51           je short ahead_dv.00415961
    
    00415910                8B7C24 18       mov edi,dword ptr ss:[esp+0x18]                          ; --注册码
    
    00415914                BE 60354300     mov esi,ahead_dv.00433560
    
    00415919                8BC7            mov eax,edi
    
    0041591B                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                                                ; ---判断是否为0
    
    00415923                75 1E           jnz short ahead_dv.00415943
    
    00415925                84C9            test cl,cl
    
    00415927                74 16           je short ahead_dv.0041593F
    
    00415929                8A50 01         mov dl,byte ptr ds:[eax+0x1]
    
    0041592C                8A5E 01         mov bl,byte ptr ds:[esi+0x1]
    
    0041592F                8ACA            mov cl,dl
    
    00415931                3AD3            cmp dl,bl
    
    00415933                75 0E           jnz short ahead_dv.00415943
    
    00415935                83C0 02         add eax,0x2
    
    00415938                83C6 02         add esi,0x2
    
    0041593B                84C9            test cl,cl
    
    0041593D              ^ 75 DC           jnz short ahead_dv.0041591B
    
    0041593F                33C0            xor eax,eax
    
    00415941                EB 05           jmp short ahead_dv.00415948
    
    00415943                1BC0            sbb eax,eax
    
    00415945                83D8 FF         sbb eax,-0x1
    
    00415948                85C0            test eax,eax
    
    0041594A                74 15           je short ahead_dv.00415961
    
    0041594C                57              push edi                                                 ; 注册码
    
    0041594D                55              push ebp                                                 ; 用户名
    
    0041594E                E8 3DFDFFFF     call ahead_dv.00415690                                   ; 算法
    
    5.算法分析
    
    00415690                6A FF           push -0x1
    
    00415692                68 C0504200     push ahead_dv.004250C0
    
    00415697                64:A1 00000000  mov eax,dword ptr fs:[0]
    
    0041569D                50              push eax
    
    0041569E                64:8925 0000000>mov dword ptr fs:[0],esp
    
    004156A5                83EC 14         sub esp,0x14
    
    004156A8                8B4424 24       mov eax,dword ptr ss:[esp+0x24]                         ; 用户名
    
    004156AC                53              push ebx
    
    004156AD                55              push ebp
    
    004156AE                56              push esi
    
    004156AF                57              push edi
    
    004156B0                50              push eax
    
    004156B1                8D4C24 18       lea ecx,dword ptr ss:[esp+0x18]                         ; 用户名
    
    004156B5                E8 50D00000     call <jmp.&MFC42.#??0CString@@QAE@PBD@Z_537>
    
    004156BA                33F6            xor esi,esi
    
    004156BC                8D4C24 14       lea ecx,dword ptr ss:[esp+0x14]
    
    004156C0                897424 2C       mov dword ptr ss:[esp+0x2C],esi
    
    004156C4                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 0x20
    
    004156D4                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,eax
    
    004156E3                51              push ecx
    
    004156E4                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],0x1
    
    004156F6                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 0x20
    
    00415706                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,eax
    
    00415711                83C9 FF         or ecx,0xFFFFFFFF
    
    00415714                8BFA            mov edi,edx
    
    00415716                33C0            xor eax,eax
    
    00415718                F2:AE           repne scas byte ptr es:[edi]
    
    0041571A                F7D1            not ecx
    
    0041571C                49              dec ecx                                                 ; ---注册码长度
    
    0041571D                8BFB            mov edi,ebx
    
    0041571F                8BE9            mov ebp,ecx
    
    00415721                83C9 FF         or ecx,0xFFFFFFFF
    
    00415724                F2:AE           repne scas byte ptr es:[edi]
    
    00415726                F7D1            not ecx
    
    00415728                49              dec ecx                                                 ; 用户名长度
    
    00415729                895424 20       mov dword ptr ss:[esp+0x20],edx                         ; ---注册码地址
    
    0041572D                3BCD            cmp ecx,ebp                                             ; --用户名长度与注册码长度比较
    
    0041572F                0F87 64010000   ja ahead_dv.00415899
    
    00415735                8BFB            mov edi,ebx
    
    00415737                83C9 FF         or ecx,0xFFFFFFFF
    
    0041573A                F2:AE           repne scas byte ptr es:[edi]
    
    0041573C                F7D1            not ecx
    
    0041573E                49              dec ecx                                                 ; 用户名长度
    
    0041573F                0F84 54010000   je ahead_dv.00415899
    
    00415745                8BFA            mov edi,edx
    
    00415747                83C9 FF         or ecx,0xFFFFFFFF
    
    0041574A                F2:AE           repne scas byte ptr es:[edi]
    
    0041574C                F7D1            not ecx
    
    0041574E                49              dec ecx                                                 ; 注册码长度
    
    0041574F                0F84 44010000   je ahead_dv.00415899
    
    00415755                897424 38       mov dword ptr ss:[esp+0x38],esi
    
    00415759                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]                       ; 字符sdR
    
    00415767                884424 18       mov byte ptr ss:[esp+0x18],al
    
    0041576B                E8 D8CD0000     call <jmp.&MFC42.#??0CString@@QAE@XZ_540>
    
    00415770                8BFB            mov edi,ebx
    
    00415772                83C9 FF         or ecx,0xFFFFFFFF
    
    00415775                33C0            xor eax,eax
    
    00415777                33ED            xor ebp,ebp
    
    00415779                F2:AE           repne scas byte ptr es:[edi]
    
    0041577B                F7D1            not ecx
    
    0041577D                49              dec ecx                                                 ; 用户名长度
    
    0041577E                C64424 2C 02    mov byte ptr ss:[esp+0x2C],0x2
    
    00415783                74 50           je short ahead_dv.004157D5                              ; --查表开始
    
    00415785                8A0C2B          mov cl,byte ptr ds:[ebx+ebp]                            ; ---取用户名1字节
    
    00415788                33F6            xor esi,esi
    
    0041578A                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                                                 ; 计数加1
    
    00415797                3D C0284300     cmp eax,ahead_dv.004328C0                               ; 判断表是否到了结尾 ("sdR")
    
    0041579C              ^ 7C F1           jl short ahead_dv.0041578F
    
    0041579E                EB 11           jmp short ahead_dv.004157B1
    
    004157A0                8A0C75 59284300 mov cl,byte ptr ds:[esi*2+0x432859]                     ; ----取表中与用户名1字节相等的后一个元素
    
    004157A7                51              push ecx
    
    004157A8                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                                            ; ---判断计数是否为0x34
    
    004157B4                75 0E           jnz short ahead_dv.004157C4
    
    004157B6                8B5424 18       mov edx,dword ptr ss:[esp+0x18]                         ; ---在表中没查到情况
    
    004157BA                8D4C24 34       lea ecx,dword ptr ss:[esp+0x34]
    
    004157BE                52              push edx
    
    004157BF                E8 80D10000     call <jmp.&MFC42.#??YCString@@QAEABV0@D@Z_940>          ; 存放数字
    
    004157C4                8BFB            mov edi,ebx
    
    004157C6                83C9 FF         or ecx,0xFFFFFFFF
    
    004157C9                33C0            xor eax,eax
    
    004157CB                45              inc ebp
    
    004157CC                F2:AE           repne scas byte ptr es:[edi]
    
    004157CE                F7D1            not ecx
    
    004157D0                49              dec ecx                                                 ; 用户名长度
    
    004157D1                3BE9            cmp ebp,ecx                                             ; ---判断是否查表完成
    
    004157D3              ^ 72 B0           jb short ahead_dv.00415785
    
    004157D5                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                                            ; 判断是否大于等于0x10
    
    004157DF                7D 3A           jge short ahead_dv.0041581B                             ; 当用户名查表完后注册码长度不大于等于0x10,就自动填充
    
    004157E1                8BC1            mov eax,ecx
    
    004157E3                B9 10000000     mov ecx,0x10
    
    004157E8                2BC8            sub ecx,eax
    
    004157EA                8D5424 1C       lea edx,dword ptr ss:[esp+0x1C]
    
    004157EE                51              push ecx
    
    004157EF                52              push edx
    
    004157F0                B9 04374300     mov ecx,ahead_dv.00433704
    
    004157F5                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],0x3
    
    00415804                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],0x2
    
    00415812                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 ecx
    
    00415820                50              push eax
    
    00415821                FF15 94784200   call dword ptr ds:[<&MSVCRT._mbscmp>]                   ; 比较注册码是否相同
    
    00415827                83C4 08         add esp,0x8
    
    0041582A                85C0            test eax,eax
    
    0041582C                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 注册机------------------------
    
    ");
    
     
    
        printf("请输入用户名: ");
    
        scanf("%s",UserName);
    
     
    
        if (0x10 < strlen(UserName)-1)
    
        {
    
            printf("用户名不能超过16位,请重新输入!
    ");
    
            memset(UserName, 0, strlen(UserName));
    
            scanf("%s",UserName);
    
        }
    
     
    
        //-判断用户名是否为空
    
        if (0 == UserName[0])
    
        {
    
            printf("请输入用户名
    ");
    
            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("
    ");
    
        printf("注册码:%s
    ",License);
    
     
    
        system("pause");
    
     
    
        return 0;
    
    }

    8.    测试注册机

    输入用户名test

    如下图:

    9.运行软件输入注册码测试,如下图

    10.点确定后注册成功,如下图

    完成。

    样本及注册机源码下载

    http://yunpan.cn/cAFXm3tRsHJRU (提取码:2cac)

    当把学习当成一种习惯!
  • 相关阅读:
    udp和tcp
    以查询代替临时变量
    memcached内存管理
    设计模式适配器模式
    排序算法
    防止表单重复提交
    php的引用
    按位与,按位异或,按位取反
    git常用操作
    http
  • 原文地址:https://www.cnblogs.com/2014asm/p/4104313.html
Copyright © 2020-2023  润新知