欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

答复

答复

对[FCG]KeyGen2.0按钮特效的分析5
这个过程应该比较简单。
seg000:00406CA5 sub_406CA5      proc near               ; CODE XREF: sub_4070D9+18D
seg000:00406CA5
seg000:00406CA5 Rect            = tagRECT ptr -10h
seg000:00406CA5 arg_0           = dword ptr  8
seg000:00406CA5
seg000:00406CA5                 push    ebp
seg000:00406CA6                 mov     ebp, esp
seg000:00406CA8                 add     esp, 0FFFFFFF0h
seg000:00406CAB                 push    ebx
seg000:00406CAC                 mov     ebx, [ebp+arg_0]
seg000:00406CAF                 cmp     dword ptr [ebx+0Ch], 1
//arg_0又是指针 
seg000:00406CB3                 jnz     short loc_406CE6
seg000:00406CB5                 lea     eax, [ebp+Rect]
seg000:00406CB8                 push    eax             ; lpRect
seg000:00406CB9                 push    dword ptr [ebx] ; hWnd
seg000:00406CBB                 call    GetWindowRect
seg000:00406CC0                 push    0CC0020h        ; DWORD
seg000:00406CC5                 push    0               ; int
seg000:00406CC7                 push    0               ; int
seg000:00406CC9                 push    dword ptr [ebx+8] ; HDC
seg000:00406CCC                 mov     edx, [ebp+Rect.bottom]
seg000:00406CCF                 sub     edx, [ebp+Rect.top]
seg000:00406CD2                 push    edx             ; int
seg000:00406CD3                 mov     ecx, [ebp+Rect.right]
seg000:00406CD6                 sub     ecx, [ebp+Rect.left]
seg000:00406CD9                 push    ecx             ; int
seg000:00406CDA                 push    0               ; int
seg000:00406CDC                 push    0               ; int
seg000:00406CDE                 push    dword ptr [ebx+4] ; HDC
seg000:00406CE1                 call    BitBlt
seg000:00406CE6
seg000:00406CE6 loc_406CE6:                             ; CODE XREF: sub_406CA5+E
seg000:00406CE6                 cmp     dword ptr [ebx+10h], 0
seg000:00406CEA                 jz      short loc_406CFD
seg000:00406CEC                 push    dword ptr [ebx+10h] ; HGDIOBJ
seg000:00406CEF                 push    dword ptr [ebx+8] ; HDC
seg000:00406CF2                 call    SelectObject
seg000:00406CF7                 push    eax             ; HGDIOBJ
seg000:00406CF8                 call    DeleteObject
seg000:00406CFD
seg000:00406CFD loc_406CFD:                             ; CODE XREF: sub_406CA5+45
seg000:00406CFD                 push    dword ptr [ebx+8] ; HDC
seg000:00406D00                 call    DeleteDC
seg000:00406D05                 push    dword ptr [ebx+4] ; hDC
seg000:00406D08                 push    dword ptr [ebx] ; hWnd
seg000:00406D0A                 call    ReleaseDC
seg000:00406D0F                 pop     ebx
seg000:00406D10                 mov     esp, ebp
seg000:00406D12                 pop     ebp
seg000:00406D13                 retn    4
seg000:00406D13 sub_406CA5      endp
    实在没有什么难度,注释都不必写。唯一值得注意的是,arg_0是个什么玩意。对照一下sub_406C06的分析,可以看出,arg_0就是WindowsDCInfo的指针。

代码:
Procedure sub_406CA5(DCInfo:PWindowsDCInfo);

Var

  Rect:TRect;

Begin

  If DCInfo^.unknown=1 Then

    Begin

      GetWindowRect(DCInfo.hWindow,Rect);

      BitBlt(DCInfo.WinDC,0,0,Rect.right-Rect.left,Rect.bottom-Rect.top,DCInfo.CompDC,0,0,SRCCOPY);

    End;

    

  If DCInfo^.hBitmap<>0 Then

    Begin

      DeleteObject(SelectObject(DCInfo.CompDC,DCInfo.hBitmap));

    End;

    

  DeleteDC(DCInfo.CompDC);

  ReleaseDC(DCInfo.hWindow,DCInfo.WinDC);

End;

    看来这段代码是释放sub_406C06生成的DC资源。
    
    终于开始分析sub_4070D9了:
