zoukankan      html  css  js  c++  java
  • 菜鸟 学注册机编写之 “RSA”

    测试环境
     系统: xp sp3

     调试器 :od 1.10

    RSA简单介绍

    选取两个别人不知道的大素数p, q.
    公共模n = p*q
    欧拉值φ(n) = (p-1)(q-1)
    选取公匙(加密匙) e , 条件是1< e <φ(n),且e与φ(n) 互质. 常用为3, 65537等.
    根据扩展欧几里德算法求得:
    私匙 d = e^-1 mod φ(n) . 
    加解密算法:
    加密: 密文c = m^e mod n
    解密: 明文 m = c^d mod n

    一: 定位关键CALL

    1.OD载入程序, F9运行, 点击”Register”随便输入用户名与注册码,如下图

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

    3.点”显示调用” 往上找就能找到关键跳与关键CALL,如下 地方

     1 00402830    81EC 00020000   sub esp,0x200
     2 00402836    56              push esi
     3 00402837    6A 01           push 0x1
     4 00402839    8BF1            mov esi,ecx
     5 0040283B    E8 D0020900     call Apollo_3.00492B10                     ; jmp 到 mfc42.#?UpdateData@CWnd@@QAEHH@Z_6334
     6 00402840    8B86 34010000   mov eax,dword ptr ds:[esi+0x134]           ; 注册码
     7 00402846    8B8E 38010000   mov ecx,dword ptr ds:[esi+0x138]           ; 用户名
     8 0040284C    50              push eax
     9 0040284D    51              push ecx
    10 0040284E    E8 2DE50000     call Apollo_3.00410D80                     ; 关键Call
    11 00402853    83C4 08         add esp,0x8
    12 00402856    85C0            test eax,eax
    13 00402858    75 1B           jnz short Apollo_3.00402875                ; 关键跳
    14 0040285A    6A 40           push 0x40
    15 0040285C    68 B0724C00     push Apollo_3.004C72B0                     ; ASCII "抱歉"
    16 00402861    68 88724C00     push Apollo_3.004C7288                     ; ASCII "无效的用户名或注册码"
    17 00402866    8BCE            mov ecx,esi
    18 00402868    E8 9D020900     call Apollo_3.00492B0A                     ; jmp 到 mfc42.#?MessageBoxA@CWnd@@QAEHPBD0I@Z_4224
    19 0040286D    5E              pop esi
    20 0040286E    81C4 00020000   add esp,0x200
    21 00402874    C3              retn

    4.分析关键Call

      1 00410D80    6A FF           push -0x1
      2 00410D82    68 095A4900     push Apollo_3.00495A09
      3 00410D87    64:A1 00000000  mov eax,dword ptr fs:[0]
      4 00410D8D    50              push eax
      5 00410D8E    64:8925 0000000>mov dword ptr fs:[0],esp
      6 00410D95    81EC 94000000   sub esp,0x94
      7 00410D9B    8B8424 A4000000 mov eax,dword ptr ss:[esp+0xA4]
      8 00410DA2    53              push ebx
      9 00410DA3    56              push esi
     10 00410DA4    50              push eax
     11 00410DA5    8D4C24 10       lea ecx,dword ptr ss:[esp+0x10]
     12 00410DA9    C74424 60 5F144>mov dword ptr ss:[esp+0x60],0xE14B145F     ; 初始化 模n
     13 00410DB1    C74424 64 86C6C>mov dword ptr ss:[esp+0x64],0xEC9C686
     14 00410DB9    C74424 68 1969E>mov dword ptr ss:[esp+0x68],0x6BEF6919
     15 00410DC1    C74424 6C 63CF1>mov dword ptr ss:[esp+0x6C],0xCC14CF63
     16 00410DC9    C74424 70 CDB41>mov dword ptr ss:[esp+0x70],0x2D15B4CD
     17 00410DD1    C74424 74 B1716>mov dword ptr ss:[esp+0x74],0xA26E71B1
     18 00410DD9    C74424 78 CD44C>mov dword ptr ss:[esp+0x78],0xDDCC44CD
     19 00410DE1    C74424 7C 02064>mov dword ptr ss:[esp+0x7C],0x5C4D0602
     20 00410DE9    E8 B61C0800     call Apollo_3.00492AA4                     ; jmp 到 mfc42.#??0CString@@QAE@PBD@Z_537
     21 00410DEE    8B8C24 B0000000 mov ecx,dword ptr ss:[esp+0xB0]
     22 00410DF5    C78424 A4000000>mov dword ptr ss:[esp+0xA4],0x0
     23 00410E00    51              push ecx
     24 00410E01    8D4C24 0C       lea ecx,dword ptr ss:[esp+0xC]
     25 00410E05    E8 9A1C0800     call Apollo_3.00492AA4                     ; jmp 到 mfc42.#??0CString@@QAE@PBD@Z_537
     26 00410E0A    68 647C4C00     push Apollo_3.004C7C64                     ; UNICODE " "
     27 00410E0F    8D4C24 10       lea ecx,dword ptr ss:[esp+0x10]
     28 00410E13    C68424 A8000000>mov byte ptr ss:[esp+0xA8],0x1
     29 00410E1B    E8 D81F0800     call Apollo_3.00492DF8                     ; jmp 到 mfc42.#?TrimLeft@CString@@QAEXPBD@Z_6928
     30 00410E20    68 647C4C00     push Apollo_3.004C7C64                     ; UNICODE " "
     31 00410E25    8D4C24 10       lea ecx,dword ptr ss:[esp+0x10]
     32 00410E29    E8 C41F0800     call Apollo_3.00492DF2                     ; jmp 到 mfc42.#?TrimRight@CString@@QAEXPBD@Z_6930
     33 00410E2E    68 647C4C00     push Apollo_3.004C7C64                     ; UNICODE " "
     34 00410E33    8D4C24 0C       lea ecx,dword ptr ss:[esp+0xC]
     35 00410E37    E8 BC1F0800     call Apollo_3.00492DF8                     ; jmp 到 mfc42.#?TrimLeft@CString@@QAEXPBD@Z_6928
     36 00410E3C    68 647C4C00     push Apollo_3.004C7C64                     ; UNICODE " "
     37 00410E41    8D4C24 0C       lea ecx,dword ptr ss:[esp+0xC]
     38 00410E45    E8 A81F0800     call Apollo_3.00492DF2                     ; jmp 到 mfc42.#?TrimRight@CString@@QAEXPBD@Z_6930
     39 00410E4A    8B5424 0C       mov edx,dword ptr ss:[esp+0xC]
     40 00410E4E    8B35 68AD4900   mov esi,dword ptr ds:[0x49AD68]            ; msvcrt._mbscmp
     41 00410E54    68 285E4D00     push Apollo_3.004D5E28
     42 00410E59    52              push edx
     43 00410E5A    FFD6            call esi                                   ; 判断用户名是否为空 mbscmp
     44 00410E5C    83C4 08         add esp,0x8
     45 00410E5F    85C0            test eax,eax
     46 00410E61    0F84 0F020000   je Apollo_3.00411076
     47 00410E67    8B4424 08       mov eax,dword ptr ss:[esp+0x8]
     48 00410E6B    68 285E4D00     push Apollo_3.004D5E28
     49 00410E70    50              push eax
     50 00410E71    FFD6            call esi                                   ; 判断注册码是否为空
     51 00410E73    83C4 08         add esp,0x8
     52 00410E76    85C0            test eax,eax
     53 00410E78    0F84 F8010000   je Apollo_3.00411076
     54 00410E7E    57              push edi
     55 00410E7F    6A 00           push 0x0
     56 00410E81    8D4C24 44       lea ecx,dword ptr ss:[esp+0x44]
     57 00410E85    E8 261F0000     call Apollo_3.00412DB0
     58 00410E8A    6A 00           push 0x0
     59 00410E8C    8D4C24 4C       lea ecx,dword ptr ss:[esp+0x4C]
     60 00410E90    C68424 AC000000>mov byte ptr ss:[esp+0xAC],0x2
     61 00410E98    E8 131F0000     call Apollo_3.00412DB0
     62 00410E9D    B3 03           mov bl,0x3
     63 00410E9F    68 01000100     push 0x10001                               ; 公钥 e 10001
     64 00410EA4    8D4C24 5C       lea ecx,dword ptr ss:[esp+0x5C]
     65 00410EA8    889C24 AC000000 mov byte ptr ss:[esp+0xAC],bl
     66 00410EAF    E8 FC1E0000     call Apollo_3.00412DB0                     ; cinstr(e,"10001")初始化公钥e
     67 00410EB4    8D4C24 58       lea ecx,dword ptr ss:[esp+0x58]
     68 00410EB8    C68424 A8000000>mov byte ptr ss:[esp+0xA8],0x4
     69 00410EC0    51              push ecx
     70 00410EC1    8D4C24 4C       lea ecx,dword ptr ss:[esp+0x4C]
     71 00410EC5    E8 461F0000     call Apollo_3.00412E10
     72 00410ECA    8D4C24 58       lea ecx,dword ptr ss:[esp+0x58]
     73 00410ECE    889C24 A8000000 mov byte ptr ss:[esp+0xA8],bl
     74 00410ED5    E8 861F0000     call Apollo_3.00412E60
     75 00410EDA    8D5424 60       lea edx,dword ptr ss:[esp+0x60]
     76 00410EDE    6A 08           push 0x8
     77 00410EE0    52              push edx
     78 00410EE1    8D4C24 48       lea ecx,dword ptr ss:[esp+0x48]
     79 00410EE5    E8 961D0000     call Apollo_3.00412C80                     ; 将模N转换成大数
     80 00410EEA    B9 08000000     mov ecx,0x8
     81 00410EEF    33C0            xor eax,eax
     82 00410EF1    8D7C24 18       lea edi,dword ptr ss:[esp+0x18]
     83 00410EF5    8D5424 2C       lea edx,dword ptr ss:[esp+0x2C]
     84 00410EF9    F3:AB           rep stos dword ptr es:[edi]
     85 00410EFB    8D4424 34       lea eax,dword ptr ss:[esp+0x34]
     86 00410EFF    8D4C24 30       lea ecx,dword ptr ss:[esp+0x30]
     87 00410F03    50              push eax
     88 00410F04    51              push ecx
     89 00410F05    8D4424 30       lea eax,dword ptr ss:[esp+0x30]
     90 00410F09    52              push edx
     91 00410F0A    8D4C24 30       lea ecx,dword ptr ss:[esp+0x30]
     92 00410F0E    50              push eax
     93 00410F0F    8D5424 30       lea edx,dword ptr ss:[esp+0x30]
     94 00410F13    51              push ecx
     95 00410F14    8D4424 30       lea eax,dword ptr ss:[esp+0x30]
     96 00410F18    52              push edx
     97 00410F19    8B5424 24       mov edx,dword ptr ss:[esp+0x24]
     98 00410F1D    8D4C24 30       lea ecx,dword ptr ss:[esp+0x30]
     99 00410F21    50              push eax
    100 00410F22    51              push ecx                                   ; 注册码格式成16进制数据
    101 00410F23    68 0C914C00     push Apollo_3.004C910C                     ; ASCII "%08lX-%08lX-%08lX-%08lX-%08lX-%08lX-%08lX-%08lX
    "
    102 00410F28    52              push edx
    103 00410F29    FF15 98AD4900   call dword ptr ds:[0x49AD98]               ; msvcrt.sscanf
    104 00410F2F    8B4424 50       mov eax,dword ptr ss:[esp+0x50]            ; sn5
    105 00410F33    8B4C24 4C       mov ecx,dword ptr ss:[esp+0x4C]            ; sn4
    106 00410F37    8B7C24 48       mov edi,dword ptr ss:[esp+0x48]            ; sn3
    107 00410F3B    8B5424 44       mov edx,dword ptr ss:[esp+0x44]            ; sn2
    108 00410F3F    03C1            add eax,ecx                                ; sn5 = sn5+sn4
    109 00410F41    8B4C24 5C       mov ecx,dword ptr ss:[esp+0x5C]            ; sn8
    110 00410F45    03C7            add eax,edi                                ; sn5 = (sn5+sn4)+sn3
    111 00410F47    8B7C24 58       mov edi,dword ptr ss:[esp+0x58]            ; sn7
    112 00410F4B    03C2            add eax,edx                                ; sn5 = (sn5+sn4+sn3)+sn2
    113 00410F4D    8B5424 40       mov edx,dword ptr ss:[esp+0x40]            ; sn1
    114 00410F51    33C8            xor ecx,eax                                ; sn8 ^= (sn5+sn4+sn3+sn2)
    115 00410F53    8B4424 54       mov eax,dword ptr ss:[esp+0x54]            ; sn6
    116 00410F57    83C4 28         add esp,0x28
    117 00410F5A    03C2            add eax,edx                                ; sn6 = sn6+sn1
    118 00410F5C    894C24 34       mov dword ptr ss:[esp+0x34],ecx            ; 存放sn8 ^= (sn5+sn4+sn3+sn2)
    119 00410F60    33F8            xor edi,eax                                ; sn7 ^= (sn6+sn1)
    120 00410F62    6A 00           push 0x0
    121 00410F64    8D4C24 3C       lea ecx,dword ptr ss:[esp+0x3C]
    122 00410F68    897C24 34       mov dword ptr ss:[esp+0x34],edi            ; 存放sn7 ^= (sn6+sn1)
    123 00410F6C    E8 3F1E0000     call Apollo_3.00412DB0
    124 00410F71    8D4C24 18       lea ecx,dword ptr ss:[esp+0x18]
    125 00410F75    6A 08           push 0x8
    126 00410F77    51              push ecx
    127 00410F78    8D4C24 40       lea ecx,dword ptr ss:[esp+0x40]
    128 00410F7C    C68424 B0000000>mov byte ptr ss:[esp+0xB0],0x5
    129 00410F84    E8 F71C0000     call Apollo_3.00412C80
    130 00410F89    8D5424 38       lea edx,dword ptr ss:[esp+0x38]
    131 00410F8D    8D4424 50       lea eax,dword ptr ss:[esp+0x50]
    132 00410F91    52              push edx
    133 00410F92    50              push eax
    134 00410F93    8D4C24 48       lea ecx,dword ptr ss:[esp+0x48]            ; 指向注册计算出来的数
    135 00410F97    E8 94140000     call Apollo_3.00412430                     ; powmod c= m^e mod n
    136 00410F9C    B9 08000000     mov ecx,0x8
    137 00410FA1    33C0            xor eax,eax
    138 00410FA3    8D7C24 18       lea edi,dword ptr ss:[esp+0x18]
    139 00410FA7    6A 08           push 0x8
    140 00410FA9    F3:AB           rep stos dword ptr es:[edi]                ; 清空
    141 00410FAB    8D4C24 1C       lea ecx,dword ptr ss:[esp+0x1C]
    142 00410FAF    C68424 AC000000>mov byte ptr ss:[esp+0xAC],0x6
    143 00410FB7    51              push ecx
    144 00410FB8    8D4C24 58       lea ecx,dword ptr ss:[esp+0x58]
    145 00410FBC    E8 FF1C0000     call Apollo_3.00412CC0                     ; big_to_bytes
    146 00410FC1    B9 08000000     mov ecx,0x8
    147 00410FC6    33C0            xor eax,eax
    148 00410FC8    8DBC24 80000000 lea edi,dword ptr ss:[esp+0x80]
    149 00410FCF    F3:AB           rep stos dword ptr es:[edi]
    150 00410FD1    5F              pop edi
    151 00410FD2    8A5404 17       mov dl,byte ptr ss:[esp+eax+0x17]          ; 循环交换数据位置 4字节一组 应当是小端转大端操作
    152 00410FD6    8A4C04 16       mov cl,byte ptr ss:[esp+eax+0x16]
    153 00410FDA    885404 7C       mov byte ptr ss:[esp+eax+0x7C],dl
    154 00410FDE    8B5404 14       mov edx,dword ptr ss:[esp+eax+0x14]
    155 00410FE2    884C04 7D       mov byte ptr ss:[esp+eax+0x7D],cl
    156 00410FE6    8A4C04 14       mov cl,byte ptr ss:[esp+eax+0x14]
    157 00410FEA    C1EA 08         shr edx,0x8
    158 00410FED    885404 7E       mov byte ptr ss:[esp+eax+0x7E],dl
    159 00410FF1    884C04 7F       mov byte ptr ss:[esp+eax+0x7F],cl
    160 00410FF5    83C0 04         add eax,0x4
    161 00410FF8    83F8 20         cmp eax,0x20
    162 00410FFB  ^ 7C D5           jl short Apollo_3.00410FD2                 ; 判断是否结束
    163 00410FFD    8D5424 7C       lea edx,dword ptr ss:[esp+0x7C]
    164 00411001    8D4C24 10       lea ecx,dword ptr ss:[esp+0x10]
    165 00411005    52              push edx
    166 00411006    E8 991A0800     call Apollo_3.00492AA4                     ; jmp 到 mfc42.#??0CString@@QAE@PBD@Z_537
    167 0041100B    8B4424 10       mov eax,dword ptr ss:[esp+0x10]
    168 0041100F    8B4C24 0C       mov ecx,dword ptr ss:[esp+0xC]
    169 00411013    50              push eax
    170 00411014    51              push ecx
    171 00411015    FFD6            call esi                                   ; 比较用户名是否相同
    172 00411017    83C4 08         add esp,0x8
    173 0041101A    8D4C24 10       lea ecx,dword ptr ss:[esp+0x10]
    174 0041101E    85C0            test eax,eax
    175 00411020    C68424 A4000000>mov byte ptr ss:[esp+0xA4],0x6
    176 00411028    0F84 86000000   je Apollo_3.004110B4

    算法分析总结

    以上是注册的第一步,检查是否受到用户名和注册码的输入,如果没有输入就返回 false,同时,也已经找到了 RSA 算法中的公钥 e 和模 n,可以进入下一步参与大数运算了.

    我们现在可以分解N 然后得到D

    如下图

    注册码格式是 s0-s1-s2-s3-s4-s5-s6-s7,首先把 s6 和 s7 原先处理一下,处理的方法是:
    s6 = ( s0 + s5 ) ^ s6
    s7 = ( s1 + s2 + s3 + s4 ) ^ s7

    二:注册码机编写

    1. 注册机源码

      1 #include <stdio.h>
      2 #include <windows.h>
      3 #include "MIRACL.H"
      4 
      5 #pragma comment(lib,"ms32.lib")
      6 
      7 #if _DEBUG
      8 #pragma comment(linker,"/NODEFAULTLIB:LIBC")
      9 #endif
     10 
     11 
     12 void hex_to_str(char *ptr,unsigned char *buf,int len)  
     13 {  
     14     int i=0;
     15     for(i = 0; i < len; i++)  
     16     {  
     17         sprintf(ptr, "%02x",buf[i]);  
     18         ptr += 2;  
     19     }  
     20 } 
     21 
     22 
     23 void main()
     24 {
     25 
     26     miracl* mip=mirsys(500,16);
     27     char szName[256]={0};
     28     unsigned char hexstring[256] = {0};
     29     unsigned char UserSun[256] = {0};
     30     char License[256] = {0};
     31     char szSerial[256] = {0};
     32     int i, j;
     33     big n,d,c,m;
     34     long dtLength;
     35     unsigned char temp[8] = {0};
     36     unsigned int  SN[8] = {0};
     37 
     38     printf("------HA-Apollo3GP_362 注册码机-------
    
    ");
     39 
     40     printf("请输入用户名:");
     41     scanf("%s",szName);
     42 
     43     if (strlen(szName) > 240)
     44     {
     45         printf("用户名不长度不能大于240
    ");
     46         return;
     47     }
     48 
     49 
     50     //将用户名转换成10进制值并逆转
     51 
     52     for (i =0; i<strlen(szName); i++)
     53     {
     54         UserSun[i] = toascii(szName[i]);
     55     }
     56 
     57     //交换位置
     58     j =0;
     59     for (; i>4; i-=4)
     60     {
     61 
     62         strncpy(temp, UserSun+j, 4);
     63         strncpy(UserSun+j, UserSun+i-4, 4);
     64         strncpy(UserSun+i-4,temp, 4);
     65         j+=4;
     66     }
     67 
     68 
     69     hex_to_str(hexstring, UserSun, strlen(UserSun));
     70 
     71     dtLength = strlen(hexstring);
     72     mip->IOBASE=16;                                // 16进制模式
     73     c=mirvar(0);                                   // MIRACL的大数类型
     74     n=mirvar(0);
     75     d=mirvar(0);
     76     m=mirvar(0);
     77 
     78     cinstr(c,hexstring);     // 将用户名转换成大数
     79     cinstr(n,"5C4D0602DDCC44CDA26E71B12D15B4CDCC14CF636BEF69190EC9C686E14B145F");  // 初始化模数n     
     80     cinstr(d,"D32AA4860A4A3B5EFA2F138CF648A2CB1C889773DFD90D95AC93B6D76E08FB9");  // 初始化私钥d
     81     powmod(c,d,n,m);          // 计算m = (c ^ d) mod n
     82     cotstr(m,szSerial); 
     83 
     84     //组合注册码
     85     //SN7 = SN7 ^ (sn6+sn1)
     86     //SN8 = SN8 ^ (sn5+sn4+sn3+sn2)
     87 
     88     //-每4字节进行计算
     89     memset(UserSun, 0, strlen(UserSun));
     90     j = 0;
     91 
     92     //逆序组合注册码格式
     93     for (i = strlen(szSerial); i>0; i -= 8)
     94     {
     95         strncpy(UserSun+j, szSerial+i-8, 8);
     96 
     97         if (i !=8)
     98         {
     99             strcat(UserSun,"-");
    100         }
    101         
    102 
    103         j += 9;
    104     }
    105 
    106 
    107     //--格式化成16进制数据 dword值
    108 
    109     j = 0;
    110     for (i=0; i<strlen(UserSun)-8; i+=8)
    111     {
    112         sscanf(UserSun+i+j, "%08lX", SN+j);
    113         j += 1;
    114     }
    115     
    116     //SN7 = SN7 ^ SN1+ SN6;
    117     //SN8 = SN8 ^ (sn5+sn4+sn3+sn2)
    118     SN[7-1] = SN[7-1] ^ (SN[1-1]+SN[6-1]);
    119     SN[8-1] = SN[8-1] ^ (SN[5-1]+SN[4-1]+SN[3-1]+SN[2-1]);
    120 
    121 
    122     //-将16进制转换成字符串
    123 
    124     //-生成最终注册码
    125     j=0;
    126     for (i=0; i<8; i++)
    127     {
    128         sprintf(License+j, "%08X", SN[i]);
    129         if (i != 7)
    130         {
    131             strcat(License, "-");
    132         }
    133         
    134         j+=9;
    135     }
    136 
    137     printf("注册码: %s
    ",License);
    138     system("pause");
    139 
    140 }

    2. 测试注册机

    输入用户名test

    成功注册

    完。

     样本及注册机源码下载

    http://yunpan.cn/cAqLfTSHxYBvX (提取码:3855)

    当把学习当成一种习惯!
  • 相关阅读:
    2016-2017-2 20155325实验二《Java面向对象程序设计》实验报告
    20155325 2016-2017-2 《Java程序设计》第8周学习总结
    20155325《Java程序设计》实验一(Java开发环境的熟悉)实验报告
    20155323 2016-2017-2《Java程序设计》课程总结
    20155323 第五次实验 网络编程与安全
    20155323课堂实践20170531
    20155323课堂实践20170524
    20155323 第四次实验 Android程序设计实验报告
    20155323课堂实践20170517
    20155323课堂实践20170510
  • 原文地址:https://www.cnblogs.com/2014asm/p/4110561.html
Copyright © 2011-2022 走看看