⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wndproc2.asm

📁 很美的窗口控件,让你的系统界面接近WINDOWS界面...不信你
💻 ASM
字号:
;==============================================================================
; E:\Work\SubclassingThunk\2. Asm\WndProc2.asm
;
;   Subclassing Thunk (SuperClass V2) Project
;   Portions copyright (c) 2002 by Paul Caton <Paul_Caton@hotmail.com>
;   Portions copyright (c) 2002 by Vlad Vissoultchev <wqweto@myrealbox.com>
;
;   A second attempt on WndProc thunking stub. Assembled with MASM32,
;   actually Microsoft (R) Macro Assembler Version 6.14.8444
;
; Modifications:
;
; 2002-09-28    WQW     Initial implementation based on the original
;                       WndProc.asm
;
;==============================================================================

            option casemap :none                        ;# Case sensitive
            .486                                        ;# Create 32 bit code
            .model flat, stdcall                        ;# 32 bit memory model
            .code

            WM_NCDESTROY        = 82h
            GWL_WNDPROC         = -4

start:


_wnd_proc   proc    hWin        :DWORD,
                    uMsg        :DWORD,
                    wParam      :DWORD,
                    lParam      :DWORD

            local   lReturn     :DWORD,
                    bHandled    :DWORD,
                    lInstr2     :DWORD,
                    lInstr1     :DWORD
                    

            pusha                                       ; have troubles with registers under win98
            call    _entry_point
_entry_point:
            pop     ebx                                 ; get current block ptr
            sub     ebx, offset _entry_point
            xor     eax, eax                            ; zero bHandled & lReturn
            mov     bHandled, eax
            mov     lReturn, eax
            mov     ecx, [ebx][_before_buffer_size]     ; get number of 'before' msgs
            test    ecx, ecx                            ; if anything to do
            jz      _call_orig
            cmp     ecx, -1                             ; -1 interpreted as 'all msgs'
            je      _call_before
            mov     edi, [ebx][_msg_buffer]             ; edi -> start of buffer
            mov     eax, uMsg                           ; eax -> msg number
            repne   scasd
            jne     _call_orig                          ; if not found -> call orig wndproc
_call_before:
            cmp     [ebx][_addr_ebmode], 0              ; check if in break-mode
            jz      _no_debug_check_1
            call    dword ptr [ebx][_addr_ebmode]
            cmp     eax, 2                              ; prevent re-entering VB code in break-mode
            jne     _no_debug_check_1
            mov     bHandled, 1                         ; signal debug mode -> don't even try 'after'
            jmp     _call_orig
_check_if_stopped:
            test    eax, eax                            ; if IDE 'stopped'
            jne     _no_debug_check_1
            push    [ebx][_orig_wndproc]                ; Unsubclass
            push    GWL_WNDPROC
            push    [ebx][_hwnd]
            call    dword ptr [ebx][_addr_setwindowlong]
            mov     [ebx][_sink_interface], 0           ; invalidate reference
_no_debug_check_1:
            mov     edx, [ebx][_sink_interface]         ; edx -> sink interface ptr
            test    edx, edx
            jz      _call_orig
            mov     eax, [edx]                          ; check for invalid references
            test    eax, eax
            jz      _call_orig
            and     eax, 80000000h
            jnz     _call_orig
            push    ebx                                 ; save base ptr
            lea     eax, lParam                         ; pass arguments ByRef
            push    eax
            lea     eax, wParam
            push    eax
            lea     eax, uMsg
            push    eax
            lea     eax, hWin
            push    eax
            lea     eax, lReturn
            push    eax
            lea     eax, bHandled
            push    eax
            push    edx                                 ; push 'this' ptr
            mov     eax, [edx]                          ; eax -> ptr to VTBL
            call    dword ptr [eax][20h]                ; call ISubclassingSink_Before
            pop     ebx                                 ; restore base ptr
            cmp     bHandled, 0
            jne     _return_result                      ; if handled -> return result
_call_orig:
            push    ebx                                 ; save base ptr
            push    lParam                              ; call original wndproc
            push    wParam
            push    uMsg
            push    hWin
            push    [ebx][_orig_wndproc]
            call    dword ptr [ebx][_addr_callwindowproc]
            pop     ebx                                 ; restore base ptr
            mov     lReturn, eax                        ; store result
            cmp     bHandled, 0                         ; if debug mode signalled -> return result
            jne     _return_result
            mov     ecx, [ebx][_after_buffer_size]      ; search after buffer
            test    ecx, ecx                            ; if anything to do
            jz      _return_result
            cmp     ecx, -1                             ; -1 -> special 'all msgs' case
            je      _call_after
            mov     edi, [ebx][_msg_buffer]
            mov     eax, [ebx][_before_buffer_size]     ; skip 'before' buffer
            lea     edi, [edi][4*eax]                   ; using lea instead of mul
            mov     eax, uMsg
            repne   scasd
            jne     _return_result
_call_after:
            cmp     [ebx][_addr_ebmode], 0              ; check if in break-mode
            jz      _no_debug_check_2
            call    dword ptr [ebx][_addr_ebmode]
            cmp     eax, 2                              ; prevent re-entering VB code in break-mode
            je      _return_result
