github.com/tencent/goom@v1.0.1/internal/bytecode/memory/mwrite_windows.go (about)

     1  package memory
     2  
     3  import (
     4  	"fmt"
     5  	"syscall"
     6  	"unsafe"
     7  )
     8  
     9  // 注意: 此版本暂时不能完整支持 windows
    10  // pageExecuteReadwrite page 窗口大小
    11  const pageExecuteReadwrite = 0x40
    12  
    13  var procVirtualProtect = syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualProtect")
    14  
    15  // virtualProtect 获取 page 读写权限
    16  func virtualProtect(lpAddress uintptr, dwSize int, flNewProtect uint32, lpflOldProtect unsafe.Pointer) error {
    17  	ret, _, _ := procVirtualProtect.Call(
    18  		lpAddress,
    19  		uintptr(dwSize),
    20  		uintptr(flNewProtect),
    21  		uintptr(lpflOldProtect))
    22  	if ret == 0 {
    23  		return syscall.GetLastError()
    24  	}
    25  	return nil
    26  }
    27  
    28  // WriteTo this function is super unsafe
    29  // aww yeah
    30  // It copies a slice to a raw memory location, disabling all memory protection before doing so.
    31  func WriteTo(addr uintptr, data []byte) error {
    32  	memoryAccessLock.Lock()
    33  	defer memoryAccessLock.Unlock()
    34  
    35  	f := RawAccess(addr, len(data))
    36  
    37  	var oldPerms uint32
    38  	err := virtualProtect(addr, len(data), pageExecuteReadwrite, unsafe.Pointer(&oldPerms))
    39  	if err != nil {
    40  		panic(fmt.Errorf("access mem error: %w", err))
    41  	}
    42  	copy(f, data[:])
    43  
    44  	// VirtualProtect requires you to pass in a pointer which it can write the
    45  	// current memory protection permissions to, even if you don't want them.
    46  	var tmp uint32
    47  	return virtualProtect(addr, len(data), oldPerms, unsafe.Pointer(&tmp))
    48  }