菜鸟 学注册机编写之 “序列号组合”

发布者:我是小三
发布于:2014-11-18 13:14

测试环境
系统: xp sp3

调试器 :od 1.10

一: 定位关键CALL

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

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

3.选择”MessageBoxA” 右键 “显示调用”,来到如下图的地方

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

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

二:算法分析

1.F7跟进关键Call

将用户名与一个固定字符串组后,然后生成两个字符串

 1 004704B0  /$  55            push ebp
 2 004704B1  |.  8BEC          mov ebp,esp
 3 004704B3  |.  6A 00         push 0x0
 4 004704B5  |.  6A 00         push 0x0
 5 004704B7  |.  6A 00         push 0x0
 6 004704B9  |.  6A 00         push 0x0
 7 004704BB  |.  6A 00         push 0x0
 8 004704BD  |.  6A 00         push 0x0
 9 004704BF  |.  6A 00         push 0x0
10 004704C1  |.  6A 00         push 0x0
11 004704C3  |.  53            push ebx
12 004704C4  |.  56            push esi
13 004704C5  |.  57            push edi
14 004704C6  |.  8BD9          mov ebx,ecx
15 004704C8  |.  8955 FC       mov [local.1],edx
16 004704CB  |.  8BF8          mov edi,eax
17 004704CD  |.  8B45 FC       mov eax,[local.1]
18 004704D0  |.  E8 FB47F9FF   call FlashSli.00404CD0
19 004704D5  |.  33C0          xor eax,eax
20 004704D7  |.  55            push ebp
21 004704D8  |.  68 0B064700   push FlashSli.0047060B
22 004704DD  |.  64:FF30       push dword ptr fs:[eax]
23 004704E0  |.  64:8920       mov dword ptr fs:[eax],esp
24 004704E3  |.  8D45 FC       lea eax,[local.1]
25 004704E6  |.  BA 24064700   mov edx,FlashSli.00470624                ;  I1Fa$Mdf8
26 004704EB  |.  E8 0046F9FF   call FlashSli.00404AF0                   ;  用户与固定字符连接
27 004704F0  |.  8B45 FC       mov eax,[local.1]
28 004704F3  |.  E8 F045F9FF   call FlashSli.00404AE8                   ;  ----长度
29 004704F8  |.  8BF0          mov esi,eax
30 004704FA  |.  D1FE          sar esi,1                                ;  计算要分取字符串的长度 算术右移
31 004704FC  |.  79 03         jns short FlashSli.00470501
32 004704FE  |.  83D6 00       adc esi,0x0
33 00470501  |>  8D45 F0       lea eax,[local.4]
34 00470504  |.  50            push eax
35 00470505  |.  8BCE          mov ecx,esi
36 00470507  |.  BA 01000000   mov edx,0x1
37 0047050C  |.  8B45 FC       mov eax,[local.1]
38 0047050F  |.  E8 2C48F9FF   call FlashSli.00404D40                   ;  分取上面计算长度的字符串
39 00470514  |.  8B45 F0       mov eax,[local.4]
40 00470517  |.  50            push eax
41 00470518  |.  8D45 EC       lea eax,[local.5]
42 0047051B  |.  50            push eax
43 0047051C  |.  8B45 FC       mov eax,[local.1]
44 0047051F  |.  E8 C445F9FF   call FlashSli.00404AE8                   ;  长度
45 00470524  |.  8BC8          mov ecx,eax                              ;  总字符串长度
46 00470526  |.  8D56 01       lea edx,dword ptr ds:[esi+0x1]           ;  要取字符串开始地址
47 00470529  |.  8B45 FC       mov eax,[local.1]
48 0047052C  |.  E8 0F48F9FF   call FlashSli.00404D40                   ;  取字符串
49 00470531  |.  8B55 EC       mov edx,[local.5]
50 00470534  |.  8D45 FC       lea eax,[local.1]
51 00470537  |.  59            pop ecx
52 00470538  |.  E8 F745F9FF   call FlashSli.00404B34                   ;  ---交换字符串
53 0047053D  |.  8D45 F8       lea eax,[local.2]
54 00470540  |.  50            push eax
55 00470541  |.  B9 0A000000   mov ecx,0xA                              ;  要取的长度
56 00470546  |.  BA 01000000   mov edx,0x1
57 0047054B  |.  8B45 FC       mov eax,[local.1]
58 0047054E  |.  E8 ED47F9FF   call FlashSli.00404D40                   ;  ---取交换组合后的字符
59 00470553  |.  8D45 F4       lea eax,[local.3]
60 00470556  |.  50            push eax
61 00470557  |.  8B45 FC       mov eax,[local.1]
62 0047055A  |.  E8 8945F9FF   call FlashSli.00404AE8                   ;  交换后字符串长度
63 0047055F  |.  8BC8          mov ecx,eax                              ;  要取的度长
64 00470561  |.  BA 06000000   mov edx,0x6                              ;  从第6个字符开始取
65 00470566  |.  8B45 FC       mov eax,[local.1]
66 00470569  |.  E8 D247F9FF   call FlashSli.00404D40                   ;  --取交换组合后的字符
67 0047056E  |.  837D F4 00    cmp [local.3],0x0
68 00470572  |.  75 10         jnz short FlashSli.00470584
69 00470574  |.  8D45 F4       lea eax,[local.3]
70 00470577  |.  BA 24064700   mov edx,FlashSli.00470624                ;  I1Fa$Mdf8
71 0047057C  |.  8B4D F8       mov ecx,[local.2]
72 0047057F  |.  E8 B045F9FF   call FlashSli.00404B34

