菜鸟 学注册机编写之 “RSA”

发布者:我是小三
发布于:2014-11-20 14:34

测试环境
 系统: 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\n"
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 注册码机-------\n\n");
 39 
 40     printf("请输入用户名:");
 41     scanf("%s",szName);
 42 
 43     if (strlen(szName) > 240)
 44     {
 45         printf("用户名不长度不能大于240\n");
 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, UserSun4, 4);
 64         strncpy(UserSun4,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, szSerial8, 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\n",License);
138     system("pause");
139 
140 }

2. 测试注册机

输入用户名test

成功注册

完。

 样本及注册机源码下载

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


声明:该文观点仅代表作者本人,转载请注明来自看雪