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 }