seg000:004070D9 sub_4070D9      proc near               ; CODE XREF: sub_406D7D+5C
seg000:004070D9                                         ; sub_406D7D+89 ...
seg000:004070D9
seg000:004070D9 String          = byte ptr -124h
seg000:004070D9 var_24          = dword ptr -24h
seg000:004070D9 hDC             = dword ptr -1Ch
seg000:004070D9 var_18          = dword ptr -18h
seg000:004070D9 var_14          = dword ptr -14h
seg000:004070D9 var_10          = dword ptr -10h
seg000:004070D9 arg_0           = dword ptr  8
seg000:004070D9
seg000:004070D9                 push    ebp
seg000:004070DA                 mov     ebp, esp
seg000:004070DC                 add     esp, 0FFFFFEDCh
seg000:004070E2                 push    ebx
seg000:004070E3                 push    esi
seg000:004070E4                 push    edi
seg000:004070E5                 mov     ebx, [ebp+arg_0]
seg000:004070E8                 lea     edi, [ebp+var_10]
seg000:004070EB                 mov     eax, [ebx]
//arg_0仍然是指针
seg000:004070ED                 mov     [ebp+var_24], eax
//联系004070FE处代码,这里eax即arg_0^应该是窗口句柄。
seg000:004070F0                 xor     edx, edx
seg000:004070F2                 mov     [ebp+var_18], edx
//unknown
seg000:004070F5                 xor     ecx, ecx
seg000:004070F7                 mov     [ebp+var_14], ecx
//hBitmap
seg000:004070FA                 lea     eax, [ebp+var_24]
seg000:004070FD                 push    eax
seg000:004070FE                 call    sub_406C06
//内部调用
seg000:00407103                 push    edi             ; lpRect
seg000:00407104                 push    dword ptr [ebx] ; hWnd
seg000:00407106                 call    GetWindowRect
//var_10就是Rect了
seg000:0040710B                 mov     edx, [edi]
seg000:0040710D                 sub     [edi+8], edx
//var_10.right-=var_10.left
seg000:00407110                 mov     ecx, [edi+4]
seg000:00407113                 sub     [edi+0Ch], ecx
//var_10.bottom-=var_10.top
seg000:00407116                 xor     eax, eax
seg000:00407118                 mov     [edi+4], eax
//var_10.top=0
seg000:0040711B                 mov     [edi], eax
//var_10.left=0
seg000:0040711D                 test    byte ptr [ebx+8], 1
seg000:00407121                 jz      short loc_407131
//if arg_0^[8] and 1 =0 then goto loc_407131
seg000:00407123                 push    0Fh             ; nIndex
//COLOR_3DFACE
seg000:00407125                 call    GetSysColor
seg000:0040712A                 sub     eax, 202020h
seg000:0040712F                 jmp     short loc_407136
seg000:00407131
seg000:00407131 loc_407131:                             ; CODE XREF: sub_4070D9+48
seg000:00407131                 mov     eax, 733C00h
seg000:00407136
seg000:00407136 loc_407136:                             ; CODE XREF: sub_4070D9+56
seg000:00407136                 push    eax             ; COLORREF
seg000:00407137                 call    CreateSolidBrush
seg000:0040713C                 mov     esi, eax
//esi=hBrush
seg000:0040713E                 push    esi             ; hbr
seg000:0040713F                 push    edi             ; lprc
seg000:00407140                 push    [ebp+hDC]       ; hDC
seg000:00407143                 call    FrameRect
//这里的hDC实际是CompDC
seg000:00407148                 push    esi             ; HGDIOBJ
seg000:00407149                 call    DeleteObject
seg000:0040714E                 push    0FFFFFFFFh      ; dy
seg000:00407150                 push    0FFFFFFFFh      ; dx
seg000:00407152                 push    edi             ; lprc
seg000:00407153                 call    InflateRect
seg000:00407158                 test    byte ptr [ebx+8], 1
seg000:0040715C                 jz      short loc_40717C
//if arg_0^[8] and 1 =0 then goto loc_40717C
seg000:0040715E                 push    0EAF4F5h        ; COLORREF
seg000:00407163                 call    CreateSolidBrush
seg000:00407168                 mov     esi, eax
seg000:0040716A                 push    esi             ; hbr
seg000:0040716B                 push    edi             ; lprc
seg000:0040716C                 push    [ebp+hDC]       ; hDC
seg000:0040716F                 call    FillRect
seg000:00407174                 push    esi             ; HGDIOBJ
seg000:00407175                 call    DeleteObject
seg000:0040717A                 jmp     short loc_4071BA
seg000:0040717C
seg000:0040717C loc_40717C:                             ; CODE XREF: sub_4070D9+83
seg000:0040717C                 test    byte ptr [ebx+8], 2
//看来arg_0^[8]应该是位组合
seg000:00407180                 jz      short loc_407186
seg000:00407182                 xor     eax, eax
seg000:00407184                 jmp     short loc_4071A8
seg000:00407186
seg000:00407186 loc_407186:                             ; CODE XREF: sub_4070D9+A7
seg000:00407186                 test    byte ptr [ebx+8], 4
seg000:0040718A                 jz      short loc_407190
seg000:0040718C                 xor     eax, eax
seg000:0040718E                 jmp     short loc_4071A8
seg000:00407190
seg000:00407190 loc_407190:                             ; CODE XREF: sub_4070D9+B1
seg000:00407190                 test    byte ptr [ebx+8], 8
seg000:00407194                 jnz     short loc_40719C
seg000:00407196                 test    byte ptr [ebx+8], 10h
seg000:0040719A                 jz      short loc_4071A3
seg000:0040719C
seg000:0040719C loc_40719C:                             ; CODE XREF: sub_4070D9+BB
seg000:0040719C                 mov     eax, 2
seg000:004071A1                 jmp     short loc_4071A8
seg000:004071A3
seg000:004071A3 loc_4071A3:                             ; CODE XREF: sub_4070D9+C1
seg000:004071A3                 mov     eax, 2
//上面这一段代码有点奇怪。特别是40719A。怀疑是原作者削掉了一些条件值。 
seg000:004071A8
seg000:004071A8 loc_4071A8:                             ; CODE XREF: sub_4070D9+AB
seg000:004071A8                                         ; sub_4070D9+B5 ...
seg000:004071A8                 shl     eax, 4
seg000:004071AB                 add     eax, offset dword_40A19C
//dword_40A19C应该是数组首地址。注意这里的eax计算,暗示这是3*4的AlphaRGB
seg000:004071B0                 push    eax             ; int
seg000:004071B1                 push    edi             ; int
seg000:004071B2                 push    [ebp+hDC]       ; HDC
seg000:004071B5                 call    sub_406F99
seg000:004071BA
seg000:004071BA loc_4071BA:                             ; CODE XREF: sub_4070D9+A1
seg000:004071BA                 test    byte ptr [ebx+8], 2
seg000:004071BE                 jz      short loc_4071CE
seg000:004071C0                 push    offset dword_40A1CC ; int
seg000:004071C5                 push    edi             ; int
seg000:004071C6                 push    [ebp+hDC]       ; HDC
seg000:004071C9                 call    sub_406F99
seg000:004071CE
seg000:004071CE loc_4071CE:                             ; CODE XREF: sub_4070D9+E5
seg000:004071CE                 test    byte ptr [ebx+8], 8
seg000:004071D2                 jz      short loc_4071E7
seg000:004071D4                 push    0FFFFFFFFh      ; dy
seg000:004071D6                 push    0FFFFFFFFh      ; dx
seg000:004071D8                 push    edi             ; lprc
seg000:004071D9                 call    InflateRect
seg000:004071DE                 push    edi             ; lprc
seg000:004071DF                 push    [ebp+hDC]       ; hDC
seg000:004071E2                 call    DrawFocusRect
seg000:004071E7
seg000:004071E7 loc_4071E7:                             ; CODE XREF: sub_4070D9+F9
seg000:004071E7                 push    100h            ; nMaxCount
seg000:004071EC                 lea     edx, [ebp+String]
seg000:004071F2                 push    edx             ; lpString
seg000:004071F3                 push    dword ptr [ebx] ; hWnd
seg000:004071F5                 call    GetWindowTextA
//取得窗口标题,最多256字节
seg000:004071FA                 test    eax, eax
seg000:004071FC                 jz      short loc_40725B
seg000:004071FE                 test    byte ptr [ebx+8], 2
seg000:00407202                 jz      short loc_40720E
seg000:00407204                 push    1               ; dy
seg000:00407206                 push    1               ; dx
seg000:00407208                 push    edi             ; lprc
seg000:00407209                 call    OffsetRect
seg000:0040720E
seg000:0040720E loc_40720E:                             ; CODE XREF: sub_4070D9+129
seg000:0040720E                 test    byte ptr [ebx+8], 1
seg000:00407212                 jz      short loc_40721B
seg000:00407214                 mov     ecx, 94A2A5h
seg000:00407219                 jmp     short loc_40721D
seg000:0040721B
seg000:0040721B loc_40721B:                             ; CODE XREF: sub_4070D9+139
seg000:0040721B                 xor     ecx, ecx
seg000:0040721D
seg000:0040721D loc_40721D:                             ; CODE XREF: sub_4070D9+140
seg000:0040721D                 push    ecx             ; COLORREF
seg000:0040721E                 push    [ebp+hDC]       ; HDC
seg000:00407221                 call    SetTextColor
seg000:00407226                 push    0
seg000:00407228                 push    0
seg000:0040722A                 push    31h
//WM_GETFONT
seg000:0040722C                 push    dword ptr [ebx]
seg000:0040722E                 call    SendMessageA_0
seg000:00407233                 push    eax             ; HGDIOBJ
seg000:00407234                 push    [ebp+hDC]       ; HDC
seg000:00407237                 call    SelectObject
seg000:0040723C                 mov     esi, eax
seg000:0040723E                 push    25h
//DT_SINGLELINE+DT_VCENTER+DT_CENTER
seg000:00407240                 push    edi
seg000:00407241                 push    0FFFFFFFFh
seg000:00407243                 lea     eax, [ebp+String]
seg000:00407249                 push    eax
seg000:0040724A                 push    [ebp+hDC]
seg000:0040724D                 call    DrawTextA_0
seg000:00407252                 push    esi             ; HGDIOBJ
seg000:00407253                 push    [ebp+hDC]       ; HDC
seg000:00407256                 call    SelectObject
seg000:0040725B
seg000:0040725B loc_40725B:                             ; CODE XREF: sub_4070D9+123
seg000:0040725B                 mov     [ebp+var_18], 1
seg000:00407262                 lea     edx, [ebp+var_24]
seg000:00407265                 push    edx
seg000:00407266                 call    sub_406CA5
seg000:0040726B                 pop     edi
seg000:0040726C                 pop     esi
seg000:0040726D                 pop     ebx
seg000:0040726E                 mov     esp, ebp
seg000:00407270                 pop     ebp
seg000:00407271                 retn    4
seg000:00407271 sub_4070D9      endp
    通过查找引用,可以知道arg_0是PWindowProperty类型的。
