format pe gui 4.0
entry start

include '%fasminc%\win32a.inc'

LLKHF_ALTDOWN	= 0020h

section '.data' data readable writeable

  title db 'hook',0
  class db 'fasmw32',0

  hinst dd ?
  retval dd ?
  hook dd ?

  msg MSG
  wc WNDCLASS

section '.text' code readable executable
  start:
	invoke	GetModuleHandle,0
	mov	[hinst],eax
	invoke	LoadIcon,0,IDI_APPLICATION
	mov	[wc.hIcon],eax
	invoke	LoadCursor,0,IDC_ARROW
	mov	[wc.hCursor],eax
	mov	[wc.style],0
	mov	[wc.lpfnWndProc],windowproc
	mov	[wc.cbClsExtra],0
	mov	[wc.cbWndExtra],0
	push	[hinst]
	pop	[wc.hInstance]
	mov	[wc.hbrBackground],COLOR_BTNFACE+1
	mov	[wc.lpszMenuName],0
	mov	[wc.lpszClassName],class
	invoke	RegisterClass,wc
	invoke	CreateWindowEx,0,class,title,WS_VISIBLE+WS_OVERLAPPED+WS_SYSMENU,128,128,155,155,NULL,NULL,[hinst],NULL

msg_loop:
	invoke	GetMessage,msg,NULL,0,0
	or	eax,eax
	jz	end_loop
	invoke	TranslateMessage,msg
	invoke	DispatchMessage,msg
	jmp	msg_loop
  end_loop:
	invoke	ExitProcess,[msg.wParam]

proc windowproc, hwnd,wmsg,wparam,lparam
	push	esp ebx edi esi
	cmp	[wmsg],WM_CREATE
	je	wmcreate
	cmp	[wmsg],WM_DESTROY
	je	wmdestroy
  defwndproc:
	invoke	DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
	jmp	finish
  wmcreate:
	invoke	SetWindowsHookEx,WH_KEYBOARD_LL,hookproc,[hinst],0 ;all keystrokes will pass thru hookproc
	mov	[hook],eax
	xor	eax,eax
	jmp	finish
  wmdestroy:
	invoke	UnhookWindowsHookEx,[hook]
	invoke	PostQuitMessage,0
	xor	eax,eax
  finish:
	pop	esi edi ebx esp
	return
endp

proc hookproc, ncode,wp,lp
       push	ebx esi edi esp
       invoke	CallNextHookEx,[hook],[ncode],[wp],[lp] ;return keystroke to other hooks if you wish
       mov	[retval],eax
       mov	eax,[ncode]
       cmp	ax,HC_ACTION
       jne	skip
       cmp	[wp],WM_KEYDOWN
       je	which_key
       cmp	[wp],WM_SYSKEYDOWN
       jne	skip
  which_key:
       mov	eax, [lp] ;KBDLLHOOKSTRUCT
       cmp	dword [eax+4],VK_F5 ;kbdllhookstruct.vkCode
       je	disable
       cmp	dword [eax+4],VK_SPACE
       jne	skip
  disable:
       invoke	MessageBox,0,title,title,0 ;should see this?!
       or	eax,-1 ;returning -1 to disable
       jmp	finish_up
  skip:
       mov	eax,[retval]
  finish_up:
       pop	esp edi esi ebx
       return
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
	  user,'USER32.DLL'

  import kernel,\
	 GetModuleHandle,'GetModuleHandleA',\
	 ExitProcess,'ExitProcess'

  import user,\
	 RegisterClass,'RegisterClassA',\
	 CreateWindowEx,'CreateWindowExA',\
	 DefWindowProc,'DefWindowProcA',\
	 GetMessage,'GetMessageA',\
	 MessageBox,'MessageBoxA',\
	 TranslateMessage,'TranslateMessage',\
	 DispatchMessage,'DispatchMessageA',\
	 LoadCursor,'LoadCursorA',\
	 LoadMenu,'LoadMenuA',\
	 LoadIcon,'LoadIconA',\
	 PostQuitMessage,'PostQuitMessage',\
	 SetWindowsHookEx,'SetWindowsHookExA',\
	 CallNextHookEx,'CallNextHookEx',\
	 UnhookWindowsHookEx,'UnhookWindowsHookEx'