2.将上面生成的两个字符串传入函数进行计算

  1 0046FB94  /$  55            push ebp
  2 0046FB95  |.  8BEC          mov ebp,esp
  3 0046FB97  |.  83C4 E0       add esp,-0x20
  4 0046FB9A  |.  53            push ebx
  5 0046FB9B  |.  56            push esi
  6 0046FB9C  |.  57            push edi
  7 0046FB9D  |.  33DB          xor ebx,ebx
  8 0046FB9F  |.  895D E0       mov [local.8],ebx
  9 0046FBA2  |.  895D F0       mov [local.4],ebx
 10 0046FBA5  |.  894D F8       mov [local.2],ecx
 11 0046FBA8  |.  8955 FC       mov [local.1],edx
 12 0046FBAB  |.  8B45 FC       mov eax,[local.1]
 13 0046FBAE  |.  E8 1D51F9FF   call FlashSli.00404CD0
 14 0046FBB3  |.  8B45 F8       mov eax,[local.2]
 15 0046FBB6  |.  E8 1551F9FF   call FlashSli.00404CD0
 16 0046FBBB  |.  33C0          xor eax,eax
 17 0046FBBD  |.  55            push ebp
 18 0046FBBE  |.  68 B0FC4600   push FlashSli.0046FCB0
 19 0046FBC3  |.  64:FF30       push dword ptr fs:[eax]
 20 0046FBC6  |.  64:8920       mov dword ptr fs:[eax],esp
 21 0046FBC9  |.  8B45 F8       mov eax,[local.2]
 22 0046FBCC  |.  E8 174FF9FF   call FlashSli.00404AE8                   ;  长度  后一次取的字符串
 23 0046FBD1  |.  8945 F4       mov [local.3],eax
 24 0046FBD4  |.  837D F4 00    cmp [local.3],0x0
 25 0046FBD8  |.  75 0D         jnz short FlashSli.0046FBE7
 26 0046FBDA  |.  8D45 F8       lea eax,[local.2]
 27 0046FBDD  |.  BA C8FC4600   mov edx,FlashSli.0046FCC8                ;  Think Space
 28 0046FBE2  |.  E8 E14CF9FF   call FlashSli.004048C8
 29 0046FBE7  |>  33F6          xor esi,esi
 30 0046FBE9  |.  BB 00010000   mov ebx,0x100                            ;  初始化0x100
 31 0046FBEE  |.  8D45 F0       lea eax,[local.4]
 32 0046FBF1  |.  50            push eax                                 ; /Arg1
 33 0046FBF2  |.  C745 E4 00010>mov [local.7],0x100                      ; |
 34 0046FBF9  |.  C645 E8 00    mov byte ptr ss:[ebp-0x18],0x0           ; |
 35 0046FBFD  |.  8D55 E4       lea edx,[local.7]                        ; |
 36 0046FC00  |.  33C9          xor ecx,ecx                              ; |
 37 0046FC02  |.  B8 DCFC4600   mov eax,FlashSli.0046FCDC                ; |%1.2x
 38 0046FC07  |.  E8 E0AAF9FF   call FlashSli.0040A6EC                   ; \格式化成字符串
 39 0046FC0C  |.  8B45 FC       mov eax,[local.1]
 40 0046FC0F  |.  E8 D44EF9FF   call FlashSli.00404AE8                   ;  长度 第一次取的字符
 41 0046FC14  |.  8BF8          mov edi,eax
 42 0046FC16  |.  85FF          test edi,edi
 43 0046FC18  |.  7E 60         jle short FlashSli.0046FC7A              ;  循环取余
 44 0046FC1A  |.  C745 EC 01000>mov [local.5],0x1                        ;  索引
 45 0046FC21  |>  8B45 FC       /mov eax,[local.1]                       ;  字符串地址
 46 0046FC24  |.  8B55 EC       |mov edx,[local.5]                       ;  索引
 47 0046FC27  |.  0FB64410 FF   |movzx eax,byte ptr ds:[eax+edw-0x1]     ;  取第一次取的字符串1字节
 48 0046FC2C  |.  03C3          |add eax,ebx                             ;  相加
 49 0046FC2E  |.  B9 FF000000   |mov ecx,0xFF
 50 0046FC33  |.  99            |cdq
 51 0046FC34  |.  F7F9          |idiv ecx                                ;  取余
 52 0046FC36  |.  8BDA          |mov ebx,edx                             ;  取余后的值存放在ebx
 53 0046FC38  |.  3B75 F4       |cmp esi,[local.3]                       ;  比较字符长度
 54 0046FC3B  |.  7D 03         |jge short FlashSli.0046FC40
 55 0046FC3D  |.  46            |inc esi                                 ;  索引加1
 56 0046FC3E  |.  EB 05         |jmp short FlashSli.0046FC45
 57 0046FC40  |>  BE 01000000   |mov esi,0x1                             ;  索引
 58 0046FC45  |>  8B45 F8       |mov eax,[local.2]                       ;  字符串地址
 59 0046FC48  |.  0FB64430 FF   |movzx eax,byte ptr ds:[eax+esg-0x1]     ;  取第二次取的字符串1字节
 60 0046FC4D  |.  33D8          |xor ebx,eax                             ;  与上个字符取余后的值xor
 61 0046FC4F  |.  8D45 E0       |lea eax,[local.8]
 62 0046FC52  |.  50            |push eax                                ; /Arg1
 63 0046FC53  |.  895D E4       |mov [local.7],ebx                       ; |
 64 0046FC56  |.  C645 E8 00    |mov byte ptr ss:[ebp-0x18],0x0          ; |
 65 0046FC5A  |.  8D55 E4       |lea edx,[local.7]                       ; |
 66 0046FC5D  |.  33C9          |xor ecx,ecx                             ; |
 67 0046FC5F  |.  B8 DCFC4600   |mov eax,FlashSli.0046FCDC               ; |%1.2x
 68 0046FC64  |.  E8 83AAF9FF   |call FlashSli.0040A6EC                  ; \格式化成字符串
 69 0046FC69  |.  8B55 E0       |mov edx,[local.8]
 70 0046FC6C  |.  8D45 F0       |lea eax,[local.4]
 71 0046FC6F  |.  E8 7C4EF9FF   |call FlashSli.00404AF0                  ;  存放字符串 eax指向字符串地址
 72 0046FC74  |.  FF45 EC       |inc [local.5]                           ;  索引加1
 73 0046FC77  |.  4F            |dec edi                                 ;  第一次字符长度
 74 0046FC78  |.^ 75 A7         \jnz short FlashSli.0046FC21             ;  判断是否结束
 75 0046FC7A  |>  8B45 08       mov eax,[arg.1]
 76 0046FC7D  |.  8B55 F0       mov edx,[local.4]
 77 0046FC80  |.  E8 FF4BF9FF   call FlashSli.00404884
 78 0046FC85  |.  33C0          xor eax,eax
 79 0046FC87  |.  5A            pop edx
 80 0046FC88  |.  59            pop ecx
 81 0046FC89  |.  59            pop ecx
 82 0046FC8A  |.  64:8910       mov dword ptr fs:[eax],edx
 83 0046FC8D  |.  68 B7FC4600   push FlashSli.0046FCB7
 84 0046FC92  |>  8D45 E0       lea eax,[local.8]
 85 0046FC95  |.  E8 964BF9FF   call FlashSli.00404830
 86 0046FC9A  |.  8D45 F0       lea eax,[local.4]
 87 0046FC9D  |.  E8 8E4BF9FF   call FlashSli.00404830
 88 0046FCA2  |.  8D45 F8       lea eax,[local.2]
 89 0046FCA5  |.  BA 02000000   mov edx,0x2
 90 0046FCAA  |.  E8 A54BF9FF   call FlashSli.00404854
 91 0046FCAF  \.  C3            retn

