首页
社区
课程
招聘
[原创]Bxm的第3个CrackMe分析
2006-10-13 18:20 6155

[原创]Bxm的第3个CrackMe分析

2006-10-13 18:20
6155
【文章标题】: 【原创】Bxm的第3个CrackMe分析
【文章作者】: domin
【软件名称】: Bxm的第3个CrackMe
【下载地址】: http://bbs.pediy.com/attachment.php?s=&attachmentid=3014
【使用工具】: OD
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
----------------------------------------------------------------------
----------
第一次发分析贴,请多指教,另请版主给个上传附件权限吧
【详细过程】
  一、反调试
      这个程序一用OD调试就会退出,具体怎么弄的我还没搞清楚,我真的是新手:),反正他是用ExitProcess退出,那我们
  就跟一下。看到下面的代码:
  004023C9   .  3BF4          cmp     esi, esp
  004023CB   .  E8 BAFBFFFF   call    <jmp.&MSVCRTD._chkesp>
  004023D0   .  837D C8 00    cmp     dword ptr [ebp-38], 0
  004023D4      EB 42         jmp     short 00402407                   ;  改这里
  004023D6   .  837D CC 00    cmp     dword ptr [ebp-34], 0
  004023DA   .  75 2B         jnz     short 00402407
  004023DC   .  837D D8 00    cmp     dword ptr [ebp-28], 0
  004023E0   .  75 25         jnz     short 00402407
  004023E2   .  837D DC 00    cmp     dword ptr [ebp-24], 0
  004023E6   .  75 1F         jnz     short 00402407
  004023E8   .  837D E0 00    cmp     dword ptr [ebp-20], 0
  004023EC   .  75 19         jnz     short 00402407
  004023EE   .  837D D0 00    cmp     dword ptr [ebp-30], 0
  004023F2   .  75 13         jnz     short 00402407
  004023F4   .  837D D4 00    cmp     dword ptr [ebp-2C], 0
  004023F8   .  75 0D         jnz     short 00402407
  004023FA   .  8B55 E4       mov     edx, [ebp-1C]
  004023FD   .  81E2 80000000 and     edx, 80
  00402403   .  85D2          test    edx, edx
  00402405   .  74 11         je      short 00402418
  00402407   >  8BF4          mov     esi, esp
  00402409   .  6A 00         push    0                                ; /ExitCode = 0
  0040240B   .  FF15 9C734100 call    [<&KERNEL32.ExitProcess>]        ; \ExitProcess
  00402411   .  3BF4          cmp     esi, esp
  
  从004023D6开始有一系列的判断,如果有一点不对就转00402407,那些判断具体是些什么我们先不管它吧,我们注意到
  跳到00402407的严重后果就是进程终止,那我们先改一下将004023D4的代码改成jmp     short 00402418,然后复制到
  可执行文件保存文件。再ctrl-f2重新开始,我们就可以正常的跟踪它了。
  
  二、算法分析
  
   ctrl-n看了下,函数很多,根据经验(其实也没多少经验:))在strcpy上设了断点,F9,程序运行,在对话框中输入
  用户名:abcdefg,序列号:12345678确定,程序断下
  00401A0D  |.  E8 EA050000   call    <jmp.&MSVCRTD.strcpy>            ; \strcpy
  00401A12  |.  83C4 08       add     esp, 8
  00401A15  |.  8B4D FC       mov     ecx, [ebp-4]
  00401A18  |.  83C1 60       add     ecx, 60
  一看eax中就是放用户名的缓冲区指针,看来这个地方差不多,再看后面
  00401A0D  |.  E8 EA050000   call    <jmp.&MSVCRTD.strcpy>            ; \strcpy
  00401A12  |.  83C4 08       add     esp, 8
  00401A15  |.  8B4D FC       mov     ecx, [ebp-4]
  00401A18  |.  83C1 60       add     ecx, 60
  00401A1B  |.  E8 58050000   call    <jmp.&MFC42D.#2640>
  00401A20  |.  83F8 05       cmp     eax, 5                           ;  判断长度是否小于5
  00401A23  |.  7D 18         jge     short 00401A3D
  00401A25  |.  6A 00         push    0
  00401A27  |.  6A 00         push    0
  00401A29  |.  8D95 7CFFFFFF lea     edx, [ebp-84]
  00401A2F  |.  52            push    edx
  00401A30  |.  8B4D FC       mov     ecx, [ebp-4]
  00401A33  |.  E8 3A050000   call    <jmp.&MFC42D.#3517>              ;  弹对话框告诉你用户名太短
  00401A38  |.  E9 F3010000   jmp     00401C30
  00401A3D  |>  8B4D FC       mov     ecx, [ebp-4]                     ;  长度符合条件的话就跳到这里了
  00401A40  |.  83C1 60       add     ecx, 60
  00401A43  |.  E8 30050000   call    <jmp.&MFC42D.#2640>              ;  取长度
  00401A48  |.  8945 A8       mov     [ebp-58], eax
  00401A4B  |.  C745 AC 00000>mov     dword ptr [ebp-54], 0
  00401A52  |.  EB 09         jmp     short 00401A5D
  00401A54  |>  8B45 AC       /mov     eax, [ebp-54]                   ;  for(V_54=0;V_54<V_58;V_54++)
  00401A57  |.  83C0 01       |add     eax, 1
  00401A5A  |.  8945 AC       |mov     [ebp-54], eax
  00401A5D  |>  8B4D AC        mov     ecx, [ebp-54]
  00401A60  |.  3B4D A8       |cmp     ecx, [ebp-58]
  00401A63  |.  7D 13         |jge     short 00401A78
  00401A65  |.  8B55 AC       |mov     edx, [ebp-54]
  00401A68  |.  0FBE4415 E4   |movsx   eax, byte ptr [ebp+edx-1C]      ;  取字符
  00401A6D  |.  8B4D 9C       |mov     ecx, [ebp-64]                   ;  变量V_64初值为1
  00401A70  |.  0FAFC8        |imul    ecx, eax
  00401A73  |.  894D 9C       |mov     [ebp-64], ecx                   ;  每个字符累乘,放入变量V_64中
  00401A76  |.^ EB DC         \jmp     short 00401A54
  00401A78  |>  C745 AC 00000>mov     dword ptr [ebp-54], 0
  00401A7F  |>  8B45 9C       /mov     eax, [ebp-64]                   ;  把上步结果变成10进制数的字符,不过顺序是倒的
  00401A82  |.  99            |cdq                                     ;  用AX和DX的符号位填充EAX和EDX的符号位
  00401A83  |.  B9 0A000000   |mov     ecx, 0A
  00401A88  |.  F7F9          |idiv    ecx                             ;  除10取余
  00401A8A  |.  83C2 30       |add     edx, 30                         ;  变成相应字符
  00401A8D  |.  8B45 AC       |mov     eax, [ebp-54]
  00401A90  |.  885405 B4     |mov     [ebp+eax-4C], dl
  00401A94  |.  8B45 9C       |mov     eax, [ebp-64]
  00401A97  |.  99            |cdq
  00401A98  |.  B9 0A000000   |mov     ecx, 0A
  00401A9D  |.  F7F9          |idiv    ecx
  00401A9F  |.  8945 9C       |mov     [ebp-64], eax                   ;  除10取整
  00401AA2  |.  8B55 AC       |mov     edx, [ebp-54]
  00401AA5  |.  83C2 01       |add     edx, 1
  00401AA8  |.  8955 AC       |mov     [ebp-54], edx
  00401AAB  |.  837D 9C 00    |cmp     dword ptr [ebp-64], 0
  00401AAF  |.^ 75 CE         \jnz     short 00401A7F
  00401AB1  |.  8B45 AC       mov     eax, [ebp-54]                    ;  "0044639502"放入V_4c中
  00401AB4  |.  C64405 B4 00  mov     byte ptr [ebp+eax-4C], 0         ;  加个结束符
  00401AB9  |.  8D4D B4       lea     ecx, [ebp-4C]
  00401ABC  |.  51            push    ecx                              ; /s
  00401ABD  |.  E8 34050000   call    <jmp.&MSVCRTD.strlen>            ; \strlen
  00401AC2  |.  83C4 04       add     esp, 4
  00401AC5  |.  8945 A4       mov     [ebp-5C], eax
  00401AC8  |.  C745 AC 00000>mov     dword ptr [ebp-54], 0
  00401ACF  |.  EB 09         jmp     short 00401ADA
  00401AD1  |>  8B55 AC       /mov     edx, [ebp-54]                   ;  将用户名的字符加上其偏移的2倍abcdefg变成adgjmps
  00401AD4  |.  83C2 01       |add     edx, 1
  00401AD7  |.  8955 AC       |mov     [ebp-54], edx
  00401ADA  |>  8B45 AC        mov     eax, [ebp-54]
  00401ADD  |.  3B45 A8       |cmp     eax, [ebp-58]                   ;  58是用户名长度
  00401AE0  |.  7D 31         |jge     short 00401B13
  00401AE2  |.  8B4D AC       |mov     ecx, [ebp-54]
  00401AE5  |.  0FBE540D E4   |movsx   edx, byte ptr [ebp+ecx-1C]      ;  1C是存用户名的地方
  00401AEA  |.  8B45 AC       |mov     eax, [ebp-54]
  00401AED  |.  8D0C42        |lea     ecx, [edx+eax*2]
  00401AF0  |.  8B55 AC       |mov     edx, [ebp-54]
  00401AF3  |.  884C15 E4     |mov     [ebp+edx-1C], cl
  00401AF7  |.  8B45 AC       |mov     eax, [ebp-54]
  00401AFA  |.  0FBE4C05 E4   |movsx   ecx, byte ptr [ebp+eax-1C]
  00401AFF  |.  83F9 7A       |cmp     ecx, 7A
  00401B02  |.  7E 0D         |jle     short 00401B11
  00401B04  |.  8B55 AC       |mov     edx, [ebp-54]
  00401B07  |.  83C2 61       |add     edx, 61
  00401B0A  |.  8B45 AC       |mov     eax, [ebp-54]
  00401B0D  |.  885405 E4     |mov     [ebp+eax-1C], dl                ;  结果仍然放在V_1C中
  00401B11  |>^ EB BE         \jmp     short 00401AD1
  00401B13  |>  8B4D A8       mov     ecx, [ebp-58]
  00401B16  |.  3B4D A4       cmp     ecx, [ebp-5C]
  00401B19  |.  7D 12         jge     short 00401B2D
  00401B1B  |.  8B55 A8       mov     edx, [ebp-58]
  00401B1E  |.  8955 A0       mov     [ebp-60], edx
  00401B21  |.  8B45 A0       mov     eax, [ebp-60]
  00401B24  |.  8D4C05 E4     lea     ecx, [ebp+eax-1C]
  00401B28  |.  894D B0       mov     [ebp-50], ecx
  00401B2B  |.  EB 10         jmp     short 00401B3D
  00401B2D  |>  8B55 A4       mov     edx, [ebp-5C]
  00401B30  |.  8955 A0       mov     [ebp-60], edx
  00401B33  |.  8B45 A0       mov     eax, [ebp-60]
  00401B36  |.  8D4C05 B4     lea     ecx, [ebp+eax-4C]
  00401B3A  |.  894D B0       mov     [ebp-50], ecx
  00401B3D  |>  C745 AC 00000>mov     dword ptr [ebp-54], 0
  00401B44  |.  EB 09         jmp     short 00401B4F
  00401B46  |>  8B55 AC       /mov     edx, [ebp-54]                   ;  这个循环将变化过的用户名和前面算出来的结果叠在一起0a0d4g4j6m3p9s
  00401B49  |.  83C2 01       |add     edx, 1
  00401B4C  |.  8955 AC       |mov     [ebp-54], edx
  00401B4F  |>  8B45 AC        mov     eax, [ebp-54]
  00401B52  |.  3B45 A0       |cmp     eax, [ebp-60]
  00401B55  |.  7D 1E         |jge     short 00401B75                  ;  看哪个结果长
  00401B57  |.  8B4D AC       |mov     ecx, [ebp-54]                   ;  用户名比较长
  00401B5A  |.  8B55 AC       |mov     edx, [ebp-54]
  00401B5D  |.  8A4415 B4     |mov     al, [ebp+edx-4C]
  00401B61  |.  88444D C4     |mov     [ebp+ecx*2-3C], al
  00401B65  |.  8B4D AC       |mov     ecx, [ebp-54]
  00401B68  |.  8B55 AC       |mov     edx, [ebp-54]
  00401B6B  |.  8A4415 E4     |mov     al, [ebp+edx-1C]
  00401B6F  |.  88444D C5     |mov     [ebp+ecx*2-3B], al
  00401B73  |.^ EB D1         \jmp     short 00401B46
  00401B75  |>  8B4D AC       mov     ecx, [ebp-54]                    ;  上步算出来的整数字符串比较长
  00401B78  |.  C6444D C4 00  mov     byte ptr [ebp+ecx*2-3C], 0
  00401B7D  |.  8B55 B0       mov     edx, [ebp-50]
  00401B80  |.  52            push    edx                              ; /src
  00401B81  |.  8D45 C4       lea     eax, [ebp-3C]                    ; |
  00401B84  |.  50            push    eax                              ; |dest
  00401B85  |.  E8 66040000   call    <jmp.&MSVCRTD.strcat>            ; \strcat
  00401B8A  |.  83C4 08       add     esp, 8
  00401B8D  |.  8D4D C4       lea     ecx, [ebp-3C]
  00401B90  |.  51            push    ecx                              ; /s
  00401B91  |.  E8 60040000   call    <jmp.&MSVCRTD.strlen>            ; \strlen
  00401B96  |.  83C4 04       add     esp, 4
  00401B99  |.  8BF0          mov     esi, eax                         ;  算出来的序列号的长度
  00401B9B  |.  8B4D FC       mov     ecx, [ebp-4]
  00401B9E  |.  83C1 64       add     ecx, 64
  00401BA1  |.  E8 D8030000   call    <jmp.&MFC42D.#880>               ;  取得输入的序列号
  00401BA6  |.  50            push    eax                              ; /s
  00401BA7  |.  E8 4A040000   call    <jmp.&MSVCRTD.strlen>            ; \strlen
  00401BAC  |.  83C4 04       add     esp, 4
  00401BAF  |.  3BF0          cmp     esi, eax                         ;  比较两个长度
  00401BB1  |.  75 7D         jnz     short 00401C30
  00401BB3  |.  C745 AC 00000>mov     dword ptr [ebp-54], 0
  00401BBA  |.  EB 09         jmp     short 00401BC5
  00401BBC  |>  8B55 AC       /mov     edx, [ebp-54]                   ;  这个循环将对产生的组合字符串与输入的key串作异或然后
  00401BBF  |.  83C2 01       |add     edx, 1                          ;  与“bxm"比较
  00401BC2  |.  8955 AC       |mov     [ebp-54], edx
  00401BC5  |>  8D45 C4        lea     eax, [ebp-3C]
  00401BC8  |.  50            |push    eax                             ; /s
  00401BC9  |.  E8 28040000   |call    <jmp.&MSVCRTD.strlen>           ; \strlen
  00401BCE  |.  83C4 04       |add     esp, 4
  00401BD1  |.  3945 AC       |cmp     [ebp-54], eax
  00401BD4  |.  73 34         |jnb     short 00401C0A
  00401BD6  |.  8B4D AC       |mov     ecx, [ebp-54]
  00401BD9  |.  0FBE740D C4   |movsx   esi, byte ptr [ebp+ecx-3C]
  00401BDE  |.  8B55 AC       |mov     edx, [ebp-54]
  00401BE1  |.  52            |push    edx
  00401BE2  |.  8B4D FC       |mov     ecx, [ebp-4]
  00401BE5  |.  83C1 64       |add     ecx, 64
  00401BE8  |.  E8 7F030000   |call    <jmp.&MFC42D.#850>
  00401BED  |.  0FBEC0        |movsx   eax, al
  00401BF0  |.  33F0          |xor     esi, eax
  00401BF2  |.  8B45 AC       |mov     eax, [ebp-54]
  00401BF5  |.  99            |cdq
  00401BF6  |.  B9 03000000   |mov     ecx, 3
  00401BFB  |.  F7F9          |idiv    ecx
  00401BFD  |.  0FBE5415 98   |movsx   edx, byte ptr [ebp+edx-68]
  00401C02  |.  3BF2          |cmp     esi, edx
  00401C04  |.  74 02         |je      short 00401C08
  00401C06  |.  EB 02         |jmp     short 00401C0A
  00401C08  |>^ EB B2         \jmp     short 00401BBC
  00401C0A  |>  8D45 C4       lea     eax, [ebp-3C]
  00401C0D  |.  50            push    eax                              ; /s
  00401C0E  |.  E8 E3030000   call    <jmp.&MSVCRTD.strlen>            ; \strlen
  00401C13  |.  83C4 04       add     esp, 4
  00401C16  |.  3945 AC       cmp     [ebp-54], eax
  00401C19  |.  75 15         jnz     short 00401C30                   ;  如果提前跳出循环说明不对
  00401C1B  |.  6A 00         push    0                                ;  到这里就对啦
  00401C1D  |.  8D4D 90       lea     ecx, [ebp-70]
  00401C20  |.  51            push    ecx
  00401C21  |.  8D95 70FFFFFF lea     edx, [ebp-90]
  00401C27  |.  52            push    edx
  00401C28  |.  8B4D FC       mov     ecx, [ebp-4]
  00401C2B  |.  E8 42030000   call    <jmp.&MFC42D.#3517>
  
  过程如下:
  
  1.将username中的字符累乘放入整数中,如"abcdefg"就变成整数2059364400
  2.将该整数变成字符串,不过顺序是到的"0044639502",记为result1。
  3.将username的每个字符加上它偏移的2倍,第0个加0,第1个加2,第2个加四...
    这样"abcdefg"就变成了"adgjmps",记为result2。
  4.将上两步产生的字符串result1和result2组合起来
    如果result1长或两串等长,那么新串的长度是result2串长度的2倍
      0a0d4g4j6m3p9s
      result1后面有剩的话就丢掉
    如果是result2长
       那么新串的长度是result1串长度的2倍
       result1串剩下的接在组合串的后面
    这个串记为result3吧
  
  5.将result3与输入的key每个字符进行异或,看结果是否等于制定的值:"bxm"呵呵就是作者
          key[i]^result2[i]==bxm[i%3]?
    如果都对的话那就是注册成功啦
    这样写注册机的话就是
          key[i]=result2[i]^bxm[i%3];
  
    不过不幸的是key中有不可打印字符
  
    试了一下12345居然可以是RI]VJZPB[_
   
  三、注册机
  
      void keygen(char *username,char *key)
  {
          char bxm[4]="bxm";
          int usize=strlen(username);
          int pruduct=1;
          int re;
          char result1[30];
          char result2[60];
          for(int i=0;i<usize;i++)
          pruduct*=username[i];
          for(i=0;pruduct>0;i++)
          {
          re=pruduct%10;
                  pruduct/=10;
                  result1[i]=re+0x30;
          }
          result1[i]=0;
      int size1=strlen(result1);
          for(i=0;i<usize;i++)
          {
          username[i]+=i*2;
          }
         
          if(size1>=usize)
          {
              for(i=0;i<usize;i++)
                  {
              result2[i*2]=result1[i];
                          result2[i*2+1]=username[i];
                  }
                  result2[i*2]=0;
          }
          else
          {
                  for(i=0;i<size1;i++)
                  {
                          result2[i*2]=result1[i];
                          result2[i*2+1]=username[i];
                  }
                  result2[i*2]=0;
  
          }
  
          strcat(result2,username+i);
          int size2=strlen(result2);
          for(i=0;i<size2;i++)
          {
                  key[i]=result2[i]^bxm[i%3];
          }
          key[i]=0;
         
  }
  
  
  
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年10月13日 18:16:05

[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!

收藏
免费 7
打赏
分享
最新回复 (5)
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
KAN 6 2006-10-13 19:19
2
0
好,支持的说
雪    币: 372
活跃值: (31)
能力值: ( LV12,RANK:410 )
在线值:
发帖
回帖
粉丝
vxin 10 2006-10-13 19:26
3
0
赶来拜读。。。
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
Wucheng 1 2006-10-13 21:20
4
0
好文,支持楼主!
雪    币: 338
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
bfqyygy 1 2006-10-13 22:37
5
0
膜拜一下!
雪    币: 538
活跃值: (460)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
坚持到底 7 2006-10-14 12:27
6
0
好文章 但偶看不懂
游客
登录 | 注册 方可回帖
返回