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

     1  //go:build darwin && cgo
     2  // +build darwin,cgo
     3  
     4  package vmmap
     5  
     6  /*
     7  
     8  #include <mach/mach.h>
     9  #include <mach/mach_vm.h>
    10  
    11  mach_port_t get_mach_task_self() {
    12  	return mach_task_self();
    13  }
    14  */
    15  import "C"
    16  import (
    17  	"fmt"
    18  	"github.com/eh-steve/goloader/mmap/mapping"
    19  	"math"
    20  	"unsafe"
    21  )
    22  
    23  func Vmmap() ([]mapping.Mapping, error) {
    24  	// TODO - could populate more stuff from vm_region_recurse_info_t and libproc (e.g. permissions etc into mappings), for now only addresses are populated
    25  	var start C.mach_vm_address_t = 0
    26  	var end C.mach_vm_address_t = math.MaxUint64
    27  	var depth C.uint32_t = 2048
    28  
    29  	var info C.vm_region_submap_info_data_64_t
    30  	var count C.mach_msg_type_number_t = C.VM_REGION_SUBMAP_INFO_COUNT_64
    31  	task := C.get_mach_task_self()
    32  
    33  	var mappings []mapping.Mapping
    34  	isFirst := true
    35  	for {
    36  		var address = start
    37  		var size C.mach_vm_size_t = 0
    38  		var depth0 = depth
    39  		var kr C.kern_return_t = C.mach_vm_region_recurse(task, &address, &size,
    40  			&depth0, (C.vm_region_recurse_info_t)(unsafe.Pointer(&info)), &count)
    41  		if kr != C.KERN_SUCCESS || address > end {
    42  			if isFirst {
    43  				if start == end {
    44  					return nil, fmt.Errorf("no virtual memory region contains address 0x%x\n", uintptr(start))
    45  				} else {
    46  					return nil, fmt.Errorf("no virtual memory region intersects 0x%x-0x%x\n", uintptr(start), uintptr(end))
    47  				}
    48  			}
    49  			break
    50  		}
    51  
    52  		isFirst = false
    53  		mappings = append(mappings, mapping.Mapping{
    54  			StartAddr: uintptr(address),
    55  			EndAddr:   uintptr(address + size),
    56  		})
    57  		start = address + size
    58  	}
    59  	return mappings, nil
    60  }