首页
社区
课程
招聘
[原创]简单的CrackMe的算法分析
2006-8-1 17:39 5085

[原创]简单的CrackMe的算法分析

bxm 活跃值
29
2006-8-1 17:39
5085
【文章标题】: 简单的CrackMe的算法分析
【文章作者】: bxm
【作者邮箱】: bxm78@163.com
【软件名称】: Duelist's Crackme #4
【保护方式】: name,code
【编写语言】: MASM32 / TASM32 [覆盖]
【使用工具】: OD
【操作平台】: xinxp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
    通过简单的跟踪,发现name最好为字母,如果输入]将出现错误,应该是软件设计的原因,不能出现数字,好,下断点MessageBoxA可以很容易断下来,输入
  name:bxm
  code:780
  
  00401127   > /6A 00         push    0                        ; /lParam = 0
  00401129   . |6A 00         push    0                        ; |wParam = 0
  0040112B   . |6A 0E         push    0E                       ; |Message = WM_GETTEXTLENGTH
  0040112D   . |6A 03         push    3                        ; |ControlID = 3
  0040112F   . |FF75 08       push    dword ptr [ebp+8]        ; |hWnd
  00401132   . |E8 41020000   call    <jmp.&USER32.SendDlgItem>; \SendDlgItemMessageA
  00401137   . |A3 AF214000   mov     [4021AF], eax            ;  EAX为name长度
  0040113C   . |83F8 00       cmp     eax, 0                   ;  EAX=0 ?
  0040113F   . |0F84 D5000000 je      0040121A                 ;  是,完蛋
  00401145   . |83F8 08       cmp     eax, 8                   ;  EAX>8 ?
  00401148   . |0F8F CC000000 jg      0040121A                 ;  是,完蛋
  0040114E   . |8BF0          mov     esi, eax                 ;  name长度入ESI
  00401150   . |6A 00         push    0                        ; /lParam = 0
  00401152   . |6A 00         push    0                        ; |wParam = 0
  00401154   . |6A 0E         push    0E                       ; |Message = WM_GETTEXTLENGTH
  00401156   . |6A 04         push    4                        ; |ControlID = 4
  00401158   . |FF75 08       push    dword ptr [ebp+8]        ; |hWnd
  0040115B   . |E8 18020000   call    <jmp.&USER32.SendDlgItem>; \SendDlgItemMessageA
  00401160   . |83F8 00       cmp     eax, 0                   ;  EAX为code长度
  00401163   . |0F84 B1000000 je      0040121A                 ;  EAX为0,跳向结束
  00401169   . |3BF0          cmp     esi, eax                 ;  name长度=code长度 ?
  0040116B   . |0F85 A9000000 jnz     0040121A                 ;  不是,完蛋
  00401171   . |68 60214000   push    00402160                 ; /lParam = 402160
  00401176   . |6A 08         push    8                        ; |wParam = 8
  00401178   . |6A 0D         push    0D                       ; |Message = WM_GETTEXT
  0040117A   . |6A 03         push    3                        ; |ControlID = 3
  0040117C   . |FF75 08       push    dword ptr [ebp+8]        ; |hWnd
  0040117F   . |E8 F4010000   call    <jmp.&USER32.SendDlgItem>; \SendDlgItemMessageA
  00401184   . |68 79214000   push    00402179                 ; /lParam = 402179
  00401189   . |6A 10         push    10                       ; |wParam = 10
  0040118B   . |6A 0D         push    0D                       ; |Message = WM_GETTEXT
  0040118D   . |6A 04         push    4                        ; |ControlID = 4
  0040118F   . |FF75 08       push    dword ptr [ebp+8]        ; |hWnd
  00401192   . |E8 E1010000   call    <jmp.&USER32.SendDlgItem>; \SendDlgItemMessageA
  00401197   . |B9 FFFFFFFF   mov     ecx, -1
  0040119C   > |41            inc     ecx                      ;  ECX作为name的字符计数器
  0040119D   . |0FBE81 602140>movsx   eax, byte ptr [ecx+40216>;  EAX依次读入name的每个字符
  004011A4   . |83F8 00       cmp     eax, 0                   ;  Switch (cases 0..7A)
  004011A7   . |74 32         je      short 004011DB           ;  读完了,跳
  004011A9   . |BE FFFFFFFF   mov     esi, -1                  ;  ESI作为表1的计数器
  004011AE   . |83F8 41       cmp     eax, 41                  ;  EAX<41H ?
  004011B1   . |7C 67         jl      short 0040121A           ;  是,跳向失败
  004011B3   . |83F8 7A       cmp     eax, 7A                  ;  EAX>=7AH ?
  004011B6   . |77 62         ja      short 0040121A           ;  是,跳向失败
  004011B8   . |83F8 5A       cmp     eax, 5A                  ;  EAX<5AH ?
  004011BB   . |7C 03         jl      short 004011C0           ;  是,跳
  004011BD   . |83E8 20       sub     eax, 20                  ;  EAX-20H; Cases 5A ('Z'),5B ('['),5C ('\'),5D (']'),5E ('^'),5F ('_'),60 ('`'),61 ('a'),62 ('b'),63 ('c'),64 ('d'),65 ('e'),66 ('f'),67 ('g'),68 ('h'),69 ('i'),6A ('j'),6B ('k'),6C ('l'),6D ('m')... of switch 004011A4
  004011C0   > |46            inc     esi                      ;  Cases 41 ('A'),42 ('B'),43 ('C'),44 ('D'),45 ('E'),46 ('F'),47 ('G'),48 ('H'),49 ('I'),4A ('J'),4B ('K'),4C ('L'),4D ('M'),4E ('N'),4F ('O'),50 ('P'),51 ('Q'),52 ('R'),53 ('S'),54 ('T')... of switch 004011A4
  004011C1   . |0FBE96 172040>movsx   edx, byte ptr [esi+40201>;  读表1
  004011C8   . |3BC2          cmp     eax, edx                 ;  name转换后的字符与表1中的字符比较
  004011CA   .^|75 F4         jnz     short 004011C0           ;  不相等,继续读表
  004011CC   . |0FBE86 3C2040>movsx   eax, byte ptr [esi+40203>;  根据ESI的值读表2
  004011D3   . |8981 94214000 mov     [ecx+402194], eax        ;  EAX存于内存单元
  004011D9   .^|EB C1         jmp     short 0040119C
  004011DB   > |FF35 AF214000 push    dword ptr [4021AF]       ; /CODE长度; Case 0 of switch 004011A4
  004011E1   . |68 94214000   push    00402194                 ; |真CODE
  004011E6   . |68 79214000   push    00402179                 ; |假CODE
  004011EB   . |E8 54000000   call    00401244                 ; \due-cm4.00401244
  004011F0   . |83F8 01       cmp     eax, 1                   ;  返回值为1表示成功
  004011F3   .^|0F84 DEFEFFFF je      004010D7                 ;  跳向成功地址
  004011F9   . |EB 1F         jmp     short 0040121A
  004011FB   > |837D 10 01    cmp     dword ptr [ebp+10], 1    ; |
  004011FF   .^\0F84 22FFFFFF je      00401127                 ; |
  00401205   .  837D 10 02    cmp     dword ptr [ebp+10], 2    ; |
  00401209   .  75 2F         jnz     short 0040123A           ; |
  0040120B   >  E8 B4000000   call    <jmp.&KERNEL32.ExitProce>; \ExitProcess
  00401210   .  B8 01000000   mov     eax, 1
  00401215   .^ E9 FFFEFFFF   jmp     00401119
  0040121A   >  68 00200000   push    2000                     ; /Style = MB_OK|MB_TASKMODAL; Default case of switch 004011A4
  0040121F   .  68 01204000   push    00402001                 ; |Title = "Duelist's Crackme #4"
  00401224   .  68 AE204000   push    004020AE                 ; |Text = "Your registration info is invalid... Note that most of the special chars may raise registration problems!"
  00401229   .  6A 00         push    0                        ; |hOwner = NULL
  0040122B   .  E8 36010000   call    <jmp.&USER32.MessageBoxA>; \MessageBoxA
  
  算法小结:
  1、name长度为1――8位,code长度与其相等。
  2、把name的每个字符转换成小大写字母。
  3、name的每个字符在表1中的位置,记为A。
  4、根据A的值查表2,得到的即为注册码。
  
  可用的注册码
  name:bxm
  code:487
  
  附注册机:
  #include<iostream.h>
  #include <string.h>
  void  main()
  {
          char name[9],code[9];
          char table1[34]={
                  0x41, 0x31, 0x4C, 0x53, 0x4B, 0x32, 0x44, 0x4A, 0x46, 0x34, 0x48, 0x47, 0x50, 0x33, 0x51, 0x57,
  0x4F, 0x35, 0x45, 0x49, 0x52, 0x36, 0x55, 0x54, 0x59, 0x5A, 0x38, 0x4D, 0x58, 0x4E, 0x37, 0x43,
  0x42, 0x56};
          char table2[34]={
                  0x53, 0x55, 0x37, 0x43, 0x53, 0x4A, 0x4B, 0x46, 0x30, 0x39, 0x4E, 0x43, 0x53, 0x44, 0x4F, 0x39,
  0x53, 0x44, 0x46, 0x30, 0x39, 0x53, 0x44, 0x52, 0x4C, 0x56, 0x4B, 0x37, 0x38, 0x30, 0x39, 0x53,
  0x34, 0x4E};
          int i,j;
          cout<<"Please input name(1-8bit):\n";
          cin>>name;
          for(i=0;i<strlen(name);i++)
          {
                  if(name[i]>0x5A)name[i]-=0x20;
                  j=0;
                  while(name[i]!=table1[j])j++;
                  code[i]=table2[j];
          }
          code[i]=0;
          cout<<endl<<"Code is "<<code<<endl;
  }
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年08月01日 下午 05:37:27

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 7
打赏
分享
最新回复 (2)
雪    币: 433
活跃值: (176)
能力值: ( LV13,RANK:1250 )
在线值:
发帖
回帖
粉丝
冲天剑 31 2006-8-2 20:17
2
0
你这表可以直接定义成一个字符串
char table1[] = "A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9";
char table2[] = "SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF";

另外,算法还可以优化
雪    币: 338
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
bfqyygy 1 2006-8-2 21:17
3
0
分析的好!学习!
游客
登录 | 注册 方可回帖
返回