format PE GUI 4.0 DLL
entry dllmain

include '%fasminc%\win32a.inc'

; ------------------------------------------------
section '.sdata' data readable writeable shareable
; ------------------------------------------------
buff			rb MAX_PATH
buff2			rb MAX_PATH
buffAddr		dd ?

odsAttach		db 'DLL_PROCESS_ATTACH',0
odsDetach		db 'DLL_PROCESS_DETACH',0
odsHcbtActivate		db '--> HCBT_ACTIVATE',0
odsSetWindowLongFailed	db '-----> SetWindowLong : Failed',0
odsSetWindowLongSuccess	db '-----> SetWindowLong : Success',0

fodsWndHandle		db '>>> Window Handle : %#x',0
fodsError		db '>>> Error Code : %#x',0
fodsHcbtActivate	db '---> HCBT_ACTIVATE >>> Name : %s, HWND: %#x',0

appName			db '\notepad.exe',0

hookH			dd 0
hookFlag		dd 0			; 1 = hook, 0 = unhook
baseAddrDll		dd ?

targetWndH		dd 0			; target window handle
targetTitle		db 'Untitled - Notepad',0
targetClsName		db 'Notepad',0
targetPrevWndAddr	dd 0




; --------------------------------------
section '.code' code readable executable
; --------------------------------------

; -------------------------------------------
proc dllmain hinstDll, fdwReason, lpvReserved
; -------------------------------------------
		push	[hinstDll]
		pop	[baseAddrDll]

		cmp	[fdwReason],DLL_PROCESS_ATTACH
		je	.attach
		cmp	[fdwReason],DLL_PROCESS_DETACH
		je	.detach

	.exit:
	; ----
		mov	eax,TRUE
		ret

	.attach:
	; ------
		invoke	OutputDebugString,odsAttach
			jmp	.exit


	.detach:
	; ------
		invoke	OutputDebugString,odsDetach
			jmp	.exit
endp



; ------------------------------------------------------
proc cbtHookProc uses esi edi ebx, ncode, wparam, lparam
; ------------------------------------------------------
		cmp	[ncode],HCBT_ACTIVATE
		je	.hcbt_activate

	.exit:
	; ----
	invoke	CallNextHookEx,[hookH],[ncode],[wparam],[lparam]
		ret

	.hcbt_activate:
	; -------------
	invoke	GetModuleHandle,NULL
	invoke	GetModuleFileName,eax,buff,MAX_PATH
	cinvoke	wsprintf,buff2,fodsHcbtActivate,buff,[wparam]
	invoke	OutputDebugString,buff2
		jmp	.exit

endp



; -----------------
proc cbtHookInstall
; -----------------
	invoke	SetWindowsHookEx,WH_CBT,cbtHookProc,[baseAddrDll],0
		mov	[hookH],eax
	invoke	SetTimer,NULL,NULL,3000,findTargetTimerProc
		ret
endp



; -------------------
proc cbtHookUninstall
; -------------------
	invoke	UnhookWindowsHookEx,[hookH]
		mov	[targetWndH],0
		ret
endp



; --------------------------------------------------
proc findTargetTimerProc hwnd, umsg, idevent, dwtime
; --------------------------------------------------
	invoke	FindWindow,targetClsName,targetTitle
		cmp	eax,NULL
		je	.exit

		push	eax
		pop	[targetWndH]
	invoke	KillTimer,NULL,NULL
	invoke	SetWindowLong,[targetWndH],GWL_WNDPROC,targetWndProc
		cmp	eax,0
		je	.error

		push	eax
		pop	[targetPrevWndAddr]
	invoke	OutputDebugString,odsSetWindowLongSuccess
		jmp	.exit

	.error:
	; -----
	invoke	GetLastError
	cinvoke	wsprintf,buff,fodsError,eax
	invoke	OutputDebugString,buff
	invoke	OutputDebugString,odsSetWindowLongFailed
	
		
	.exit:
	; ----
		ret
endp

; ---------------------------------------------------------
proc targetWndProc uses esi edi ebx, hwnd,msg,wparam,lparam
; ---------------------------------------------------------
	.exit:
	; ----
	invoke	CallWindowProc,[targetPrevWndAddr],[hwnd],[msg],[wparam],[lparam]
		ret
endp


; -----------------------------------
section '.edata' export data readable
; -----------------------------------
export	'WIN32HOOK.DLL',\
	cbtHookInstall,		'cbtHookInstall',\
	cbtHookUninstall,	'cbtHookUninstall'



; ---------------------------------------------
section '.idata' import data readable writeable
; ---------------------------------------------
library	kernel32,		'kernel32.dll',\
	user32,			'user32.dll'

include '%fasminc%\api\kernel32.inc'
include '%fasminc%\api\user32.inc'



; --------------------------------------
section '.reloc' fixups data discardable
; --------------------------------------