首页
社区
课程
招聘
[原创]skilLa's keyGenMe#3算法分析(检测断点)
发表于: 2006-9-30 16:53 5822

[原创]skilLa's keyGenMe#3算法分析(检测断点)

bxm 活跃值
29
2006-9-30 16:53
5822

【文章标题】: skilLa's keyGenMe#3算法分析(检测断点)
【文章作者】: bxm
【作者邮箱】: bxm78@163.com
【保护方式】: name,serial
【编写语言】: MASM32 / TASM32
【使用工具】: OD,计算器
【操作平台】: winxp
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  本打算下常规断点的,可此程序有断点检查功能,只要扫描到有断点,立刻终止程序。无奈,只有静态分析了。
  0040105D   .  6A 14         push    14                               ; /Count = 14 (20.)
  0040105F   .  68 46304000   push    00403046                         ; |Buffer = skilLa's.00403046
  00401064   .  68 EC030000   push    3EC                              ; |ControlID = 3EC (1004.)
  00401069   .  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
  0040106C   .  E8 71010000   call    <jmp.&user32.GetDlgItemTextA>    ; \GetDlgItemTextA
  00401071   .  83F8 04       cmp     eax, 4                           ;  name长度与4比较
  00401074   .  0F82 C2000000 jb      0040113C                         ;  小于,跳向失败
  0040107A   .  6A 0A         push    0A                               ; /Count = A (10.)
  0040107C   .  68 00304000   push    00403000                         ; |Buffer = skilLa's.00403000
  00401081   .  68 EA030000   push    3EA                              ; |ControlID = 3EA (1002.)
  00401086   .  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
  00401089   .  E8 54010000   call    <jmp.&user32.GetDlgItemTextA>    ; \GetDlgItemTextA
  0040108E   .  83F8 08       cmp     eax, 8                           ;  serial长度与8比
  00401091   .  0F85 A5000000 jnz     0040113C                         ;  不相等,跳向失败
  00401097   .  8D35 00304000 lea     esi, [403000]                    ;  serial地址入ESI
  0040109D   .  83C6 04       add     esi, 4                           ;  ESI+4
  004010A0   .  8B06          mov     eax, [esi]                       ;  serial后四位入EAX
  004010A2   .  8D3D 46304000 lea     edi, [403046]                    ;  name地址入EDI
  004010A8   .  8B1F          mov     ebx, [edi]                       ;  name的前四位入EBX
  004010AA   .  33C3          xor     eax, ebx                         ;  EAX与EBX异或
  004010AC   .  3D 37130000   cmp     eax, 1337                        ;  EAX=1337 ?
  004010B1   .  0F85 85000000 jnz     0040113C                         ;  不等,跳向失败
  
  以上功能,Name长度必须大于等于4,Serial必须等于8,然后用name的前四位与serial的后四异或,结果必须为1337,否则失败。如我输入name为bxm78,则serial的后四位必须为Ukm7。
  =========================================================================
  004010B7   .  33C0          xor     eax, eax                         ;  EAX清0
  004010B9   .  33DB          xor     ebx, ebx                         ;  EBX清0
  004010BB   .  8D35 00304000 lea     esi, [403000]                    ;  serial地址入ESI
  004010C1   .  8A06          mov     al, [esi]                        ;  serial的第1位入AL
  004010C3   .  F6E0          mul     al                               ;  AL*AL
  004010C5   .  A3 0B304000   mov     [40300B], eax                    ;  存入[40300B]单元
  004010CA   .  46            inc     esi                              ;  ESI+1
  004010CB   .  33C0          xor     eax, eax                         ;  EAX清0
  004010CD   .  8A06          mov     al, [esi]                        ;  serial的第2位入AL
  004010CF   .  B1 68         mov     cl, 68                           ;  68入CL
  004010D1   .  F6E1          mul     cl                               ;  AL*CL
  004010D3   .  8BD8          mov     ebx, eax                         ;  EAX入EBX
  004010D5   .  A1 0B304000   mov     eax, [40300B]                    ;  [40300B]入EAX
  004010DA   .  2BC3          sub     eax, ebx                         ;  EAX-EBX
  004010DC   .  05 8C0A0000   add     eax, 0A8C                        ;  EAX+0A8C
  004010E1   .  33DB          xor     ebx, ebx
  004010E3   .  8935 5B304000 mov     [40305B], esi                    ;  ESI入[40305B]
  004010E9   .  F6F0          div     al                               ;  除以AL
  004010EB   .  61            popad
  004010EC   .  6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
  004010EE   .  68 1D304000   push    0040301D                         ; |Title = "o0ps!!"
  004010F3   .  68 0F304000   push    0040300F                         ; |Text = "Try again... "
  004010F8   .  FF75 08       push    dword ptr [ebp+8]                ; |hOwner
  004010FB   .  E8 E8000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
  
  可以看出,在004010E9必须要发生异常,否则,注册失败。设serial的第1位为A,第2位为B,则A*A-B*68+0A8C的结果的低8位必须为0,为此,我设计了这样C程序:
          int i,j,temp;                   //i即A,j即B
          for(i=0x21;i<0x7B;i++)
          {
                  temp=i*i+0xA8C;
                  for(j=0x21;j<0x7B;j++)
                  if((temp-j*0x68)%0x100==0) cout<<char(i)<<"              "<<char(j)<<endl;
  可以求出好多组可用的数据,如A='B'  B='Z'
  ======================================================================
  00401110   > /8B35 5B304000 mov     esi, [40305B]                    ;  serial的第2位地址入ESI
  00401116   . |46            inc     esi                              ;  ESI+1
  00401117   . |8A06          mov     al, [esi]                        ;  serial的第3位入AL
  00401119   . |F7E0          mul     eax                              ;  EAX*EAX
  0040111B   . |A3 0B304000   mov     [40300B], eax                    ;  存入[40300B]单元
  00401120   . |46            inc     esi
  00401121   . |33C0          xor     eax, eax
  00401123   . |8A06          mov     al, [esi]                        ;  serial的第4位入AL
  00401125   . |B1 68         mov     cl, 68                           ;  68入CL
  00401127   . |F6E1          mul     cl                               ;  AL*CL
  00401129   . |8BD8          mov     ebx, eax                         ;  EAX入EBX
  0040112B   . |A1 0B304000   mov     eax, [40300B]                    ;  [40300B]入EAX
  00401130   . |2BC3          sub     eax, ebx                         ;  EAX-EBX
  00401132   . |05 8C0A0000   add     eax, 0A8C                        ;  EAX+0A8C
  00401137   . |83F8 00       cmp     eax, 0                           ;  EAX=0 ?
  0040113A   . |74 18         je      short 00401154                   ;  相等,跳向成功
  0040113C   > |61            popad
  0040113D   . |6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
  0040113F   . |68 1D304000   push    0040301D                         ; |Title = "o0ps!!"
  00401144   . |68 0F304000   push    0040300F                         ; |Text = "Try again... "
  00401149   . |FF75 08       push    dword ptr [ebp+8]                ; |hOwner
  0040114C   . |E8 97000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
  00401151   . |60            pushad
  00401152   . |EB 16         jmp     short 0040116A
  00401154   > |61            popad
  00401155   . |6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
  00401157   . |68 24304000   push    00403024                         ; |Title = "Wo0!!"
  0040115C   . |68 2A304000   push    0040302A                         ; |Text = "Goodboy, now write a keygen"
  00401161   . |FF75 08       push    dword ptr [ebp+8]                ; |hOwner
  00401164   . |E8 7F000000   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
  00401169   . |60            pushad
  0040116A   > |EB 45         jmp     short 004011B1
  0040116C   $ |8B4C24 0C     mov     ecx, [esp+C]                     ;  结构异常处理程序
  00401170   . |8BA1 C4000000 mov     esp, [ecx+C4]
  00401176   . |64:8F05 00000>pop     dword ptr fs:[0]
  0040117D   . |83C4 04       add     esp, 4
  00401180   .^\EB 8E         jmp     short 00401110
  
  设Serial的第3位为C,第4位为D,则C*C-D*68+0A8C=0,为此,设计如下的C程序:
          int i,temp;
          for(i=0x21;i<0x7B;i++)
          {
                  temp=i*i+0xA8C;
                  if(temp%0x68==0) cout<<char(i)<<"              "<<char(temp/0x68)<<endl;
          }
  也可以求出多组可用的数据,如C='2',D='2'
  
  附可用注册码:
  name:bxm78
  serial:BZ22Ukm7     或2222Ukm7
  一个name可以对应多个serial,serial只与name的前4位有关。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年09月29日 下午 09:44:55


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (3)
雪    币: 200
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
zcg
2
精彩,学习了!
2006-9-30 17:03
0
雪    币: 560
活跃值: (359)
能力值: ( LV13,RANK:1370 )
在线值:
发帖
回帖
粉丝
3
最初由 bxm 发布
skilLa's keyGenMe#3算法分析(检测断点)
........

确切点说应该不是只检测断点,而是将OEP处到004011B1处的代码做了内存镜象校检,在这段代码中修改任何代码都会被检测到。因为OD下断就是插入个INT3,所以也被检测到了:

004011B1   > \B8 00104000   MOV EAX,<ModuleEntryPoint>               ;  入口点的EIP,401000
004011B6   >  8B18          MOV EBX,DWORD PTR DS:[EAX]               ;  内存映像
004011B8   .  40            INC EAX                                  ;  逐行检测代码
004011B9   .  03CB          ADD ECX,EBX                              ;  内存映像总和
004011BB   .  3D B1114000   CMP EAX,004011B1                         ;  一直到EIP=4011B1
004011C0   .^ 75 F4         JNZ SHORT 004011B6
004011C2   .  81F9 4A181941 CMP ECX,4119184A                         ;  内存映像总和是否为4119184A
004011C8   .^ 0F85 57FEFFFF JNZ 00401025                             ;  退出程序,NOP掉即可

这段代码改一下应该可以用内联汇编在高级语言中用于内存镜象校检。
2006-9-30 17:51
0
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
4
最初由 laomms 发布
确切点说应该不是只检测断点,而是将OEP处到004011B1处的代码做了内存镜象校检,在这段代码中修改任何代码都会被检测到。因为OD下断就是插入个INT3,所以也被检测到了:

004011B1 > \B8 00104000 MOV EAX,<ModuleEntryPoint> ; 入口点的EIP,401000
004011B6 > 8B18 MOV EBX,DWORD PTR DS:[EAX] ; 内存映像
004011B8 . 40 INC EAX ; 逐行检测代码
........

感谢指导,其实上面的断点检测是我猜测的!
2006-10-1 13:27
0
游客
登录 | 注册 方可回帖
返回
//