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:


.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,
Posted on 2002-07-19 19:26:42 by James_Ladd
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...
Posted on 2002-07-19 21:58:40 by Axial
List all processes with toolhelp/whatever, then waitformultipleobjects? ;P
Or install a correct r0 hook or sth.
Posted on 2002-07-20 00:36:32 by f0dder
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
Posted on 2002-07-20 10:24:59 by 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
Posted on 2002-07-22 12:28:06 by miracle



Each time an exe-file is to be started you'll be called.

Bye Miracle


Wrong.
You will only catch ShellExecute like api!
Posted on 2002-07-22 22:13:23 by Axial
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
Posted on 2002-07-23 04:03:35 by 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 :) )
Posted on 2002-07-23 04:39:07 by Axial
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
Posted on 2002-07-23 04:52:46 by 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
Posted on 2002-07-23 06:25:41 by mob
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...
Posted on 2002-07-23 11:38:05 by f0dder