飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 4437|回复: 2

[原创] Mister PiX 算法的简单分析

[复制链接]
  • TA的每日心情
    开心
    2018-12-18 12:34
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2008-9-3 16:51:55 | 显示全部楼层 |阅读模式
    【文章标题】: 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);
          
      }
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-9-3 19:26:07 | 显示全部楼层
    good job 。。。/:001
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2008-9-7 14:35:12 | 显示全部楼层
    牛人呀!多发破文/:013 /:013
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表