replace_windows.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package monkey
  2. import (
  3. "syscall"
  4. "unsafe"
  5. )
  6. const PAGE_EXECUTE_READWRITE = 0x40
  7. var procVirtualProtect = syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualProtect")
  8. func virtualProtect(lpAddress uintptr, dwSize int, flNewProtect uint32, lpflOldProtect unsafe.Pointer) error {
  9. ret, _, _ := procVirtualProtect.Call(
  10. lpAddress,
  11. uintptr(dwSize),
  12. uintptr(flNewProtect),
  13. uintptr(lpflOldProtect))
  14. if ret == 0 {
  15. return syscall.GetLastError()
  16. }
  17. return nil
  18. }
  19. // this function is super unsafe
  20. // aww yeah
  21. // It copies a slice to a raw memory location, disabling all memory protection before doing so.
  22. func copyToLocation(location uintptr, data []byte) {
  23. f := rawMemoryAccess(location, len(data))
  24. var oldPerms uint32
  25. err := virtualProtect(location, len(data), PAGE_EXECUTE_READWRITE, unsafe.Pointer(&oldPerms))
  26. if err != nil {
  27. panic(err)
  28. }
  29. copy(f, data[:])
  30. // VirtualProtect requires you to pass in a pointer which it can write the
  31. // current memory protection permissions to, even if you don't want them.
  32. var tmp uint32
  33. err = virtualProtect(location, len(data), oldPerms, unsafe.Pointer(&tmp))
  34. if err != nil {
  35. panic(err)
  36. }
  37. }