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

     1  package mmap
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/eh-steve/goloader/mmap/mapping"
     6  	"sort"
     7  	"syscall"
     8  	"unsafe"
     9  )
    10  
    11  func init() {
    12  	pageSize = uintptr(GetAllocationGranularity())
    13  }
    14  
    15  const (
    16  	MEM_COMMIT  = 0x1000
    17  	MEM_FREE    = 0x10000
    18  	MEM_RESERVE = 0x2000
    19  )
    20  
    21  const (
    22  	MEM_IMAGE   = 0x1000000
    23  	MEM_MAPPED  = 0x40000
    24  	MEM_PRIVATE = 0x20000
    25  )
    26  
    27  func getCurrentProcMaps() ([]mapping.Mapping, error) {
    28  	var mappings []mapping.Mapping
    29  
    30  	pHandle, err := syscall.GetCurrentProcess()
    31  	if err != nil {
    32  		return nil, fmt.Errorf("failed to GetCurrentProcess: %w", err)
    33  	}
    34  	info := new(MemoryBasicInformation)
    35  
    36  	addr := uintptr(0)
    37  	infoSize := unsafe.Sizeof(*info)
    38  	for {
    39  		infoSize, err = VirtualQueryEx(pHandle, addr, info)
    40  		if err != nil {
    41  			return nil, fmt.Errorf("failed to VirtualQueryEx: %w", err)
    42  		}
    43  		if infoSize != unsafe.Sizeof(*info) {
    44  			break
    45  		}
    46  
    47  		if info.State != MEM_FREE {
    48  			mappings = append(mappings, mapping.Mapping{
    49  				StartAddr:   addr,
    50  				EndAddr:     addr + info.RegionSize,
    51  				ReadPerm:    info.AllocationProtect&syscall.PAGE_EXECUTE_READWRITE != 0 || info.AllocationProtect&syscall.PAGE_EXECUTE_READ != 0 || info.AllocationProtect&syscall.PAGE_READWRITE != 0 || info.AllocationProtect&syscall.PAGE_READONLY != 0,
    52  				WritePerm:   info.AllocationProtect&syscall.PAGE_EXECUTE_READWRITE != 0 || info.AllocationProtect&syscall.PAGE_EXECUTE_WRITECOPY != 0 || info.AllocationProtect&syscall.PAGE_READWRITE != 0 || info.AllocationProtect&syscall.PAGE_WRITECOPY != 0,
    53  				ExecutePerm: info.AllocationProtect&syscall.PAGE_EXECUTE_READWRITE != 0 || info.AllocationProtect&syscall.PAGE_EXECUTE_READ != 0 || info.AllocationProtect&syscall.PAGE_EXECUTE_WRITECOPY != 0,
    54  				PrivatePerm: info.State&MEM_PRIVATE != 0,
    55  			})
    56  		}
    57  		addr += info.RegionSize
    58  	}
    59  	sort.Slice(mappings, func(i, j int) bool {
    60  		return mappings[i].StartAddr < mappings[j].StartAddr
    61  	})
    62  
    63  	err = syscall.CloseHandle(pHandle)
    64  	if err != nil {
    65  		return nil, fmt.Errorf("failed to CloseHandle: %w", err)
    66  	}
    67  	return mappings, nil
    68  }