github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/mmap/mmap_windows.go (about)

     1  //go:build windows
     2  // +build windows
     3  
     4  package mmap
     5  
     6  import (
     7  	"os"
     8  	"reflect"
     9  	"syscall"
    10  	"unsafe"
    11  )
    12  
    13  func MakeThreadJITCodeExecutable(ptr uintptr, len int) {
    14  }
    15  
    16  func Mmap(size int) ([]byte, error) {
    17  	return AcquireMapping(size, mmapCode)
    18  }
    19  
    20  func MmapData(size int) ([]byte, error) {
    21  	return AcquireMapping(size, mmapData)
    22  }
    23  
    24  func mmapCode(size int, targetAddr uintptr) ([]byte, error) {
    25  	sizelo := uint32(size >> 32)
    26  	sizehi := uint32(size) & 0xFFFFFFFF
    27  	h, errno := syscall.CreateFileMapping(syscall.InvalidHandle, nil,
    28  		syscall.PAGE_EXECUTE_READWRITE, sizelo, sizehi, nil)
    29  	if h == 0 {
    30  		return nil, os.NewSyscallError("CreateFileMapping", errno)
    31  	}
    32  
    33  	addr, errno := MapViewOfFileEx(h,
    34  		syscall.FILE_MAP_READ|syscall.FILE_MAP_WRITE|syscall.FILE_MAP_EXECUTE,
    35  		0, 0, uintptr(size), targetAddr)
    36  	if addr == 0 {
    37  		return nil, os.NewSyscallError("MapViewOfFileEx", errno)
    38  	}
    39  
    40  	if err := syscall.CloseHandle(h); err != nil {
    41  		return nil, os.NewSyscallError("CloseHandle", err)
    42  	}
    43  
    44  	var header reflect.SliceHeader
    45  	header.Data = addr
    46  	header.Len = size
    47  	header.Cap = size
    48  	b := *(*[]byte)(unsafe.Pointer(&header))
    49  
    50  	return b, nil
    51  }
    52  
    53  func mmapData(size int, targetAddr uintptr) ([]byte, error) {
    54  	sizelo := uint32(size >> 32)
    55  	sizehi := uint32(size) & 0xFFFFFFFF
    56  	h, errno := syscall.CreateFileMapping(syscall.InvalidHandle, nil,
    57  		syscall.PAGE_READWRITE, sizelo, sizehi, nil)
    58  	if h == 0 {
    59  		return nil, os.NewSyscallError("CreateFileMapping", errno)
    60  	}
    61  
    62  	addr, errno := MapViewOfFileEx(h,
    63  		syscall.FILE_MAP_READ|syscall.FILE_MAP_WRITE,
    64  		0, 0, uintptr(size), targetAddr)
    65  	if addr == 0 {
    66  		return nil, os.NewSyscallError("MapViewOfFileEx", errno)
    67  	}
    68  
    69  	if err := syscall.CloseHandle(h); err != nil {
    70  		return nil, os.NewSyscallError("CloseHandle", err)
    71  	}
    72  
    73  	var header reflect.SliceHeader
    74  	header.Data = addr
    75  	header.Len = size
    76  	header.Cap = size
    77  	b := *(*[]byte)(unsafe.Pointer(&header))
    78  
    79  	return b, nil
    80  }
    81  
    82  func Munmap(b []byte) error {
    83  	addr := (uintptr)(unsafe.Pointer(&b[0]))
    84  	if err := syscall.UnmapViewOfFile(addr); err != nil {
    85  		return os.NewSyscallError("UnmapViewOfFile", err)
    86  	}
    87  	return nil
    88  }