• 【分析 0x03】《加密与解密》第三版 5.2学习笔记


    这是一个注册的例子,首先通过查找提示的字符串进而找到程序对输入的name和key的处理函数

    这个例子是用的对等函数检查注册码 F1(用户名)=F2(序列号)

     1 00401223   .  83F8 00       cmp eax,0x0
     2 00401226   .^ 74 BE         je short serial.004011E6
     3 00401228   .  68 8E214000   push serial.0040218E                     ;  ASCII "GFFGFGFGFG"
     4 0040122D   .  E8 4C010000   call serial.0040137E                     ;  计算F1用户名
     5 00401232   .  50            push eax
     6 00401233   .  68 7E214000   push serial.0040217E                     ;  ASCII "ggggggggg"
     7 00401238   .  E8 9B010000   call serial.004013D8                     ;  计算F2序列号
     8 0040123D      83C4 04       add esp,0x4
     9 00401240   .  58            pop eax
    10 00401241   .  3BC3          cmp eax,ebx                              ;  比较
    11 00401243   .  74 07         je short serial.0040124C                 ;  相等 则注册成功
    12 00401245   .  E8 18010000   call serial.00401362
    13 0040124A   .^ EB 9A         jmp short serial.004011E6

    call serial.0040137E

     1 0040137E  /$  8B7424 04     mov esi,dword ptr ss:[esp+0x4]
     2 00401382  |.  56            push esi
     3 00401383  |>  8A06          /mov al,byte ptr ds:[esi]                ;  从字符串中取一个字符
     4 00401385  |.  84C0          |test al,al                              ;  判断取出的字符是否为null
     5 00401387  |.  74 13         |je short serial.0040139C
     6 00401389  |.  3C 41         |cmp al,0x41                             ;  判断取出的字符是否小于'A'
     7 0040138B  |.  72 1F         |jb short serial.004013AC
     8 0040138D  |.  3C 5A         |cmp al,0x5A                             ;  判断字符是否为大写
     9 0040138F  |.  73 03         |jnb short serial.00401394
    10 00401391  |.  46            |inc esi
    11 00401392  |.^ EB EF         |jmp short serial.00401383
    12 00401394  |>  E8 39000000   |call serial.004013D2
    13 00401399  |.  46            |inc esi
    14 0040139A  |.^ EB E7         jmp short serial.00401383               ;  开始读取下一个字符
    15 0040139C  |>  5E            pop esi                                  ;  esi 再次指向字符串首部
    16 0040139D  |.  E8 20000000   call serial.004013C2                     ;  把整个字符串的单个字符依次相加 结果存放在edi中
    17 004013A2  |.  81F7 78560000 xor edi,0x5678                           ;  edi | 5678h
    18 004013A8  |.  8BC7          mov eax,edi
    19 004013AA  |.  EB 15         jmp short serial.004013C1                ;  返回值存放于eax后返回
    20 004013AC  |>  5E            pop esi
    21 004013AD  |.  6A 30         push 0x30                                ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
    22 004013AF  |.  68 60214000   push serial.00402160                     ; |Title = "Error!  "
    23 004013B4  |.  68 69214000   push serial.00402169                     ; |Text = "Incorrect!,Try Again"
    24 004013B9  |.  FF75 08       push [arg.1]                             ; |hOwner
    25 004013BC  |.  E8 79000000   call <jmp.&USER32.MessageBoxA>           ; MessageBoxA
    26 004013C1  >  C3            retn
    27 004013C2  /$  33FF          xor edi,edi
    28 004013C4  |.  33DB          xor ebx,ebx
    29 004013C6  |>  8A1E          /mov bl,byte ptr ds:[esi]
    30 004013C8  |.  84DB          |test bl,bl
    31 004013CA  |.  74 05         |je short serial.004013D1                ;  判断是否把字符串读结束
    32 004013CC  |.  03FB          |add edi,ebx                             ;  读出的字符加到edi中 edi+=字符(小写)ASCII值
    33 004013CE  |.  46            |inc esi
    34 004013CF  |.^ EB F5         jmp short serial.004013C6
    35 004013D1  >  C3            retn
    36 004013D2  /$  2C 20         sub al,0x20                              ;  小写改为大写
    37 004013D4  |.  8806          mov byte ptr ds:[esi],al
    38 004013D6  .  C3            retn

    返回值就是把字符串转换为小写在把每个字符相加

    call serial.004013D8

     1 004013D8  /$  33C0          xor eax,eax
     2 004013DA  |.  33FF          xor edi,edi
     3 004013DC  |.  33DB          xor ebx,ebx
     4 004013DE  |.  8B7424 04     mov esi,dword ptr ss:[esp+0x4]
     5 004013E2  |>  B0 0A         /mov al,0xA
     6 004013E4  |.  8A1E          |mov bl,byte ptr ds:[esi]
     7 004013E6  |.  84DB          |test bl,bl
     8 004013E8  |.  74 0B         |je short serial.004013F5
     9 004013EA  |.  80EB 30       |sub bl,0x30                             ;  取出的字符c-=30h
    10 004013ED  |.  0FAFF8        |imul edi,eax                            ;  edi*Ah
    11 004013F0  |.  03FB          |add edi,ebx                             ;  edi+=c
    12 004013F2  |.  46            |inc esi
    13 004013F3  |.^ EB ED         jmp short serial.004013E2
    14 004013F5  |>  81F7 34120000 xor edi,0x1234                           ;  edi|1234h
    15 004013FB  |.  8BDF          mov ebx,edi                              ;  结果放在ebx中
    16 004013FD  .  C3            retn                                     ;  最后返回的 ebx=edi=(c-48)+edi*

    设每次读取一个字符c

    返回值就是sum = sum * 10 +c-48

    这样就可以写出注册程序了

     1 // F2(name) = F1(key)
     2 // key = F1(-1)(F2(name)) = F1(F2(name)) 因为xor (xor A) = A
     3 #include <iostream>
     4 using namespace std;
     5 
     6 int keygen(char *name)
     7 {
     8     int key1=0;
     9     int key2=0;
    10     char *pname=name;
    11     while(*pname != NULL)
    12     {
    13         if(*pname>='a'&&*pname<='z')
    14             *pname-=32;
    15         key1+=*pname;
    16         pname++;
    17     }
    18     key1=key1^0x5678;    //这里利用了 异或是可逆的
    19     key2=key1^0x1234;    //xor (xor A) = A
    20     return key2;
    21 }
    22 
    23 int main()
    24 {
    25     char name[20]={0};
    26     cin>>name;
    27     int key = keygen(name);
    28     cout<<key<<endl;
    29 }

     

  • 相关阅读:
    5.2-5.3
    5.1封装
    阅读《构建之法》 5-7章
    做汉堡
    阅读《构建之法》1-5章
    结对 四则运算
    回答
    读后感
    提问*2
    提问1
  • 原文地址:https://www.cnblogs.com/driedfish/p/5436176.html
Copyright © 2020-2023  润新知