flat assembler
Message board for the users of flat assembler.

Index > Windows > Logging Windows Events

Author
Thread Post new topic Reply to topic
bitRAKE



Joined: 21 Jul 2003
Posts: 4016
Location: vpcmpistri
bitRAKE 09 Jan 2019, 02:06
By creating a dialog indirectly the event messages are not sent to hooks on desktop version of Windows. Opening a standard dialog (ex. Calc.exe About...) will send messages. Message boxes are standard dialogs.
Code:
include 'format/format.inc'

format PE64 CONSOLE 6.0 at $10000 on "NUL"
stack 1000h,1000h
heap  1000h,1000h

; convert UTF8 string to UTF16
struc utf16? line&
        label .:2
        local i,j
        virtual at 0
                db line,-1
                load i:$ from $$
        end virtual
        while i>255
                j = i and $FF
                i = i shr 8
                if j<$80
                        dw j
                else if j<$E0
                        j = ((j and $1F) shl 6) + (i and $3F)
                        i = i shr 8
                        dw j
                else if j<$F7
                        j = ((j and $0F) shl 6) + (i and $3F)
                        i = i shr 8
                        j = (j shl 6) + (i and $3F)
                        i = i shr 8
                        if $D7FF<j & j<$E000
                                err "unexpected code point"
                        else
                                dw j
                        end if
                else
                        ; need to split and store two words
                        err "other planes not implemented, yet"
                end if
        end while
end struc


section '.data' data readable writeable

msg rq 8

va_list rq 8

hHook           dq ?
msLastEvent     dq ?

; [thread] hWnd obj child time "string"
_format UTF16 '[%d] %IX %IX:%IX, %d ms "%s"',0

        align 64
; API says limit of 1024 bytes for wvsprintfW, but it's character length
buff rb 4096



section '.text' code readable executable

__entry: entry $
        pop rax                 ; reuse shadow space from caller

        call ToggleHook

; process messages
        lea rsi,[msg]
_Loop:  mov rcx,rsi
        call [TranslateMessage]
        mov rcx,rsi
        call [DispatchMessageW]
.get:   xor r9,r9
        xor r8,r8
        xor edx,edx
        mov rcx,rsi
        call [GetMessageW]
        test eax,eax ; -1,0,1
        jg _Loop

        call ToggleHook        

        xor ecx,ecx
        call [exit]
        int3                    ; exit should not return


ToggleHook:
        virtual at rbp-.FRAME
                        rq 4    ; shadow forward
                .p4     rq 1
                .p5     rq 1
                .p6     rq 1
                        ; only if padding needed
                        rb (16-(($-$$) AND 15)) AND 15
                .FRAME := $-$$
                        rq 1    ; RBP saved
                        rq 1    ; return address
                .s0     rq 1    ; our shadow
                .s1     rq 1    ; our shadow
                .s2     rq 1    ; our shadow
                .s3     rq 1    ; our shadow
        end virtual
        enter .FRAME,0
        mov rcx,[hHook]
        jrcxz .hook_off
        call [UnhookWinEvent]
        and [hHook],0
        leave
        retn

.hook_off:
        xor r8,r8                       ; hook not in DLL
        mov [.p6],r8                    ; WINEVENT_OUTOFCONTEXT
        mov [.p5],r8                    ; all existing threads
        mov [.p4],r8                    ; all process events
        lea r9,[WinEventProc]
        mov edx,16                      ; EVENT_SYSTEM_DIALOGSTART
        mov ecx,edx                     ; EVENT_SYSTEM_DIALOGSTART
        call [SetWinEventHook]
        xchg rcx,rax
        jrcxz .err_hook
        mov [hHook],rcx
.err_com:
.err_hook:
        leave
        retn

WinEventProc:
        virtual at rbp-.FRAME
                        rq 4    ; shadow forward
                .output rq 1
                        ; only if padding needed
                        rb (16-(($-$$) AND 15)) AND 15
                .FRAME := $-$$
                                rq 1    ; RBP saved
                                rq 1    ; return address
                .hWinEventHook  rq 1    ; our shadow
                .event          rq 1    ; our shadow
                .hWnd           rq 1    ; our shadow
                .idObject       rq 1    ; our shadow
                .idChild        rq 1    ;
                .idEventThread  rq 1    ;
                .dwmsEventTime  rq 1    ;
        end virtual
        enter .FRAME,0
        ; fill shadow space to preserve parameters
        mov [.hWinEventHook],rcx
        mov [.event],rdx
        mov [.hWnd],r8
        mov [.idObject],r9

        or r8d,-1                       ; all of it
        lea rdx,[buff]
        mov rcx,[.hWnd]
        mov qword [rdx],"?"             ; clear string to unknown
        call [GetWindowTextW]
        lea rcx,[buff+(rax+1)*2]
        mov [.output],rcx

        push rdi
        lea rdi,[va_list]
        mov r8,rdi
        mov rax,[.idEventThread]
        stosq
        mov rax,[.hWnd]
        stosq
        mov rax,[.idObject]
        stosq
        mov rax,[.idChild]
        stosq
        mov rax,[.dwmsEventTime]
        mov rdx,[msLastEvent]
        mov [msLastEvent],rax
        sub rax,rdx
        stosq
        lea rax,[buff]
        stosq
        pop rdi

; output results

;       lea r8,[va_list]
        lea rdx,[_format]
;       mov rcx,[.output]
        call [wvsprintfW]

        mov rcx,[.output]
        call [_putws]

        leave
        retn

section '.idata' import data readable writeable

  dd 0,0,0,RVA msvcrt_name,RVA msvcrt_table
  dd 0,0,0,RVA user32_name,RVA user32_table
  dd 0,0,0,0,0

  msvcrt_table:
    exit dq RVA _exit
    _putws dq RVA __putws
    dq 0

  user32_table:
    DispatchMessageW dq RVA _DispatchMessageW
    GetMessageW dq RVA _GetMessageW
    GetWindowTextW dq RVA _GetWindowTextW
    SetWinEventHook dq RVA _SetWinEventHook
    TranslateMessage dq RVA _TranslateMessage
    UnhookWinEvent dq RVA _UnhookWinEvent
    wvsprintfW dq RVA _wvsprintfW
    dq 0

  msvcrt_name db 'msvcrt',0
  user32_name db 'user32',0

  _exit db 0,0,'exit',0
  __putws db 0,0,'_putws',0

  _DispatchMessageW db 0,0,'DispatchMessageW',0
  _GetMessageW db 0,0,'GetMessageW',0
  _GetWindowTextW db 0,0,'GetWindowTextW',0
  _SetWinEventHook db 0,0,'SetWinEventHook',0
  _TranslateMessage db 0,0,'TranslateMessage',0
  _UnhookWinEvent db 0,0,'UnhookWinEvent',0
  _wvsprintfW db 0,0,'wvsprintfW',0    
References:

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwineventhook
https://docs.microsoft.com/en-us/windows/desktop/WinAuto/event-constants

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 09 Jan 2019, 02:06
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.