代码:
Const

  ARGBs:Array[0..2] of Array[0..3] of AlphaRGB=

  (

  ((ARGB:$A5B2B5),(ARGB:$CED7D6),(ARGB:$CED7D6),(ARGB:$DEEFF7)),

  ((ARGB:$CEF3FF),(ARGB:$63CBFF),(ARGB:$63CBFF),(ARGB:$31B2FF)),

  ((ARGB:$FAE3BA),(ARGB:$CCA372),(ARGB:$BC9362),(ARGB:$BE9463))

  )

  ;

  GradientARGBs:Array[0..3] of AlphaRGB=

    ((ARGB:$DEE3E7),(ARGB:$E7E7E7),(ARGB:$DEE3E7),(ARGB:$FFDEE3E7));

Procedure sub_4070D9(wp:PWindowProperty);

Var

  title:Array[0..256] of Char;

  r:Rect;

  DCInfo:WindowsDCInfo;

  Brush:HBRUSH;

  color:COLORREF;

  clrindex:Byte;

  fnt:HFONT;

Begin

  DCInfo.hWindow:=wp^.CurrentWindow;

  DCInfo.unknown:=0;

  DCInfo.hBitmap:=0;

  sub_406C06(DCInfo);

  GetWindowRect(wp^.CurrentWindow,r);

  r.right:=r.right-r.left;

  r.bottom:=r.bottom-r.top;

  r.top:=0;

  r.left:=0;

  If wp^.Preserve2 AND 1<>0 Then

    Begin

      color:=GetSysColor(COLOR_3DFACE)-$202020;

    End

  Else

    Begin

      color:=$733C00;

    End;

  Brush:=CreateSolidBrush(color);

  FrameRect(DCInfo.CompDC,r,Brush);

  DeleteObject(Brush);

  

  InflateRect(r,-1,-1);

  If wp^.Preserve2 AND 1<>0 Then

    Begin

      Brush:=CreateSolidBrush($EAF4F5);

      FillRect(DCInfo.CompDC,r,Brush);

      DeleteObject(Brush);

    End

  Else

    Begin

      If (wp^.Preserve2 AND 2=0) AND (wp^.Preserve2 AND 4=0) Then

        Begin

          clrindex:=2;

        End

      Else

        Begin

          clrindex:=0;

        End;

      sub_406F99(DCInfo.CompDC,r,ARGBs[clrindex]);

    End;

    

  If wp^.Preserve2 AND 2<>0 Then

    Begin

      DoGradientFill(DCInfo.CompDC,r,GradientARGBs);

    End;

  If wp^.Preserve2 AND 8<>0 Then

    Begin

      InflateRect(r,-1,-1);

      DrawFocusRect(DCInfo.CompDC,r);

    End;

  If GetWindowText(wp^.CurrentWindow,@title,$100)<>0 Then

    Begin

      If wp^.Preserve2 AND 2<>0 Then

        Begin

          OffsetRect(r,1,1);

        End;

      If wp^.Preserve2 AND 1<>0 Then

        Begin

          clrindex:=94A2A5h

        End

      Else

        Begin

          clrindex:=0;

        End;

        

      SetTextColor(DCInfo.CompDC,clrindex);

      fnt:=SelectObject(DCInfo.CompDC,SendMessage(wp^.CurrentWindow,WM_GETFONT,0,0));

      DrawTextA(DCInfo.CompDC,@title,-1,r);

      SelectObject(DCInfo.CompDC,fnt);

    End;

  DCInfo.unknown:=1;

  sub_406CA5(DCInfo);

End;

    我不得不说,这段函数确实够长……换句话说,长得该死……
    不过,wp^.Preserve2到底是什么玩意,确实值得分析。

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功