菜鸟 学注册机编写之 “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\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, 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\n",License);
138     system("pause");
139 
140 }

2. 测试注册机

输入用户名test

成功注册

完。

 样本及注册机源码下载

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

HDU 4786Fibonacci Tree(最小生成树)

Problem Description   Coach Pang is interested in Fibonacci numbers while Un...

4026
来自专栏ml

HDUOJ--畅通工程

畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java...

34210
来自专栏码匠的流水账

聊聊eureka client的serviceUrl

eureka-client-1.8.8-sources.jar!/com/netflix/discovery/DiscoveryClient.java

2721
来自专栏xingoo, 一个梦想做发明家的程序员

Spark MLlib 之 aggregate和treeAggregate从原理到应用

由于treeAggregate是在aggregate基础上的优化版本,因此先来看看aggregate是什么.

1440
来自专栏lgp20151222

SSH上一个随笔的基础上添加上hibernate支持

熟悉的pom.xml其中lo4g和slf4j这两个包第一眼看上去有点莫名奇妙,我也是这么觉得的,实际作用是在后台输出sql语句,不导入hibernate就会报错...

881
来自专栏一个会写诗的程序员的博客

【Kotlin 反应式编程】第1讲 你好,Reactive Programming

【Kotlin 反应式编程】第1讲 你好,Reactive Programming

882
来自专栏码匠的流水账

聊聊spring cloud gateway的LoadBalancerClientFilter

本文主要研究一下spring cloud gateway的LoadBalancerClientFilter

1531
来自专栏Java 技术分享

Ajax 案例之三级联动

3476
来自专栏Java与Android技术栈

Transformer 在RxJava中的使用

Transformer,顾名思义是转换器的意思。早在 RxJava1.x 版本就有了Observable.Transformer、Single.Transfor...

9062
来自专栏拂晓风起

jQuery 和 json 简单例子(注意callback函数的处理!!) (servlet返回json,jquery更新,java json)

1253

扫码关注云+社区

领取腾讯云代金券