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 }