g'day,
i need some help with this problem. i need my program to receive a message or something when another app opens and closes, so that I can grab some information from it before it closes. what i tried doing was using a WH_FOREGROUNDIDLE hook, and did an enum_windows inside the hook, so I knew whether or not the other application was open, but I discovered that enum_windows doesn't work properly from inside a hook. also I tried other hooks (WH_CBT, WH_CALLWNDPROC...) but they didn't work because the window I want to hook is a child window i think. how do I do this?? Here is the code for my hook dll:
Posted on 2002-07-19 09:47:09 by Spider
i need some help with this problem. i need my program to receive a message or something when another app opens and closes, so that I can grab some information from it before it closes. what i tried doing was using a WH_FOREGROUNDIDLE hook, and did an enum_windows inside the hook, so I knew whether or not the other application was open, but I discovered that enum_windows doesn't work properly from inside a hook. also I tried other hooks (WH_CBT, WH_CALLWNDPROC...) but they didn't work because the window I want to hook is a child window i think. how do I do this?? Here is the code for my hook dll:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
include \masm32\include\debug.inc
includelib \masm32\lib\debug.lib
EnumWinsProc PROTO :DWORD,:DWORD
EnumChildWinsProc PROTO :DWORD,:DWORD
.const
WM_MOUSEHOOK equ WM_USER+6
.data?
hHook dd ?
hWnd dd ?
.data
hInstance dd 0
hWindow dd 0
hThreader dd 0
statez dd 0
hWndWordPad dd 0
sztextstring db 65 dup (0)
szWordPad db "#32771",0
szUnicode dw 30abh,51fah,51fah,0
szWordPadEdit db "Button",0
statics dd 0
.code
DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
push hInst
pop hInstance
mov eax,TRUE
ret
DllEntry Endp
MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD
pushad
;invoke CallNextHookEx,hHook,nCode,wParam,lParam
;mov edx,lParam
;assume edx:PTR CWPSTRUCT
;mov eax, [edx].hwnd
;.if eax==hWndWordPad
; PrintHex [edx].message
;.endif
;invoke PostMessage,hWnd,WM_MOUSEHOOK,eax,0
.if statez==0
call CallEnum
;PrintDec hWndWordPad
;.if hWndWordPad!=0
; ;invoke EnumChildWindows, hWndWordPad, addr EnumChildWinsProc, 0
PrintText "Enternet Loaded"
mov statez, 1
;.endif
.endif
;.if statez==1
;.endif
assume edx:nothing
popad
xor eax,eax
ret
MouseProc endp
CallEnum:
invoke EnumWindows, addr EnumWinsProc, 0
ret
InstallHook proc
pushad
invoke SetWindowsHookEx, WH_FOREGROUNDIDLE, addr MouseProc, hInstance, NULL
mov hHook,eax
popad
ret
InstallHook endp
UninstallHook proc
pushad
invoke UnhookWindowsHookEx,hHook
popad
ret
UninstallHook endp
EnumWinsProc proc haWnd :DWORD, lParam :DWORD
pushad
invoke GetClassName, haWnd, offset sztextstring, 64
PrintString sztextstring
mov edx, offset sztextstring
mov ebx, offset szWordPad
mov ecx, 64
comparestring:
mov al, [edx]
mov ah, [ebx]
cmp al, ah
jne notstring
cmp al, 0
jne notyet
cmp ah, 0
je stringisequal
notyet: inc edx
inc ebx
dec ecx
jne comparestring
notstring:
popad
mov eax, 1
ret
stringisequal:
mov eax, haWnd
mov hWndWordPad,eax
popad
xor eax, eax
ret
EnumWinsProc endp
EnumChildWinsProc proc uses ebx hWnnd :DWORD, lParam :DWORD
invoke GetClassName, hWnnd, offset sztextstring, 64
PrintString sztextstring
mov edx, offset sztextstring
mov ebx, offset szWordPadEdit
mov ecx, 64
acomparestring:
mov al, [edx]
mov ah, [ebx]
cmp al, ah
jne anotstring
cmp al, 0
jne anotyet
cmp ah, 0
je astringisequal
anotyet: inc edx
inc ebx
dec ecx
jne acomparestring
anotstring:
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov eax, 1
ret
astringisequal:
inc statics
.if statics==3
invoke GetWindowText, hWnnd, offset sztextstring, 64
PrintString sztextstring
.endif
xor ebx, ebx
xor ecx, ecx
xor edx, edx
mov eax, 1
ret
EnumChildWinsProc endp
End DllEntry
Posted on 2002-07-19 09:47:09 by Spider
If you can find the main (top level) window of the app you are watching, then use the window enumeration functions of the winapi to find the child window of interest. I think it is GetWindowParent/Child or FindWindow with some flag to say it is a child.
Regs,
Regs,
You could code a VxD under Win9x then you could receive system messages when a process is about to be created or closed. (look at sysinternal's filemon for more info).
You can also patch both CreateProcess and ExitProcess...
You can also patch both CreateProcess and ExitProcess...
List all processes with toolhelp/whatever, then waitformultipleobjects? ;P
Or install a correct r0 hook or sth.
Or install a correct r0 hook or sth.
If you're using NT/2K you might want to check out the article at
http://www.codeproject.com/threads/procmon.asp
Detecting Windows NT/2K process execution
By Ivo Ivanov
NT/2K provides a set of APIs, known as "Process Structure Routines" exported by NTOSKRNL. One of these APIs PsSetCreateProcessNotifyRoutine() offers the ability to register system-wide callback function which is called by OS each time when a new process starts, exits or is terminated.
Else in Win9x, hooking one of the APIs suggested or some appropriate service in a vxd (using VMMCall Hook_Device_Service) might work for you.
Kayaker
http://www.codeproject.com/threads/procmon.asp
Detecting Windows NT/2K process execution
By Ivo Ivanov
NT/2K provides a set of APIs, known as "Process Structure Routines" exported by NTOSKRNL. One of these APIs PsSetCreateProcessNotifyRoutine() offers the ability to register system-wide callback function which is called by OS each time when a new process starts, exits or is terminated.
Else in Win9x, hooking one of the APIs suggested or some appropriate service in a vxd (using VMMCall Hook_Device_Service) might work for you.
Kayaker
Hi,
if you're looking for a solution which works under NT and 9x as well
maybe this is what you want.
Register your application as the default "viewer" for exe files via registry.
HKLM\Software\Classes\exefile\shell\open\command\
orHCR\.exe\shell\open\command
Each time an exe-file is to be started you'll be called.
Bye Miracle
if you're looking for a solution which works under NT and 9x as well
maybe this is what you want.
Register your application as the default "viewer" for exe files via registry.
HKLM\Software\Classes\exefile\shell\open\command\
orHCR\.exe\shell\open\command
Each time an exe-file is to be started you'll be called.
Bye Miracle
Each time an exe-file is to be started you'll be called.
Bye Miracle
Wrong.
You will only catch ShellExecute like api!
oh interesting ..
surely you can point me to a solution to start an exe file
without this kind of "notification"
Waiting for reply
:)
Bye Miracle
surely you can point me to a solution to start an exe file
without this kind of "notification"
Waiting for reply
:)
Bye Miracle
oh interesting ..
surely you can point me to a solution to start an exe file
without this kind of "notification"
Waiting for reply
:)
Bye Miracle
You 'll catch all processes originally called by WinExec and ShellExecute (as they both use the shell).
Theses "notifications" are implemented as calls to CreateProcess.
CreateProcess simply *doesn't* care about the shell.
Here is a lame example I wrote in order to make you understand (Use with care : It may have unpredictable bugs :) )
I have written a programm wich overwrites the address of "MessageBoxA" in the memory of user32.dll ages ago.
It writes the address of its own function there, so all calls come to my dll instead of shell32.dll.
When my computer is ready again, I will dig it up and rewrite it for ShellExecute :)
Regards,
bAZiK
It writes the address of its own function there, so all calls come to my dll instead of shell32.dll.
When my computer is ready again, I will dig it up and rewrite it for ShellExecute :)
Regards,
bAZiK
I have written a programm wich overwrites the address of "MessageBoxA" in the memory of user32.dll ages ago.
this sounds like a LOCAL hook, writing a GLOBAL one (and in this case we need
a global hook...) is much more harder i think. but it is possible... on this board i
found dozens of posts that decribe how to bypass write-protection (file in use).
the pe manipulations should be plain simple.
but it would be much cleaner to work with the toolhelp (w9x) AND psapi (nt)
functions which allow you to create snapshots of all applications that are
currently running. you can parse your results easily and do what you want
then.
i found some good tutes about that stuff on google... check out this one
It should be rather easy doing a global hook in 9x, as DLLs are located
in the shared memory region - which NT fortunately doesn't have.
Under NT redirecting stuff globally to your code isn't exactly easy...
in the shared memory region - which NT fortunately doesn't have.
Under NT redirecting stuff globally to your code isn't exactly easy...