_no_debug_check_2:
            mov     edx, [ebx][_sink_interface]         ; edx -> sink interface ptr
            test    edx, edx
            jz      _return_result
            mov     eax, [edx]                          ; check for invalid references
            test    eax, eax
            jz      _return_result
            and     eax, 80000000h
            jnz     _return_result
            push    ebx                                 ; save base ptr (for future enh)
            push    lParam                              ; pass arguments ByVal
            push    wParam
            push    uMsg
            push    hWin
            lea     eax, lReturn                        ; pass lReturn ByRef
            push    eax
            push    edx                                 ; push 'this' ptr
            mov     eax, [edx]                          ; eax -> ptr to VTBL
            call    dword ptr [eax][1Ch]                ; call ISubclassingSink_After
            pop     ebx                                 ; restore base ptr (for future enh)
_return_result:
            cmp     uMsg, WM_NCDESTROY                  ; if destroying -> free heap chunk
            jne     _not_destroy
            mov     [ebx][_hwnd], 0
            lea     eax, [ebx][start]                   ; free current heap chunk
            push    eax
            push    0
            push    [ebx][_process_heap]
            lea     eax, lInstr1                        ; return address
            push    eax
            mov     eax, [ebx][_not_destroy]            ; copy instruction on stack (will not be able 
            mov     lInstr1, eax                        ; to return to our just freed heap chunk!)
            mov     eax, [ebx][_not_destroy+4]
            mov     lInstr2, eax
            jmp     dword ptr [ebx][_addr_heapfree]
_not_destroy:
            popa                                        ; 61h
            mov     eax, lReturn                        ; 8Bh, 45h, 0FCh
            ret                                         ; 0C9h, 0C2h, 10h, 0

_wnd_proc   endp

            org     0190h                               ; put data block at a fixed origin

            _hwnd                   dd      ?
            _orig_wndproc           dd      ?
            _sink_interface         dd      ?
            _msg_buffer             dd      ?
            _before_buffer_size     dd      ?
            _after_buffer_size      dd      ?
            _addr_callwindowproc    dd      ?
            _addr_setwindowlong     dd      ?
            _addr_ebmode            dd      ?
            _addr_heapfree          dd      ?
            _process_heap           dd      ?


;==============================================================================
comment %
;==============================================================================

    ;#########################################################################################################################
    ;#
    ;# This code represents the model used for cSuperClass message filtered subclassing.
    ;# We assemble this code merely to discover the opcodes to use in cSuperClass.cls
    ;#
    ;# Paul_Caton@hotmail.com
    ;# 13th June 2002
    ;#
    ;# P.S. I haven't assembled since the Atari ST... That's probably self-evident.
    ;#

    .486                                ;# Create 32 bit code
    .model flat, stdcall                ;# 32 bit memory model
    option casemap :none                ;# Case sensitive
    include WndProc.inc                 ;# Macros 'n stuff

    .code

    start:

    WndProc proc    hWin    :DWORD,
                    uMsg    :DWORD,
                    wParam  :DWORD,
                    lParam  :DWORD

        LOCAL   lReturn     :DWORD
        LOCAL   lHandled    :DWORD

        jmp     TestMsgNo               ;# Jump over the *constant* code to the run-time generated message number testing code

    BeforePrevWndProc:                  ;# Jump here if we're handling this message before the previous WndProc
        mov     lReturn,0
        lea     eax,lReturn
        push    eax
        mov     lHandled,0
        lea     eax,lHandled
        push    eax
        mov     eax,88888888h           ;# Patched with ObjPtr(Owner) at run-time
        mov     ecx,eax
        mov     ecx,dword ptr [ecx]
        push    eax
        call    dword ptr [ecx+20h]     ;# Call Sub iSuperClass_Before

        cmp     lHandled,0              ;# Check to see if the user doesn't want the previous WndProc to receive this message
        jnz     Bail_1

        push    lParam                  ;# Call previous WndProc handler
        push    wParam
        push    uMsg
        push    hWin
        call    PrevWndProc             ;# PrevWndProc will be patched with the EIP relative offset to the real PrevWndProc at run-time
        ret

    AfterPrevWndProc:                   ;# Jump here if we're handling this message number after the previous WndProc
        call    PrevWndProc             ;# PrevWndProc will be patched with the EIP relative offset to the real PrevWndProc at run-time
        mov     lReturn,eax

        push    lParam                  ;# Call our handler
        push    wParam
        push    uMsg
        push    hWin
        lea     eax,lReturn
        push    eax
        mov     eax,88888888h           ;# Patched with ObjPtr(Owner) at run-time
        mov     ecx,eax
        mov     ecx,dword ptr [ecx]
        push    eax
        call    dword ptr [ecx+1Ch]     ;# Call Sub iSuperClass_After
    Bail_1:
        mov     eax,lReturn
        ret

    TestMsgNo:
        mov     eax,uMsg

        push    lParam                  ;# No matter which way we branch these parameters are going to be stacked...
        push    wParam
        push    eax
        push    hWin

        cmp     eax,0BEF00000h          ;# The compare test and jump are dynamically added at run-time
        je      BeforePrevWndProc

        cmp     eax,0AF000000h          ;# The compare test and jump are dynamically added at run-time
        je      AfterPrevWndProc

        ;#
        ;# And so on for each message number added by the user
        ;#
        ;# Unspecified messages drop thru to here...
        call    PrevWndProc             ;# We're not interested in this message number, pass to the pre-existing window proc
        ret

    PrevWndProc:

    WndProc endp

;==============================================================================
end of comment %
;==============================================================================


end start

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -