欢迎来到 嗅灵易学

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

对[FCG]KeyGen2.0按钮特效的分析3、4、5

对[FCG]KeyGen2.0按钮特效的分析3、4、5

首先,废话几句。不知道有没有人还记得这个系列?在下因为个人原因,暂停了很久。不过最近在努力继续写。敬请期待……
另:如果您发现有错误/值得讨论的地方,请告诉我。
==========================================
    sub_406A1F中一共使用了3个func:sub_406B69、sub_406B89、sub_406D7D。
    首先看sub_406B69:
seg000:00406B69 sub_406B69      proc near               ; CODE XREF: sub_406A1F+B
seg000:00406B69                                         ; sub_406AED+A ...
seg000:00406B69
seg000:00406B69 arg_0           = dword ptr  8
//从前面的分析知道这个arg是窗口的句柄
seg000:00406B69
seg000:00406B69                 push    ebp
seg000:00406B6A                 mov     ebp, esp
seg000:00406B6C                 mov     edx, [ebp+arg_0]
seg000:00406B6F                 mov     eax, ds:dword_40A150
//即上文的WinPropLinkHead
seg000:00406B74                 test    eax, eax
seg000:00406B76                 jz      short loc_406B83
//为null
seg000:00406B78
seg000:00406B78 loc_406B78:                             ; CODE XREF: sub_406B69+18
seg000:00406B78                 cmp     edx, [eax]
//非空指针,将指针指向结构的CurrentWindow和参数比较
//其实就是寻找参数对应的窗口是否有相应的控制参数块
seg000:00406B7A                 jz      short loc_406B85
//找到,直接返回指针,即eax
seg000:00406B7C                 mov     eax, [eax+10h]
//取下一块的地址
seg000:00406B7F                 test    eax, eax
//下一块的地址是否是null
seg000:00406B81                 jnz     short loc_406B78
//不是null则循环,否则表示已到链尾
seg000:00406B83
seg000:00406B83 loc_406B83:                             ; CODE XREF: sub_406B69+D
seg000:00406B83                 xor     eax, eax
//直接返回null
seg000:00406B85
seg000:00406B85 loc_406B85:                             ; CODE XREF: sub_406B69+11
seg000:00406B85                 pop     ebp
seg000:00406B86                 retn    4
seg000:00406B86 sub_406B69      endp
    这个函数很容易写出:

代码:
    Function FindWindowInChain(Window:HWND):PWindowProperty;

    Begin

      Result:=WinPropLinkHead;

      

      While (Result<>Nil) Do

        Begin

          If Result^.CurrentWindow=Window Then

            Begin

              Break;

            End;

          Result:=Result^.NextWindowProperty;

        End;

    End;

    这样,前面的程序也需要修改。但是最好等到最后整理的时候再改。
    
    sub_406B89:
seg000:00406B89 sub_406B89      proc near               ; CODE XREF: sub_406A1F+19
seg000:00406B89
seg000:00406B89 ClassName       = byte ptr -104h
seg000:00406B89 hWnd            = dword ptr  8
seg000:00406B89
seg000:00406B89                 push    ebp
seg000:00406B8A                 mov     ebp, esp
seg000:00406B8C                 add     esp, 0FFFFFEFCh
//猜测是对齐
seg000:00406B92                 push    ebx
seg000:00406B93                 push    esi
//函数功能开始
seg000:00406B94                 mov     esi, [ebp+hWnd]
//参数
seg000:00406B97                 push    104h            ; nMaxCount
seg000:00406B9C                 lea     eax, [ebp+ClassName]
seg000:00406BA2                 push    eax             ; lpClassName
seg000:00406BA3                 push    esi             ; hWnd
seg000:00406BA4                 call    GetClassNameA
seg000:00406BA9                 xor     ebx, ebx
seg000:00406BAB
seg000:00406BAB loc_406BAB:                             ; CODE XREF: sub_406B89+41
seg000:00406BAB                 mov     eax, ebx
seg000:00406BAD                 shl     eax, 5
//这里实际是乘以20,字符串数组的第1维大小
seg000:00406BB0                 add     eax, offset dword_40A154
//字符串数组的地址
seg000:00406BB5                 push    eax
seg000:00406BB6                 lea     edx, [ebp+ClassName]
seg000:00406BBC                 push    edx
seg000:00406BBD                 call    lstrcmpi
seg000:00406BC2                 test    eax, eax
seg000:00406BC4                 jz      short loc_406BCC
//该窗口的类名符合条件
seg000:00406BC6                 inc     ebx
seg000:00406BC7                 cmp     ebx, 2
seg000:00406BCA                 jb      short loc_406BAB
//数组就2个元素
seg000:00406BCC
seg000:00406BCC loc_406BCC:                             ; CODE XREF: sub_406B89+3B
seg000:00406BCC                 sub     ebx, 1
seg000:00406BCF                 jb      short loc_406BD5
//是Button类
seg000:00406BD1                 jz      short loc_406BF2
//是Edit类
seg000:00406BD3                 jmp     short loc_406BF9
//都不是
seg000:00406BD5
seg000:00406BD5 loc_406BD5:                             ; CODE XREF: sub_406B89+46
seg000:00406BD5                 push    0FFFFFFF0h
//GWL_STYLE
seg000:00406BD7                 push    esi
seg000:00406BD8                 call    GetWindowLongA_0
seg000:00406BDD                 mov     ebx, eax
seg000:00406BDF                 and     ebx, 1Fh
seg000:00406BE2                 sub     ebx, 2
seg000:00406BE5                 jb      short loc_406BE9
seg000:00406BE7                 jmp     short loc_406BED
seg000:00406BE9
seg000:00406BE9 loc_406BE9:                             ; CODE XREF: sub_406B89+5C
seg000:00406BE9                 xor     ebx, ebx
seg000:00406BEB                 jmp     short loc_406BFC
seg000:00406BED
seg000:00406BED loc_406BED:                             ; CODE XREF: sub_406B89+5E
seg000:00406BED                 or      ebx, 0FFFFFFFFh
seg000:00406BF0                 jmp     short loc_406BFC
seg000:00406BF2
seg000:00406BF2 loc_406BF2:                             ; CODE XREF: sub_406B89+48
seg000:00406BF2                 mov     ebx, 1
seg000:00406BF7                 jmp     short loc_406BFC
seg000:00406BF9
seg000:00406BF9 loc_406BF9:                             ; CODE XREF: sub_406B89+4A
seg000:00406BF9                 or      ebx, 0FFFFFFFFh
seg000:00406BFC
seg000:00406BFC loc_406BFC:                             ; CODE XREF: sub_406B89+62
seg000:00406BFC                                         ; sub_406B89+67 ...
seg000:00406BFC                 mov     eax, ebx
seg000:00406BFE                 pop     esi
seg000:00406BFF                 pop     ebx
seg000:00406C00                 mov     esp, ebp
seg000:00406C02                 pop     ebp
seg000:00406C03                 retn    4
seg000:00406C03 sub_406B89      endp
    这个函数比较麻烦。因为dword_40A154数组的元素是按照32个字节对齐的,而我在D5里无法写出对应的形式。当然,可以用Array of Char解决这个问题,但是这样一是比较麻烦,二是我得完全按照汇编来写而不能享受数组的方便快捷。所以我在这里不打算做直接的对照翻译。等价的形式会更快。 
代码:
    Const

      Classes:Array[0..1] of PChar=('Button','Edit');

      

    Function sub_406B89(Window:HWND):Integer;

    Var

      ClassName:PChar;

      i:LongWord;

    Begin

      GetMem(ClassName,$104);

      GetClassName(Window,ClassName,$104);

    

      For i:=0 To 1 Do

        Begin

          If lstrcmpi(ClassName,Classes[i])=0 Then Break;

        End;

        

      Case i of

        0:

        Begin

          If GetWindowLong(Window,GWL_STYLE) AND $1F<2 Then

            Begin

              Result:=0;

            End

          Else

            Begin

              Result:=-1;

            End;

        End;

        1:

        Result:=1;

      Else

        Result:=-1;

      End;

    End;

=========================================

第4、5篇均在第一页

====================================
补充一下,00406BBD处的窗口类名比较时使用的类名实际是和程序有关的。在此例中,窗口由RC建立,所以类名为Button等……

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

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

0 0 0 举报
复制成功