3.计算完成后得到一串字符串 0x17长度,取该字符串每5位加上字符’-’做为注册码

 1 00470592  |.  8D45 E8       lea eax,[local.6]
 2 00470595  |.  50            push eax
 3 00470596  |.  8B03          mov eax,dword ptr ds:[ebx]
 4 00470598  |.  B9 05000000   mov ecx,0x5                              ;  要取的长度
 5 0047059D  |.  BA 01000000   mov edx,0x1                              ;  从第一个字节
 6 004705A2  |.  E8 9947F9FF   call FlashSli.00404D40                   ;  ---取字符串
 7 004705A7  |.  FF75 E8       push [local.6]
 8 004705AA  |.  68 38064700   push FlashSli.00470638                   ;  -
 9 004705AF  |.  8D45 E4       lea eax,[local.7]
10 004705B2  |.  50            push eax
11 004705B3  |.  8B03          mov eax,dword ptr ds:[ebx]
12 004705B5  |.  B9 05000000   mov ecx,0x5                              ;  要取的长度
13 004705BA  |.  BA 06000000   mov edx,0x6                              ;  从第6个字节
14 004705BF  |.  E8 7C47F9FF   call FlashSli.00404D40                   ;  取字符串
15 004705C4  |.  FF75 E4       push [local.7]
16 004705C7  |.  68 38064700   push FlashSli.00470638                   ;  -
17 004705CC  |.  8D45 E0       lea eax,[local.8]
18 004705CF  |.  50            push eax
19 004705D0  |.  8B03          mov eax,dword ptr ds:[ebx]
20 004705D2  |.  B9 05000000   mov ecx,0x5                              ;  要取的长度
21 004705D7  |.  BA 0B000000   mov edx,0xB                              ;  从0xB开始取
22 004705DC  |.  E8 5F47F9FF   call FlashSli.00404D40                   ;  取字符串
23 004705E1  |.  FF75 E0       push [local.8]
24 004705E4  |.  8BC3          mov eax,ebx
25 004705E6  |.  BA 05000000   mov edx,0x5
26 004705EB  |.  E8 B845F9FF   call FlashSli.00404BA8
27 004705F0  |.  33C0          xor eax,eax
28 004705F2  |.  5A            pop edx
29 004705F3  |.  59            pop ecx
30 004705F4  |.  59            pop ecx
31 004705F5  |.  64:8910       mov dword ptr fs:[eax],edx
32 004705F8  |.  68 12064700   push FlashSli.00470612
33 004705FD  |>  8D45 E0       lea eax,[local.8]
34 00470600  |.  BA 08000000   mov edx,0x8
35 00470605  |.  E8 4A42F9FF   call FlashSli.00404854
36 0047060A  \.  C3            retn

