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


    测试环境
    系统: 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+edx-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+esi-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 注册机----------
    ");
     69     printf("请输入用户名:");
     70     scanf("%s",UserName);
     71     if ( strlen(UserName) > 200)
     72     {
     73         printf("用户名不能超过200位
    ");
     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
    ",License);
    118     system("pause");
    119     return 0;
    120 }

    6.测试注册机

    输入用户名test

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

    完成。

    样本及注册机下载

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

    当把学习当成一种习惯!
  • 相关阅读:
    正则表达式
    HashTable与HashMap的区别
    求解连续子数组乘积的最大值
    求解N个值中最大的k个数,N远大于k
    C++权限修饰符
    DBSCAN算法
    【leetcode】1318. Minimum Flips to Make a OR b Equal to c
     【leetcode】1317. Convert Integer to the Sum of Two No-Zero Integers
    【leetcode】1316. Distinct Echo Substrings
    【leetcode】1315. Sum of Nodes with Even-Valued Grandparent
  • 原文地址:https://www.cnblogs.com/2014asm/p/4105494.html
Copyright © 2020-2023  润新知