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


    测试环境
     系统: xp sp3

     调试器 :od 1.10

    sc_office_2003_pro

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

    一:定位关键CALL

    1. 因为该软件是word插件,所以用OD载入word.exe,F9运行,运行后如下图:

    2.  点击按钮”Save As PDF”出现如下界面

    3. 点击”Register”随便输入用户名与注册码,如下图:

    4.点击 “暂停”  点击 “K” ,来到如下图的地方

    5.选择”MessageBoxExW” 右键 “显示调用”,然后在函数尾下好断点,F9运行,点”确定”,就会被断下

    6.接下来就是一直F8单步走,来到如下图的地方

    7.往上找就能找到关键跳与关键CALL,如下图

    8.在关键CALL下好断点后重新载入OD, F9运行,随便输入用户名与注册码,接着就是分析算法了

    二:算法分析

    1.首先将注册码中含有小写字母转换成大写

    1010EC3B           8BC6            mov eax,esi
    
    1010EC3D           66:391E         cmp word ptr ds:[esi],bx                 ; ---将字母转换成大写
    
    1010EC40           74 1B           je short doc2pdf.1010EC5D
    
    1010EC42           0FB708          movzx ecx,word ptr ds:[eax]              ; 判断并取字符
    
    1010EC45           83F9 61         cmp ecx,0x61                             ; ECX小于a 就跳
    
    1010EC48           72 0B           jb short doc2pdf.1010EC55
    
    1010EC4A           83F9 7A         cmp ecx,0x7A                             ; ECX大于z 就跳
    
    1010EC4D           77 06           ja short doc2pdf.1010EC55
    
    1010EC4F           83C1 E0         add ecx,-0x20                            ; 满足条件就将ECX and -0x20
    
    1010EC52           66:8908         mov word ptr ds:[eax],cx                 ; 存放
    
    1010EC55           83C0 02         add eax,0x2
    
    1010EC58           66:3918         cmp word ptr ds:[eax],bx
    
    1010EC5B         ^ 75 E5           jnz short doc2pdf.1010EC42               ; 判断是否完成
    
    1010EC5D           33C0            xor eax,eax
    
    1010EC5F           E9 E2000000     jmp doc2pdf.1010ED46

    2.分析关键 call doc2pdf.100182D0 ,  F7跟进

    10018376 E8 25F0FFFF     call <doc2pdf.strcat>    ;用户名与固定字符串拼接
    
     
    
    1001741A E8 F1F3FEFF     call <doc2pdf.MtoB>     ; 将用户名中字母转换成大写
    
    1010EC3D           66:391E         cmp word ptr ds:[esi],bx                 ; ---将字母转换成大写
    
    1010EC40           74 1B           je short doc2pdf.1010EC5D
    
    1010EC42           0FB708          movzx ecx,word ptr ds:[eax]              ; 判断并取字符
    
    1010EC45           83F9 61         cmp ecx,0x61                             ; ECX小于a 就跳
    
    1010EC48           72 0B           jb short doc2pdf.1010EC55
    
    1010EC4A           83F9 7A         cmp ecx,0x7A                             ; ECX大于z 就跳
    
    1010EC4D           77 06           ja short doc2pdf.1010EC55
    
    1010EC4F           83C1 E0         add ecx,-0x20                            ; 满足条件就将ECX and -0x20
    
    1010EC52           66:8908         mov word ptr ds:[eax],cx                 ; 存放
    
    1010EC55           83C0 02         add eax,0x2
    
    1010EC58           66:3918         cmp word ptr ds:[eax],bx
    
    1010EC5B         ^ 75 E5           jnz short doc2pdf.1010EC42               ; 判断是否完成
    
    1010EC5D           33C0            xor eax,eax
    
    1010EC5F           E9 E2000000     jmp doc2pdf.1010ED46
    
     
    
     
    
    1001744B           E8 A0280000     call <doc2pdf.WideCharToMultiByte>       ; 将用户名宽字符转换成单字符
    
     
    
    1001745E           E8 FD280000     call <doc2pdf.Remove_digital>            ; 去掉用户输入用户名中包含的数字
    
    10019D60 <doc2pd>  55              push ebp
    
    10019D61           8BEC            mov ebp,esp
    
    10019D63           56              push esi
    
    10019D64           8B75 08         mov esi,dword ptr ss:[ebp+0x8]
    
    10019D67           85F6            test esi,esi
    
    10019D69           74 37           je short doc2pdf.10019DA2
    
    10019D6B           8B55 0C         mov edx,dword ptr ss:[ebp+0xC]
    
    10019D6E           85D2            test edx,edx
    
    10019D70           74 30           je short doc2pdf.10019DA2
    
    10019D72           8A0A            mov cl,byte ptr ds:[edx]
    
    10019D74           8BC6            mov eax,esi
    
    10019D76           84C9            test cl,cl
    
    10019D78           74 25           je short doc2pdf.10019D9F
    
    10019D7A           8D9B 00000000   lea ebx,dword ptr ds:[ebx]
    
    10019D80           80F9 61         cmp cl,0x61                              ; 判断字符a
    
    10019D83           7C 05           jl short doc2pdf.10019D8A
    
    10019D85           80F9 7A         cmp cl,0x7A                              ; 判断字符z
    
    10019D88           7E 0A           jle short doc2pdf.10019D94
    
    10019D8A           80F9 41         cmp cl,0x41                              ; 字符A
    
    10019D8D           7C 08           jl short doc2pdf.10019D97
    
    10019D8F           80F9 5A         cmp cl,0x5A                              ; 字符Z
    
    10019D92           7F 03           jg short doc2pdf.10019D97
    
    10019D94           880E            mov byte ptr ds:[esi],cl
    
    10019D96           46              inc esi
    
    10019D97           8A4A 01         mov cl,byte ptr ds:[edx+0x1]
    
    10019D9A           42              inc edx
    
    10019D9B           84C9            test cl,cl
    
    10019D9D         ^ 75 E1           jnz short doc2pdf.10019D80
    
    10019D9F           5E              pop esi
    
    10019DA0           5D              pop ebp
    
    10019DA1           C3              retn
    
    1001746D           E8 7E280000     call <doc2pdf.WideCharToMultiByte>       ; 将字串"f4hguNAg"转换成单字符
    
     
    
    10017485           E8 5D8F0F00     call <doc2pdf.strcat>                    ; 用户名去掉数字与固定字符串连接
    
    101103E7 <doc2pd>  8BFF            mov edi,edi
    
    101103E9           55              push ebp
    
    101103EA           8BEC            mov ebp,esp
    
    101103EC           8B4D 08         mov ecx,dword ptr ss:[ebp+0x8]
    
    101103EF           56              push esi
    
    101103F0           57              push edi
    
    101103F1           85C9            test ecx,ecx
    
    101103F3           74 07           je short doc2pdf.101103FC
    
    101103F5           8B7D 0C         mov edi,dword ptr ss:[ebp+0xC]
    
    101103F8           85FF            test edi,edi
    
    101103FA           75 13           jnz short doc2pdf.1011040F
    
    101103FC           E8 B00F0000     call doc2pdf.101113B1
    
    10110401           6A 16           push 0x16
    
    10110403           5E              pop esi
    
    10110404           8930            mov dword ptr ds:[eax],esi
    
    10110406           E8 B4490000     call doc2pdf.10114DBF
    
    1011040B           8BC6            mov eax,esi
    
    1011040D           EB 41           jmp short doc2pdf.10110450
    
    1011040F           8B55 10         mov edx,dword ptr ss:[ebp+0x10]
    
    10110412           85D2            test edx,edx
    
    10110414           75 05           jnz short doc2pdf.1011041B
    
    10110416           C601 00         mov byte ptr ds:[ecx],0x0
    
    10110419         ^ EB E1           jmp short doc2pdf.101103FC
    
    1011041B           8BF1            mov esi,ecx
    
    1011041D           803E 00         cmp byte ptr ds:[esi],0x0                ; 判断用户是否为0
    
    10110420           74 04           je short doc2pdf.10110426
    
    10110422           46              inc esi
    
    10110423           4F              dec edi
    
    10110424         ^ 75 F7           jnz short doc2pdf.1011041D
    
    10110426           85FF            test edi,edi
    
    10110428         ^ 74 EC           je short doc2pdf.10110416
    
    1011042A           2BF2            sub esi,edx
    
    1011042C           8A02            mov al,byte ptr ds:[edx]
    
    1011042E           880416          mov byte ptr ds:[esi+edx],al             ; ----字符串f4hguNAg与用户名连接
    
    10110431           42              inc edx
    
    10110432           84C0            test al,al
    
    10110434           74 03           je short doc2pdf.10110439
    
    10110436           4F              dec edi
    
    10110437         ^ 75 F3           jnz short doc2pdf.1011042C
    
    10110439           85FF            test edi,edi
    
    1011043B           75 11           jnz short doc2pdf.1011044E
    
    1011043D           C601 00         mov byte ptr ds:[ecx],0x0
    
    10110440           E8 6C0F0000     call doc2pdf.101113B1
    
    10110445           6A 22           push 0x22
    
    10110447           59              pop ecx
    
    10110448           8908            mov dword ptr ds:[eax],ecx
    
    1011044A           8BF1            mov esi,ecx
    
    1011044C         ^ EB B8           jmp short doc2pdf.10110406
    
    1011044E           33C0            xor eax,eax
    
    10110450           5F              pop edi
    
    10110451           5E              pop esi
    
    10110452           5D              pop ebp
    
    10110453           C3              retn

    拼接完成后得到字符串 “TESTf4hguNAg”

    将拼接完成后的字符传入函数进行计算, F7跟进,观察函数发下如下图所示特征

    貌似MD5计算,我们直接让该函数走完,看它会出什么结果,发现函数执行完后与我们用工具直接对字符串” TESTf4hguNAg”进行MD5的结果是一样的。如下图

    然后将计算得到的MD5值转换成字符,并且将小写字母转换成大写,如下图

    3.查找并替换MD5中的字符

    100183E2           6A 5A           push 0x5A                                 ; Z
    
    100183E4           6A 31           push 0x31                                 ; 1
    
    100183E6           8D8D 44FEFFFF   lea ecx,dword ptr ss:[ebp-0x1BC]
    
    100183EC           E8 6FE3FEFF     call <doc2pdf.Find_and_Replace>           ; 查找第1个参数,找到则用第2个替换

    1替换成Z

    2替换成W

    0替换成K

    3替换成T

    8替换成P

    7替换成S

    10006760 <doc2pd>  55              push ebp
    
    10006761           8BEC            mov ebp,esp
    
    10006763           83EC 08         sub esp,0x8
    
    10006766           66:8B45 08      mov ax,word ptr ss:[ebp+0x8]
    
    1000676A           53              push ebx
    
    1000676B           57              push edi
    
    1000676C           33FF            xor edi,edi
    
    1000676E           8BD9            mov ebx,ecx
    
    10006770           897D F8         mov dword ptr ss:[ebp-0x8],edi
    
    10006773           66:3B45 0C      cmp ax,word ptr ss:[ebp+0xC]
    
    10006777           74 72           je short doc2pdf.100067EB
    
    10006779           8B03            mov eax,dword ptr ds:[ebx]
    
    1000677B           56              push esi
    
    1000677C           8B70 F4         mov esi,dword ptr ds:[eax-0xC]
    
    1000677F           32C9            xor cl,cl
    
    10006781           3BF7            cmp esi,edi
    
    10006783           7E 65           jle short doc2pdf.100067EA
    
    10006785           66:8B55 08      mov dx,word ptr ss:[ebp+0x8]
    
    10006789           66:391478       cmp word ptr ds:[eax+edi*2],dx            ; 比较MD5值中是否有传进的第1个参数
    
    1000678D           75 37           jnz short doc2pdf.100067C6
    
    1000678F           84C9            test cl,cl
    
    10006791           75 28           jnz short doc2pdf.100067BB
    
    10006793           C645 FF 01      mov byte ptr ss:[ebp-0x1],0x1
    
    10006797           85F6            test esi,esi
    
    10006799           78 5B           js short doc2pdf.100067F6
    
    1000679B           8B03            mov eax,dword ptr ds:[ebx]                ; ----MD5值地址
    
    1000679D           8B50 F8         mov edx,dword ptr ds:[eax-0x8]
    
    100067A0           B9 01000000     mov ecx,0x1
    
    100067A5           2B48 FC         sub ecx,dword ptr ds:[eax-0x4]
    
    100067A8           2BD6            sub edx,esi
    
    100067AA           0BCA            or ecx,edx                                ; 0xA
    
    100067AC           7D 08           jge short doc2pdf.100067B6
    
    100067AE           56              push esi
    
    100067AF           8BCB            mov ecx,ebx
    
    100067B1           E8 BAEDFFFF     call doc2pdf.10005570
    
    100067B6           8B03            mov eax,dword ptr ds:[ebx]                ; ---MD5值地址
    
    100067B8           8A4D FF         mov cl,byte ptr ss:[ebp-0x1]
    
    100067BB           66:8B55 0C      mov dx,word ptr ss:[ebp+0xC]              ; ---函数传进来的第2个参数
    
    100067BF           FF45 F8         inc dword ptr ss:[ebp-0x8]
    
    100067C2           66:891478       mov word ptr ds:[eax+edi*2],dx            ; 将传进的第2个参数替换掉MD5中查到的值
    
    100067C6           8D7C3F 02       lea edi,dword ptr ds:[edi+edi+0x2]
    
    100067CA           D1FF            sar edi,1
    
    100067CC           3BFE            cmp edi,esi                               ; 判断是否查找结束
    
    100067CE         ^ 7C B5           jl short doc2pdf.10006785
    
    100067D0           84C9            test cl,cl
    
    100067D2           74 16           je short doc2pdf.100067EA
    
    100067D4           85F6            test esi,esi
    
    100067D6           78 1E           js short doc2pdf.100067F6
    
    100067D8           8B03            mov eax,dword ptr ds:[ebx]
    
    100067DA           3B70 F8         cmp esi,dword ptr ds:[eax-0x8]
    
    100067DD           7F 17           jg short doc2pdf.100067F6
    
    100067DF           8970 F4         mov dword ptr ds:[eax-0xC],esi
    
    100067E2           8B03            mov eax,dword ptr ds:[ebx]
    
    100067E4           33C9            xor ecx,ecx
    
    100067E6           66:890C70       mov word ptr ds:[eax+esi*2],cx
    
    100067EA           5E              pop esi
    
    100067EB           8B45 F8         mov eax,dword ptr ss:[ebp-0x8]
    
    100067EE           5F              pop edi
    
    100067EF           5B              pop ebx
    
    100067F0           8BE5            mov esp,ebp
    
    100067F2           5D              pop ebp
    
    100067F3           C2 0800         retn 0x8
    
     
    
     
    
    //--获得注册码
    
    1001844B           E8 90D9FEFF     call <doc2pdf.Get12Char>                  ; --获取MD5替换后前12字节
    
    10018450           6A 0C           push 0xC
    
    10018452           8D8D 38FEFFFF   lea ecx,dword ptr ss:[ebp-0x1C8]
    
    10018458           51              push ecx
    
    10018459           8BCB            mov ecx,ebx
    
    1001845B           C645 FC 02      mov byte ptr ss:[ebp-0x4],0x2
    
    1001845F           E8 7CD9FEFF     call <doc2pdf.Get12Char>                  ; --获取用户输入注册码12字节
    
    10018464           8B00            mov eax,dword ptr ds:[eax]

    4.比较注册码,如下图

    1010EB5D           8BFF            mov edi,edi
    1010EB5F           55              push ebp
    1010EB60           8BEC            mov ebp,esp
    1010EB62           833D 78EA1810 0>cmp dword ptr ds:[0x1018EA78],0x0
    1010EB69           56              push esi
    1010EB6A           75 69           jnz short doc2pdf.1010EBD5
    1010EB6C           8B75 08         mov esi,dword ptr ss:[ebp+0x8]
    1010EB6F           85F6            test esi,esi
    1010EB71           75 17           jnz short doc2pdf.1010EB8A
    1010EB73           E8 39280000     call doc2pdf.101113B1
    1010EB78           C700 16000000   mov dword ptr ds:[eax],0x16
    1010EB7E           E8 3C620000     call doc2pdf.10114DBF
    1010EB83           B8 FFFFFF7F     mov eax,0x7FFFFFFF
    1010EB88           EB 5B           jmp short doc2pdf.1010EBE5
    1010EB8A           8B4D 0C         mov ecx,dword ptr ss:[ebp+0xC]
    1010EB8D           85C9            test ecx,ecx
    1010EB8F         ^ 74 E2           je short doc2pdf.1010EB73
    1010EB91           2BF1            sub esi,ecx
    1010EB93           0FB7040E        movzx eax,word ptr ds:[esi+ecx]           ; 取MD5后生成的注册码
    1010EB97           83F8 41         cmp eax,0x41                              ; A
    1010EB9A           72 0D           jb short doc2pdf.1010EBA9
    1010EB9C           83F8 5A         cmp eax,0x5A                              ; Z
    1010EB9F           77 08           ja short doc2pdf.1010EBA9
    1010EBA1           83C0 20         add eax,0x20                              ; 转换成小写
    1010EBA4           0FB7D0          movzx edx,ax                              ; 给值dx
    1010EBA7           EB 02           jmp short doc2pdf.1010EBAB
    1010EBA9           8BD0            mov edx,eax
    1010EBAB           0FB701          movzx eax,word ptr ds:[ecx]               ; 取用户输入的注册码
    1010EBAE           83F8 41         cmp eax,0x41                              ; A
    1010EBB1           72 0B           jb short doc2pdf.1010EBBE
    1010EBB3           83F8 5A         cmp eax,0x5A                              ; Z
    1010EBB6           77 06           ja short doc2pdf.1010EBBE
    1010EBB8           83C0 20         add eax,0x20                              ; 转换成小写
    1010EBBB           0FB7C0          movzx eax,ax
    1010EBBE           83C1 02         add ecx,0x2
    1010EBC1           66:85D2         test dx,dx                                ; 判断是否为零
    1010EBC4           74 05           je short doc2pdf.1010EBCB
    1010EBC6           66:3BD0         cmp dx,ax                                 ; 比较注册码
    1010EBC9         ^ 74 C8           je short doc2pdf.1010EB93
    1010EBCB           0FB7C8          movzx ecx,ax
    1010EBCE           0FB7C2          movzx eax,dx
    1010EBD1           2BC1            sub eax,ecx
    1010EBD3           EB 10           jmp short doc2pdf.1010EBE5
    1010EBD5           6A 00           push 0x0
    1010EBD7           FF75 0C         push dword ptr ss:[ebp+0xC]
    1010EBDA           FF75 08         push dword ptr ss:[ebp+0x8]
    1010EBDD           E8 78FEFFFF     call doc2pdf.1010EA5A
    1010EBE2           83C4 0C         add esp,0xC
    1010EBE5           5E              pop esi
    1010EBE6           5D              pop ebp
    1010EBE7           C3              retn

    总结

    1.  将用户输入的注册码中小写字母转换成大写

    2.  将用户名中数字去掉并将字母转换成大写

    3.  将用户名与固定字符拼接

    4.  将拼接后的字符进行MD5计算并且将值转换成字符

    5.  查找替换MD5字符

    6.  取MD5前12字节做注册码

    注册机编写

    #include <stdio.h>
    #include <windows.h>
    #include <string.h>
    #include "md5.h"
    
    
    /**************************************************************************** 
    函数名称: hex_to_str 
    函数功能: 十六进制转字符串 
    输入参数: ptr 字符串 buf 十六进制 len 十六进制字符串的长度。 
    输出参数: 无 
    *****************************************************************************/  
    
    void hex_to_str(char *ptr,unsigned char *buf,int len)  
    {  
        int i=0;
        for(i = 0; i < len; i++)  
        {  
            sprintf(ptr, "%02x",buf[i]);  
            ptr += 2;  
        }  
    } 
    
    
    /*
    MD5:    转换成大写的MD5值
    Val:    要查找到值
    RpVal:  要替换的值    
    */
    void FindVal_Replace(char* MD5, char Val, char RpVal)
    {
    
        int i = 0;
    
        if (NULL == MD5 || 0 == Val || 0 == RpVal)
        {
            return;
        }
    
    
        for (i=0; i<strlen(MD5); i++)
        {
            if ( Val == MD5[i] )
            {
                MD5[i] = RpVal;
            }
        }
    }
    
    int main(int argc, char* argv[])
    {
        char UserName[256] = {0};
        char License[256] = {0};
        char BigStrName[256] = {0};
        char MD5[256] = {0};
    
        //与用户名拼凑
        char *ConstString = "f4hguNAg";
    
        MD5_CTX context;
        long dtLength;
        char szHash[256] = {0};
        TCHAR szBuffer[256] = {0};
        int i = 0;
        int n = 0;
        char j = 0;
        printf("---------doc2pdf2 V5.0注册机-------
    
    ");
    
        printf("请输入用户名: ");
        scanf("%s",UserName);
        if ( strlen(UserName) >= 240 )
        {
            printf("用户名不能超过240位
    ");
            return -1;
        }
    
    
        for (i=0; i<strlen(UserName); i++)
        {
            //--是数字
            if (isdigit(UserName[i]) != 0)
            {
                continue;
            }
            else
            {
                //--是字母
                if ( isalpha(UserName[i])!=0)
                {
                    //--判断是大小写并转换成大写
                    if(UserName[i]>='a'&& UserName[i]<='z') 
                    {
                            BigStrName[i] = UserName[i] - 32;
                            continue;
                    }
                }
    
            }
        }
        
    
        //--用户名与固定字符拼凑并计算MD5值
        strcat(BigStrName,ConstString);
    //    strncpy(BigStrName+strlen(BigStrName), ConstString, strlen(ConstString));
    
        //计算MD5值
        MD5Init(&context);
        MD5Update(&context, BigStrName, strlen(BigStrName));
        MD5Final(szHash, &context);
    
    
        //--将MD5值转换成字符
        hex_to_str(MD5, szHash, strlen(szHash));
    
    
        //--将MD5字符串转换成大写
        for (n=0; n<strlen(MD5); n++)
        {
            //--判断是大小写并转换成大写
            if(MD5[n]>='a'&& MD5[n]<='z') 
            {
                MD5[n] -= 32;
                continue;
            }
        }
    
        //--查找并替换掉MD5字符
        FindVal_Replace(MD5, '1', 'Z');//1替换成Z
    
        FindVal_Replace(MD5, '2', 'W');//2替换成W
    
        FindVal_Replace(MD5, '0', 'K');//0替换成K
    
        FindVal_Replace(MD5, '3', 'T');//3替换成T
    
        FindVal_Replace(MD5, '8', 'P');//8替换成P
    
        FindVal_Replace(MD5, '7', 'S');//7替换成S
    
        //-拷贝注册码
        strncpy(License, MD5, 12);
    
        printf("注册码:%s
    ",License);
        system("pause");
    
        return 0;
    }

    测试注册机

    输入用户名 test 生成注册码

    注册成功

    样本及注册机源码下载

    http://yunpan.cn/cAFbdqsBEYEyr (提取码:2967)

    当把学习当成一种习惯!
  • 相关阅读:
    webpack打包代码生成npm包和js文件学习记录
    王道每周工作记录
    20211116 nuxt项目移动端网页修复记录
    ubuntuwireshark打开出现错误的问题
    Python3基础使用RSA2(SHA256WithRSA)签名加密作为sign值的问题
    博客成长志
    OI学习日志 12月份
    docker 运行.net镜像服务运行正常但是连接不上sqlserver数据库解决方案
    国外一位Orchard的blog
    mvc 相关联的下拉列表 cascading dropdownlist
  • 原文地址:https://www.cnblogs.com/2014asm/p/4104377.html
Copyright © 2020-2023  润新知