4.比较注册码

1 00470387  |.  E8 C48DF9FF   call FlashSli.00409150                   ;  strcmp 比较注册码,不同返回1
2 
3 0047038C  |.  85C0          test eax,eax
4 
5 0047038E  |.  75 41         jnz short FlashSli.004703D1

分析总结

A.  获得用户名并与固定字符串连接

B.  将连接后字符串长度算术右移1位得到一个长度

C.  取连接后字符串(长度为上面右移后的长度)

D.  甚下的字符串与上面取的字符做前后交换

E.  取交换后字符(0xA长度)

F.  甚下的字符与上面取得的字符传入一个函数时行计算

G.  计算后得到一串字符,取其中值做注册码

5.算法分析清楚了就开始 注册机编写

  1 #include <stdio.h>
  2 #include <windows.h>
  3 #include <string.h>
  4 
  5 //与用户名连接的固定字符串
  6 char *ConstStrig = "I1Fa$Mdf8";
  7 char License[256] = {0};
  8 char UserSun[256] = {0};
  9 
 10 //-算法,将用户名组合后计算得到一串字符
 11 void Algorithm(char* UserAgo, char* UserBack)
 12 {
 13 
 14     int UserBackLen = 0;
 15     int UserAgoLen = 0;
 16 
 17     unsigned int initVal = 0x100;
 18     char strtemp[4] = {0};
 19 
 20 
 21     if (NULL == UserAgo || NULL == UserBack)
 22     {
 23         return;
 24     }
 25 
 26     UserBackLen = strlen(UserBack);
 27     if (0 == UserBackLen)
 28     {
 29         return;
 30     }
 31     UserAgoLen = strlen(UserAgo);
 32     if (0 == UserAgoLen)
 33     {
 34         return;
 35     }
 36 
 37     //--格式化成字符串
 38     sprintf(UserSun, "%02X",initVal);
 39 
 40 
 41     for (int i=0; i<UserAgoLen; i++)
 42     {
 43 
 44         unsigned int N = 0XFF;
 45         unsigned int Val_A = UserAgo[i];
 46         initVal += Val_A;
 47 
 48         //取余
 49         initVal %= N;
 50 
 51         unsigned int Val_B = UserBack[i];
 52 
 53         initVal ^= Val_B;
 54         sprintf(UserSun+3+i*2, "%02X", initVal);
 55 
 56 
 57     }
 58 
 59 }
 60 
 61 int main()
 62 {
 63 
 64     char UserName[256] = {0};
 65     char License[256] = {0};
 66     int len = 0;
 67 
 68     printf("----------------AliveFlashSlideshowMaker 注册机----------\n");
 69     printf("请输入用户名:");
 70     scanf("%s",UserName);
 71     if ( strlen(UserName) > 200)
 72     {
 73         printf("用户名不能超过200位\n");
 74         return -1;
 75     }
 76 
 77     //连接用户名
 78     strcat(UserName,ConstStrig);
 79 
 80     len = strlen(UserName);
 81     if (0 == len)
 82     {
 83         return -1;
 84     }
 85 
 86     //长度算术右移1位
 87     len >>= 1;
 88 
 89     char strtempuser[256] = {0};
 90     char strtempuser1[256] = {0};
 91 
 92     //将组合好的字符分成两个字符
 93     strncpy(strtempuser, UserName, len);
 94     strncpy(strtempuser1, UserName+len, strlen(UserName)-len);
 95 
 96     //-重新组合交换字符
 97     memset(UserName, 0, strlen(UserName));
 98     strncpy(UserName, strtempuser1, strlen(strtempuser1));
 99     strcat(UserName, strtempuser);
100 
101     //取交换后字符前0xA位
102     memset(strtempuser, 0, strlen(strtempuser));
103     memset(strtempuser1, 0 ,strlen(strtempuser1));
104     strncpy(strtempuser, UserName, 0xA);
105     strncpy(strtempuser1, UserName+5, strlen(UserName)-5);
106 
107     Algorithm(strtempuser, strtempuser1);
108 
109     //--生成注册码
110     strncpy(License, UserSun, 5);
111     strncpy(License+strlen(License), "-", 1);
112     strncpy(License+strlen(License), UserSun+5, 5);
113     strncpy(License+strlen(License), "-", 1);
114     strncpy(License+strlen(License), UserSun+10, 5);
115 
116 
117     printf("注册码为:%s\n",License);
118     system("pause");
119     return 0;
120 }

6.测试注册机

输入用户名test

输入生成的注册码,注册成功

完成。

样本及注册机下载

http://yunpan.cn/cA3rINnem5cRn (提取码:5b95)


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