;tested on nt/xp systems only
;thanks to mike.dld for his help fixing hookproc

format pe gui 4.0
entry start

include '%fasminc%\win32a.inc'

section '.data' data readable writeable

  _title db 'trainer',0
  _class db 'fasmw32',0
  _class_btn db 'BUTTON',0
  _btn_info db 'Info',0
  _btn_about db 'About',0

  hinstance dd ?
  mainhwnd dd ?
  hhook dd ?
  hwnd_info dd ?
  hwnd_about dd ?

  _caption db 'Brood War',0

  _info  db "Use:",0Ah
	 db "=========================",0Ah
	 db "Press the respective function key to your",0Ah
	 db "player number.",0Ah
	 db " ",0Ah
	 db "eg.",0Ah
	 db "To give 5k of Mineral and Gas to player 1",0Ah
	 db "press F1, to player 2 use F2 and so on...",0Ah
	 db "=========================",0Ah
	 db "This trainer was written to be used on 4x4",0Ah
	 db "games on The Hunters and may not work",0Ah
	 db "with other type/map.",0Ah
	  db "=========================",0Ah
	 db "Dont use this to cheat on BNET or it will",0Ah
	 db "crash the game...enjoy!",0

  _about db "BroodWar 1.08 Trainer - MultiPlayer",0Ah
	 db "======================",0Ah
	 db "100% ASM  = Simple + Small + Fast",0Ah
	 db " ",0Ah
	 db "            Dont like it?Bite Me!",0Ah
	 db " ",0Ah
	 db "                                              By Zani",0

  buffer rd 4

  pid dd ?
  hprocess dd ?

  _success db 'success',0
  _no_window db 'window not found',0
  _no_pid db 'process id error',0
  _err_open db 'open process error',0
  _err_read db 'read process error',0
  _err_write db 'write process error',0

  msg MSG
  wc WNDCLASS

section '.code' code readable executable
  start:
	invoke	GetModuleHandle,0
	mov	[hinstance],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],wndproc
	mov	[wc.cbClsExtra],0
	mov	[wc.cbWndExtra],0
	push	[hinstance]
	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_MINIMIZEBOX+WS_SYSMENU,128,128,182,58,NULL,NULL,[hinstance],NULL
	mov	[mainhwnd],eax
	invoke	CreateWindowEx,0,_class_btn,_btn_info,WS_VISIBLE+WS_CHILD+BS_PUSHBUTTON,5,5,80,20,[mainhwnd],0,[hinstance],0
	mov	[hwnd_info],eax
	invoke	CreateWindowEx,0,_class_btn,_btn_about,WS_VISIBLE+WS_CHILD,90,5,80,20,[mainhwnd],0,[hinstance],0
	mov	[hwnd_about],eax
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 wndproc,hwnd,wmsg,wparam,lparam
	push	esp ebx edi esi
	cmp	[wmsg],WM_CREATE
	jz	wmcreate
	cmp	[wmsg],WM_COMMAND
	jz	wmcommand
	cmp	[wmsg],WM_DESTROY
	jz	wmdestroy
  defwndproc:
	invoke	DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
	jmp	finish
  wmcreate:
	invoke	SetWindowsHookEx,WH_KEYBOARD,hookproc,[hinstance],0
	mov	[hhook],eax
	xor	eax,eax
	jmp	finish
  wmcommand:
	mov	eax,[lparam]
	cmp	eax,[hwnd_info]
	jz	display_info
	cmp	eax,[hwnd_about]
	jz	display_about
	jmp	finish
  display_info:
	invoke	MessageBox,[mainhwnd],_info,_title,0
	jmp	finish
  display_about:
	invoke	MessageBox,[mainhwnd],_about,_title,0
	jmp	finish
  wmdestroy:
	invoke	UnhookWindowsHookEx,[hhook]
	invoke	PostQuitMessage,0
	xor	eax,eax
  finish:
	pop	esi edi ebx esp
	return
endp

