TA的每日心情  | 开心 2018-12-18 12:34 | 
|---|
 
  签到天数: 4 天 [LV.2]偶尔看看I  
 | 
 
【文章标题】: Mister PiX 算法的简单分析 
【文章作者】: qifeon 
【软件名称】: Mister PiX 2.10 
【下载地址】: 自己搜索下载 
【保护方式】: 注册码 
【使用工具】: od,peid 
【操作平台】: winxp sp2 
【软件介绍】: 可以在 newsgroup 里面寻找指定的图片。 
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教! 
-------------------------------------------------------------------------------- 
【详细过程】 
  一、分析过程 
   
  1、Peid查壳,显示无壳。编程语言为Borland Delphi 4.0 - 5.0。 
   
  2、试运行,输入“qifeon,12345”,有错误提示“”。 
   
  3、od载入,查找字符串,没找到。Delphi程序,找到关键点方法很多,如按钮事件代码,F12暂停法等。这里我们使用下API函数下断的方法。 
   
  既然有错误对话框,可以考虑使用MessageBoxExA或MessageBoxA,具体用哪个,需要测试,try and error。 
   
  ***************************************************************************************************************************** 
   
  ctrl+N,找到名称位于 MrPix, 条目 309 
   地址=0053E644 
   区段=.idata 
   类型=输入    (已知) 
   名称=user32.MessageBoxExA 
   
  ****************************************************************************************************************************** 
   
  右键“在输入函数上下断”,然后F9运行,出现异常,SHIFT+F9几次,出现注册框,输入“qifeon,12345”,点确定 
   
  程序断下在系统领空,看堆栈 
   
  ******************************************************************************************************************************* 
   
  0012D4A4   00F31EC8  ASCII "Warning" 
  0012D4A8   005292EA  /CALL 到 MessageBoxExA 来自 MrPix.005292E5 
  0012D4AC   000D0540  |hOwner = 000D0540 ('Mister PiX',class='TApplication') 
  0012D4B0   00F34C4C  |Text = "Username or Private Key don't match.",CR,"Please check your entry." 
  0012D4B4   00F31EC8  |Title = "Warning" 
  0012D4B8   00000030  |Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL 
  0012D4BC   00120409  \LanguageID = 120409 (LANG_ENGLISH) 
  0012D4C0   0012D5EC  指向下一个 SEH 记录的指针 
  0012D4C4   0052930A  SE处理程序 
   
  ********************************************************************************************************************************** 
   
  “Alt+F9”返回,点错误对话框后程序返回到自己代码内 
   
  *********************************************************************************************************************************** 
  005292E5  |.  E8 9EE1EDFF   call    <jmp.&user32.MessageBoxExA>      ; \MessageBoxExA 
  005292EA  |.  8BD8          mov     ebx, eax                           返回处 
  005292EC  |.  33C0          xor     eax, eax 
  005292EE  |.  5A            pop     edx 
  005292EF  |.  59            pop     ecx 
  005292F0  |.  59            pop     ecx 
  005292F1  |.  64:8910       mov     dword ptr fs:[eax], edx 
   
  ************************************************************************************************************************************** 
   
  向上看,没有跳转可以跳过此对话框。还要继续回溯关键处。可以找到段首下断回溯,这里使用一种快捷些的方法。 
   
  向下翻堆栈,找到 
   
  0012D5CC  |00F34C4C  ASCII "Username or Private Key don't match.",CR,"Please check your entry." 
  0012D5D0  |0012D601 
  0012D5D4  |00F31EC8  ASCII "Warning" 
  0012D5D8  |0004D87C 
  0012D5DC  |00F34C4C  ASCII "Username or Private Key don't match.",CR,"Please check your entry." 
  0012D5E0  |0012D704 
  0012D5E4  |00514B6E  返回到 MrPix.00514B6E 来自 MrPix.00529134 
  0012D5E8  |00000000 
   
  ****************************************************************************************************************************************** 
   
  0左键点击012D5E4  处,右键“反汇编窗口跟随”来到 
   
  ******************************************************************************************************************************************** 
   
  00514A54  /.  55            push    ebp                             段首 
  00514A55  |.  8BEC          mov     ebp, esp 
  00514A57  |.  81C4 F8FEFFFF add     esp, -108 
  00514A5D  |.  53            push    ebx 
  00514A5E  |.  33C9          xor     ecx, ecx 
  00514A60  |.  898D F8FEFFFF mov     dword ptr [ebp-108], ecx 
  00514A66  |.  894D FC       mov     dword ptr [ebp-4], ecx 
  00514A69  |.  8BD8          mov     ebx, eax 
  00514A6B  |.  33C0          xor     eax, eax 
  00514A6D  |.  55            push    ebp 
  00514A6E  |.  68 8F4B5100   push    00514B8F 
  00514A73  |.  64:FF30       push    dword ptr fs:[eax] 
  00514A76  |.  64:8920       mov     dword ptr fs:[eax], esp 
  00514A79  |.  8D55 FC       lea     edx, dword ptr [ebp-4] 
  00514A7C  |.  8B83 EC020000 mov     eax, dword ptr [ebx+2EC] 
  00514A82  |.  E8 D908F2FF   call    00435360 
  00514A87  |.  8B55 FC       mov     edx, dword ptr [ebp-4]           ;  用户名 
  00514A8A  |.  A1 388D5300   mov     eax, dword ptr [538D38] 
  00514A8F  |.  E8 00F2EEFF   call    00403C94 
  00514A94  |.  8D55 FC       lea     edx, dword ptr [ebp-4] 
  00514A97  |.  8B83 F0020000 mov     eax, dword ptr [ebx+2F0] 
  00514A9D  |.  E8 BE08F2FF   call    00435360 
  00514AA2  |.  8B45 FC       mov     eax, dword ptr [ebp-4]           ;  试炼码 
  00514AA5  |.  33D2          xor     edx, edx 
  00514AA7  |.  E8 8C41EFFF   call    00408C38                         ;  试炼码字符串转为整数保存在eax 
  00514AAC  |.  8B15 248F5300 mov     edx, dword ptr [538F24]          ;  MrPix.0053D728 
  00514AB2  |.  8902          mov     dword ptr [edx], eax             ;  eax值传到edx内指向的地址内 
  00514AB4  |.  8D85 FCFEFFFF lea     eax, dword ptr [ebp-104] 
  00514ABA  |.  8B15 388D5300 mov     edx, dword ptr [538D38]          ;  MrPix.0053D724 
  00514AC0  |.  8B12          mov     edx, dword ptr [edx]             ;  用户名 
  00514AC2  |.  B9 FF000000   mov     ecx, 0FF                         ;  0FFh即十进制256 
  00514AC7  |.  E8 CCF3EEFF   call    00403E98                         ;  取用户名长度,如果超过256位,按256位计算 
  00514ACC  |.  8D85 FCFEFFFF lea     eax, dword ptr [ebp-104] 
  00514AD2  |.  8B15 248F5300 mov     edx, dword ptr [538F24]          ;  MrPix.0053D728 
  00514AD8  |.  66:8B12       mov     dx, word ptr [edx]               ;  试炼码转换的整数值放入dx 
  00514ADB  |.  E8 4061FFFF   call    0050AC20                         ;  关键CALL 
  00514AE0  |.  84C0          test    al, al                           ;  标志位: al=1则注册成功, al=0则失败 
  00514AE2  |.  74 46         je      short 00514B2A                   ;  关键跳转 
  00514AE4  |.  6A 00         push    0 
  00514AE6  |.  8D85 FCFEFFFF lea     eax, dword ptr [ebp-104] 
  00514AEC  |.  50            push    eax 
  00514AED  |.  A1 CC8D5300   mov     eax, dword ptr [538DCC] 
  00514AF2  |.  8B00          mov     eax, dword ptr [eax] 
  00514AF4  |.  B9 9C4B5100   mov     ecx, 00514B9C                    ;  :mister pix wurde erfolgreich freigeschaltet.\nvielen dank! 
  00514AF9  |.  BA D84B5100   mov     edx, 00514BD8                    ;  ASCII 08,"UnlockOK" 
  00514AFE  |.  E8 B9720100   call    0052BDBC 
  00514B03  |.  8D95 FCFEFFFF lea     edx, dword ptr [ebp-104] 
  00514B09  |.  8D85 F8FEFFFF lea     eax, dword ptr [ebp-108] 
  00514B0F  |.  E8 4CF3EEFF   call    00403E60 
  00514B14  |.  8B85 F8FEFFFF mov     eax, dword ptr [ebp-108] 
  00514B1A  |.  66:8B0D E44B5>mov     cx, word ptr [514BE4] 
  00514B21  |.  B2 02         mov     dl, 2 
  00514B23  |.  E8 0C460100   call    00529134 
  00514B28  |.  EB 44         jmp     short 00514B6E 
  00514B2A  |>  6A 00         push    0 
  00514B2C  |.  8D85 FCFEFFFF lea     eax, dword ptr [ebp-104] 
  00514B32  |.  50            push    eax 
  00514B33  |.  A1 CC8D5300   mov     eax, dword ptr [538DCC] 
  00514B38  |.  8B00          mov     eax, dword ptr [eax] 
  00514B3A  |.  B9 E84B5100   mov     ecx, 00514BE8                    ;  ASCII "PBenutzername oder Private Key stimmen nicht.\nBitte 黚erpr黤en Sie Ihre Eingabe." 
  00514B3F  |.  BA 3C4C5100   mov     edx, 00514C3C                    ;  \nunlockfail 
  00514B44  |.  E8 73720100   call    0052BDBC 
  00514B49  |.  8D95 FCFEFFFF lea     edx, dword ptr [ebp-104] 
  00514B4F  |.  8D85 F8FEFFFF lea     eax, dword ptr [ebp-108] 
  00514B55  |.  E8 06F3EEFF   call    00403E60 
  00514B5A  |.  8B85 F8FEFFFF mov     eax, dword ptr [ebp-108] 
  00514B60  |.  66:8B0D E44B5>mov     cx, word ptr [514BE4] 
  00514B67  |.  33D2          xor     edx, edx 
  00514B69  |.  E8 C6450100   call    00529134 
  00514B6E  |>  33C0          xor     eax, eax                         ;  返回处 
  00514B70  |.  5A            pop     edx 
  00514B71  |.  59            pop     ecx 
  00514B72  |.  59            pop     ecx 
  00514B73  |.  64:8910       mov     dword ptr fs:[eax], edx 
  00514B76  |.  68 964B5100   push    00514B96 
  00514B7B  |>  8D85 F8FEFFFF lea     eax, dword ptr [ebp-108] 
  00514B81  |.  E8 BAF0EEFF   call    00403C40 
  00514B86  |.  8D45 FC       lea     eax, dword ptr [ebp-4] 
  00514B89  |.  E8 B2F0EEFF   call    00403C40 
  00514B8E  \.  C3            retn 
   
  ************************************************************************************************************************************************************** 
  显然,这里就是关键了。回溯的方法常常在调试里用到,段首下断就可以反复调试了。 
   
  段首下断后运行中断后,单步 
   
  00514ADB  处进入   call    0050AC20   
   
  ****************************************************************************************************************************************************************  
   
  0050AC20  /$  53            push    ebx 
  0050AC21  |.  56            push    esi 
  0050AC22  |.  57            push    edi 
  0050AC23  |.  83C4 E8       add     esp, -18 
  0050AC26  |.  8BF0          mov     esi, eax                         ;  用户名地址和长度传入esi 
  0050AC28  |.  8D3C24        lea     edi, dword ptr [esp] 
  0050AC2B  |.  33C9          xor     ecx, ecx 
  0050AC2D  |.  8A0E          mov     cl, byte ptr [esi]               ;  用户名长度传入cl 
  0050AC2F  |.  80F9 14       cmp     cl, 14                           ;  比较用户名长度是否小于20位? 
  0050AC32  |.  72 02         jb      short 0050AC36                   ;  小于或等于按实际长度计算 
  0050AC34  |.  B1 14         mov     cl, 14                           ;  大于20位则只取前20位 
  0050AC36  |>  880F          mov     byte ptr [edi], cl               ;  用户名长度传送 
  0050AC38  |.  46            inc     esi                              ;  esi增1 
  0050AC39  |.  47            inc     edi                              ;  edi增1 
  0050AC3A  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr>;  用户名传送到edi指向地址内 
  0050AC3C  |.  8BDA          mov     ebx, edx 
  0050AC3E  |.  E8 D1FFFFFF   call    0050AC14                         ;  生成注册框内显示的pubkey,我们直接利用,算法此处不探讨。 
  0050AC43  |.  8BD0          mov     edx, eax                         ;  edx=eax=pubkey 
  0050AC45  |.  8BC4          mov     eax, esp 
  0050AC47  |.  E8 10000000   call    0050AC5C                         ;  算法CALL 
  0050AC4C  |.  66:3BD8       cmp     bx, ax                           ;  真码与假码相比较 
  0050AC4F  |.  0F94C0        sete    al                               ;  相等则置al=1,否则为0 
  0050AC52  |.  83C4 18       add     esp, 18 
  0050AC55  |.  5F            pop     edi 
  0050AC56  |.  5E            pop     esi 
  0050AC57  |.  5B            pop     ebx 
  0050AC58  \.  C3            retn 
   
  ********************************************************************************************************************************* 
   
  单步,0050AC47  处  进入   call    0050AC5C  
   
  *********************************************************************************************************************************** 
   
  0050AC5C  /$  53            push    ebx 
  0050AC5D  |.  56            push    esi 
  0050AC5E  |.  57            push    edi 
  0050AC5F  |.  83C4 E8       add     esp, -18 
  0050AC62  |.  8BF0          mov     esi, eax                         ;  用户名 
  0050AC64  |.  8D3C24        lea     edi, dword ptr [esp] 
  0050AC67  |.  33C9          xor     ecx, ecx 
  0050AC69  |.  8A0E          mov     cl, byte ptr [esi] 
  0050AC6B  |.  80F9 14       cmp     cl, 14 
  0050AC6E  |.  72 02         jb      short 0050AC72 
  0050AC70  |.  B1 14         mov     cl, 14 
  0050AC72  |>  880F          mov     byte ptr [edi], cl 
  0050AC74  |.  46            inc     esi 
  0050AC75  |.  47            inc     edi 
  0050AC76  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr> 
  0050AC78  |.  8BDA          mov     ebx, edx                         ;  ebx=edx=pubkey 
  0050AC7A  |.  8BC4          mov     eax, esp                         ;  用户名及长度地址传入eax 
  0050AC7C  |.  E8 13FFFFFF   call    0050AB94                         ;  算法CALL 
  0050AC81  |.  66:81F3 82DE  xor     bx, 0DE82                        ;  bx= bx xor 0DE82h 
  0050AC86  |.  66:33C3       xor     ax, bx                           ;  ax=ax xor bx 
  0050AC89  |.  83C4 18       add     esp, 18 
  0050AC8C  |.  5F            pop     edi 
  0050AC8D  |.  5E            pop     esi 
  0050AC8E  |.  5B            pop     ebx 
  0050AC8F  \.  C3            retn 
   
  ********************************************************************************************************************** 
   
  0050AC7C处进入call    0050AB94  
   
  ************************************************************************************************************************ 
   
  0050AB94  /$  53            push    ebx 
  0050AB95  |.  56            push    esi 
  0050AB96  |.  57            push    edi 
  0050AB97  |.  83C4 D0       add     esp, -30 
  0050AB9A  |.  8BF0          mov     esi, eax 
  0050AB9C  |.  8D3C24        lea     edi, dword ptr [esp] 
  0050AB9F  |.  33C9          xor     ecx, ecx 
  0050ABA1  |.  8A0E          mov     cl, byte ptr [esi] 
  0050ABA3  |.  80F9 14       cmp     cl, 14 
  0050ABA6  |.  72 02         jb      short 0050ABAA 
  0050ABA8  |.  B1 14         mov     cl, 14 
  0050ABAA  |>  880F          mov     byte ptr [edi], cl 
  0050ABAC  |.  46            inc     esi 
  0050ABAD  |.  47            inc     edi 
  0050ABAE  |.  F3:A4         rep     movs byte ptr es:[edi], byte ptr> 
  0050ABB0  |.  8D5424 18     lea     edx, dword ptr [esp+18] 
  0050ABB4  |.  8BC4          mov     eax, esp 
  0050ABB6  |.  E8 91FEFFFF   call    0050AA4C                         ;  用户名长度小于4,则后面用'0'补充为4位 
  0050ABBB  |.  8D5424 18     lea     edx, dword ptr [esp+18] 
  0050ABBF  |.  8BC4          mov     eax, esp 
  0050ABC1  |.  B1 14         mov     cl, 14 
  0050ABC3  |.  E8 847FEFFF   call    00402B4C 
  0050ABC8  |.  66:BE 0100    mov     si, 1                            ;  si=1 
  0050ABCC  |.  33DB          xor     ebx, ebx 
  0050ABCE  |.  8A1C24        mov     bl, byte ptr [esp]               ;  bl为用户名长度 
  0050ABD1  |.  85DB          test    ebx, ebx                         ;  用户名是否为空? 
  0050ABD3  |.  76 25         jbe     short 0050ABFA 
  0050ABD5  |.  BF 01000000   mov     edi, 1                           ;  edi=1 
  0050ABDA  |.  8D4C24 01     lea     ecx, dword ptr [esp+1]           ;  用户名地址传入ecx 
  0050ABDE  |>  0FB7C6        /movzx   eax, si                         ;  eax=si,初始值为1 
  0050ABE1  |.  40            |inc     eax                             ;  eax增1 
  0050ABE2  |.  33D2          |xor     edx, edx                        ;  edx清零 
  0050ABE4  |.  8A11          |mov     dl, byte ptr [ecx]              ;  用户名逐位送入dl 
  0050ABE6  |.  F7EA          |imul    edx                             ;  eax=eax * edx 
  0050ABE8  |.  F7EF          |imul    edi                             ;  eax=eax * edi 
  0050ABEA  |.  BE FFFF0000   |mov     esi, 0FFFF                      ;  esi=0FFFFh 
  0050ABEF  |.  33D2          |xor     edx, edx                        ;  edx清零 
  0050ABF1  |.  F7F6          |div     esi                             ;  eax除以esi,商保存在eax,余数保存在edx 
  0050ABF3  |.  8BF2          |mov     esi, edx                        ;  edx值传入esi 
  0050ABF5  |.  47            |inc     edi                             ;  edi增1 
  0050ABF6  |.  41            |inc     ecx                             ;  ecx增1 
  0050ABF7  |.  4B            |dec     ebx                             ;  ebx减1 
  0050ABF8  |.^ 75 E4         \jnz     short 0050ABDE                  ;  ebx值不为0则继续循环 
  0050ABFA  |>  8BC6          mov     eax, esi                         ;  最后计算值传送入eax 
  0050ABFC  |.  83C4 30       add     esp, 30 
  0050ABFF  |.  5F            pop     edi 
  0050AC00  |.  5E            pop     esi 
  0050AC01  |.  5B            pop     ebx 
  0050AC02  \.  C3            retn 
   
  ***************************************************************************************************************************** 
   
  二、算法总结 
   
       注册码private key 由 public key 及 用户名name经计算而生成,根据用户名name长度,又分为3种情况; 
   
  1、用户名长度小于4,则后面用'0'补充为4位,参与计算; 
   
   这个限制不明显,跟了几次才看到。容易漏掉。测试了一个国外的注册机。这点就被忽略了,算出来就是错误的了。 
   
  2、用户名长度大于20则只取前20位参与计算,后面不参与验证。(用户名长度大于256,按256操作); 
   
  3、用户名长度在4-20,则正常计算。 
   
   
  ************************************************************************************************************************************** 
   
  三、C语言注册机代码 
   
   偷了点懒,从程序提取部分汇编代码嵌在里面。 
   
  #include "stdio.h" 
  #include "string.h" 
  void main() 
  { 
          static char name[30]={'0','0','0','0'}; 
          int pubkey,reg,len; 
          printf("please enter your name:");  
          scanf("%s",name); 
          printf("please enter your public key:"); 
          scanf("%d",&pubkey); 
          len=strlen(name); 
          if (len>=20) 
          len=20; 
          else if(len<4) 
          {*(name+4)='\0'; 
         *(name+len)='0';           
           len=4;} 
           
                  _asm 
          { 
                   
                  mov ebx,len 
                  mov edi,1 
                  mov si,1 
                  mov ecx,0                         
                  n1: 
                  movzx   eax, si 
                  inc     eax 
                  xor     edx, edx 
                  mov     dl, byte ptr [name+ecx] 
                  imul    edx 
                  imul    edi 
                  mov     esi, 0xFFFF 
                  xor     edx, edx                       
                  div     esi 
                  mov     esi, edx 
                  nc     edi 
                  inc     ecx 
                  dec     ebx 
                 jnz n1 
                 xor esi,0xDE82 
                 xor esi,pubkey 
                 mov reg,esi 
                   
                   
          } 
           
   
          printf("Private key is:%d",reg); 
       
  } |   
 
 
 
 |