github.com/gbl08ma/monkey@v1.1.0/replace_windows.go (about)

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