proc hookproc,ncode,wp,lp
       push	ebx esi edi
       mov	eax,[ncode]
       cmp	ax,HC_ACTION
       jnz	.clean_up
       bt	[lp],31
       jc	.clean_up
  .read_key:
       mov	eax,[wp]
       cmp	al,VK_F1
       jz	.f1_pressed
       cmp	al,VK_F2
       jz	.f2_pressed
       cmp	al,VK_F3
       jz	.f3_pressed
       cmp	al,VK_F4
       jz	.f4_pressed
       cmp	al,VK_F5
       jz	.f5_pressed
       cmp	al,VK_F6
       jz	.f6_pressed
       cmp	al,VK_F7
       jz	.f7_pressed
       cmp	al,VK_F8
       jz	.f8_pressed
       jmp	.clean_up
  .f1_pressed:
       stdcall	addval,_caption,508718h,buffer,5000
       stdcall	addval,_caption,508748h,buffer,5000
       jmp	.clean_up
  .f2_pressed:
       stdcall	addval,_caption,50871Ch,buffer,5000
       stdcall	addval,_caption,50874Ch,buffer,5000
       jmp	.clean_up
  .f3_pressed:
       stdcall	addval,_caption,508720h,buffer,5000
       stdcall	addval,_caption,508750h,buffer,5000
       jmp	.clean_up
  .f4_pressed:
       stdcall	addval,_caption,508724h,buffer,5000
       stdcall	addval,_caption,508754h,buffer,5000
       jmp	.clean_up
  .f5_pressed:
       stdcall	addval,_caption,508728h,buffer,5000
       stdcall	addval,_caption,508758h,buffer,5000
       jmp	.clean_up
  .f6_pressed:
       stdcall	addval,_caption,50872Ch,buffer,5000
       stdcall	addval,_caption,50875Ch,buffer,5000
       jmp	.clean_up
  .f7_pressed:
       stdcall	addval,_caption,508730h,buffer,5000
       stdcall	addval,_caption,508760h,buffer,5000
       jmp	.clean_up
  .f8_pressed:
       stdcall	addval,_caption,508734h,buffer,5000
       stdcall	addval,_caption,508764h,buffer,5000
  .clean_up:
       invoke	CallNextHookEx,[hhook],[ncode],[wp],[lp]
       pop	edi esi ebx
       return
endp

proc addval,caption,baseaddr,temp,to_add
	invoke	FindWindow,0,[caption]
	push	eax
	or	eax,eax
	jz	.window_not_found
	pop	eax
	invoke	GetWindowThreadProcessId,eax,pid
	or	eax,eax
	jz	.pid_error
	invoke	OpenProcess,PROCESS_ALL_ACCESS,0,[pid]
	mov	[hprocess],eax
	or	eax,eax
	jz	.err_open
	invoke	ReadProcessMemory,[hprocess],[baseaddr],[temp],4,pid
	or	eax,eax
	jz	.err_read
	mov	ecx,[to_add]
	mov	ebx,[temp]
	add	[ebx],ecx
	invoke	WriteProcessMemory,[hprocess],[baseaddr],[temp],4,pid
	or	eax,eax
	jz	.err_write
	invoke	CloseHandle,[hprocess]
	invoke	MessageBox,0,_success,_success,0
	jmp	.done
  .window_not_found:
	invoke	MessageBox,0,_no_window,_no_window,0
	jmp	.done
  .pid_error:
	invoke	MessageBox,0,_no_pid,_no_pid,0
	jmp	.done
  .err_open:
	invoke	MessageBox,0,_err_open,_err_open,0
	jmp	.done
  .err_read:
	invoke	MessageBox,0,_err_read,_err_read,0
	jmp	.done
  .err_write:
	invoke	MessageBox,0,_err_write,_err_write,0
  .done:
	return
endp

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\
	  user32,'USER32.DLL'

  include '%fasminc%\apia\kernel32.inc'
  include '%fasminc%\apia\user32.inc'



