-
-
Save dlevi309/28bdb2d4a2960d81d3df69aed8537bd6 to your computer and use it in GitHub Desktop.
A simple vmmap implementation for macOS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _LIBPROC_H_ | |
#define _LIBPROC_H_ | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <sys/cdefs.h> | |
#include <sys/mount.h> | |
#include <sys/param.h> | |
#include <sys/resource.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <sys/proc_info.h> | |
#include <Availability.h> | |
#define PROC_LISTPIDSPATH_PATH_IS_VOLUME 1 | |
#define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY 2 | |
__BEGIN_DECLS | |
int proc_listpidspath(uint32_t type, | |
uint32_t typeinfo, | |
const char *path, | |
uint32_t pathflags, | |
void *buffer, | |
int buffersize); | |
int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize); | |
int proc_listallpids(void *buffer, int buffersize); | |
int proc_listpgrppids(pid_t pgrpid, void *buffer, int buffersize); | |
int proc_listchildpids(pid_t ppid, void *buffer, int buffersize); | |
int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize); | |
int proc_pidfdinfo(int pid, int fd, int flavor, void *buffer, int buffersize); | |
int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize); | |
int proc_name(int pid, void *buffer, uint32_t buffersize); | |
int proc_regionfilename(int pid, uint64_t address, void *buffer, uint32_t buffersize); | |
int proc_kmsgbuf(void *buffer, uint32_t buffersize); | |
int proc_pidpath(int pid, void *buffer, uint32_t buffersize); | |
int proc_libversion(int *major, int *minor); | |
int proc_pid_rusage(int pid, int flavor, rusage_info_t *buffer); | |
#define PROC_SETPC_NONE 0 | |
#define PROC_SETPC_THROTTLEMEM 1 | |
#define PROC_SETPC_SUSPEND 2 | |
#define PROC_SETPC_TERMINATE 3 | |
int proc_setpcontrol(const int control); | |
int proc_setpcontrol(const int control); | |
int proc_track_dirty(pid_t pid, uint32_t flags); | |
int proc_set_dirty(pid_t pid, bool dirty); | |
int proc_get_dirty(pid_t pid, uint32_t *flags); | |
int proc_clear_dirty(pid_t pid, uint32_t flags); | |
int proc_terminate(pid_t pid, int *sig); | |
#ifdef PRIVATE | |
#include <sys/event.h> | |
int proc_list_uptrs(pid_t pid, uint64_t *buffer, uint32_t buffersize); | |
int proc_list_dynkqueueids(int pid, kqueue_id_t *buf, uint32_t bufsz); | |
int proc_piddynkqueueinfo(int pid, int flavor, kqueue_id_t kq_id, void *buffer, | |
int buffersize); | |
#endif /* PRIVATE */ | |
int proc_udata_info(int pid, int flavor, void *buffer, int buffersize); | |
__END_DECLS | |
#endif /*_LIBPROC_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _mach_vm_user_ | |
#define _mach_vm_user_ | |
/* Module mach_vm */ | |
#include <string.h> | |
#include <mach/ndr.h> | |
#include <mach/boolean.h> | |
#include <mach/kern_return.h> | |
#include <mach/notify.h> | |
#include <mach/mach_types.h> | |
#include <mach/message.h> | |
#include <mach/mig_errors.h> | |
#include <mach/port.h> | |
/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ | |
#if defined(__has_include) | |
#if __has_include(<mach/mig_strncpy_zerofill_support.h>) | |
#ifndef USING_MIG_STRNCPY_ZEROFILL | |
#define USING_MIG_STRNCPY_ZEROFILL | |
#endif | |
#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ | |
#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ | |
#endif /* __has_include(<mach/mig_strncpy_zerofill_support.h>) */ | |
#endif /* __has_include */ | |
/* END MIG_STRNCPY_ZEROFILL CODE */ | |
#ifdef AUTOTEST | |
#ifndef FUNCTION_PTR_T | |
#define FUNCTION_PTR_T | |
typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); | |
typedef struct { | |
char *name; | |
function_ptr_t function; | |
} function_table_entry; | |
typedef function_table_entry *function_table_t; | |
#endif /* FUNCTION_PTR_T */ | |
#endif /* AUTOTEST */ | |
#ifndef mach_vm_MSG_COUNT | |
#define mach_vm_MSG_COUNT 21 | |
#endif /* mach_vm_MSG_COUNT */ | |
#include <mach/std_types.h> | |
#include <mach/mig.h> | |
#include <mach/mig.h> | |
#include <mach/mach_types.h> | |
#include <mach_debug/mach_debug_types.h> | |
#ifdef __BeforeMigUserHeader | |
__BeforeMigUserHeader | |
#endif /* __BeforeMigUserHeader */ | |
#include <sys/cdefs.h> | |
__BEGIN_DECLS | |
/* Routine mach_vm_allocate */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_allocate | |
( | |
vm_map_t target, | |
mach_vm_address_t *address, | |
mach_vm_size_t size, | |
int flags | |
); | |
/* Routine mach_vm_deallocate */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_deallocate | |
( | |
vm_map_t target, | |
mach_vm_address_t address, | |
mach_vm_size_t size | |
); | |
/* Routine mach_vm_protect */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_protect | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
boolean_t set_maximum, | |
vm_prot_t new_protection | |
); | |
/* Routine mach_vm_inherit */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_inherit | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
vm_inherit_t new_inheritance | |
); | |
/* Routine mach_vm_read */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_read | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
vm_offset_t *data, | |
mach_msg_type_number_t *dataCnt | |
); | |
/* Routine mach_vm_read_list */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_read_list | |
( | |
vm_map_t target_task, | |
mach_vm_read_entry_t data_list, | |
natural_t count | |
); | |
/* Routine mach_vm_write */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_write | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
vm_offset_t data, | |
mach_msg_type_number_t dataCnt | |
); | |
/* Routine mach_vm_copy */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_copy | |
( | |
vm_map_t target_task, | |
mach_vm_address_t source_address, | |
mach_vm_size_t size, | |
mach_vm_address_t dest_address | |
); | |
/* Routine mach_vm_read_overwrite */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_read_overwrite | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
mach_vm_address_t data, | |
mach_vm_size_t *outsize | |
); | |
/* Routine mach_vm_msync */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_msync | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
vm_sync_t sync_flags | |
); | |
/* Routine mach_vm_behavior_set */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_behavior_set | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
vm_behavior_t new_behavior | |
); | |
/* Routine mach_vm_map */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_map | |
( | |
vm_map_t target_task, | |
mach_vm_address_t *address, | |
mach_vm_size_t size, | |
mach_vm_offset_t mask, | |
int flags, | |
mem_entry_name_port_t object, | |
memory_object_offset_t offset, | |
boolean_t copy, | |
vm_prot_t cur_protection, | |
vm_prot_t max_protection, | |
vm_inherit_t inheritance | |
); | |
/* Routine mach_vm_machine_attribute */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_machine_attribute | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
mach_vm_size_t size, | |
vm_machine_attribute_t attribute, | |
vm_machine_attribute_val_t *value | |
); | |
/* Routine mach_vm_remap */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_remap | |
( | |
vm_map_t target_task, | |
mach_vm_address_t *target_address, | |
mach_vm_size_t size, | |
mach_vm_offset_t mask, | |
int flags, | |
vm_map_t src_task, | |
mach_vm_address_t src_address, | |
boolean_t copy, | |
vm_prot_t *cur_protection, | |
vm_prot_t *max_protection, | |
vm_inherit_t inheritance | |
); | |
/* Routine mach_vm_page_query */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_page_query | |
( | |
vm_map_t target_map, | |
mach_vm_offset_t offset, | |
integer_t *disposition, | |
integer_t *ref_count | |
); | |
/* Routine mach_vm_region_recurse */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_region_recurse | |
( | |
vm_map_t target_task, | |
mach_vm_address_t *address, | |
mach_vm_size_t *size, | |
natural_t *nesting_depth, | |
vm_region_recurse_info_t info, | |
mach_msg_type_number_t *infoCnt | |
); | |
/* Routine mach_vm_region */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_region | |
( | |
vm_map_t target_task, | |
mach_vm_address_t *address, | |
mach_vm_size_t *size, | |
vm_region_flavor_t flavor, | |
vm_region_info_t info, | |
mach_msg_type_number_t *infoCnt, | |
mach_port_t *object_name | |
); | |
/* Routine _mach_make_memory_entry */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t _mach_make_memory_entry | |
( | |
vm_map_t target_task, | |
memory_object_size_t *size, | |
memory_object_offset_t offset, | |
vm_prot_t permission, | |
mem_entry_name_port_t *object_handle, | |
mem_entry_name_port_t parent_handle | |
); | |
/* Routine mach_vm_purgable_control */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_purgable_control | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
vm_purgable_t control, | |
int *state | |
); | |
/* Routine mach_vm_page_info */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_page_info | |
( | |
vm_map_t target_task, | |
mach_vm_address_t address, | |
vm_page_info_flavor_t flavor, | |
vm_page_info_t info, | |
mach_msg_type_number_t *infoCnt | |
); | |
/* Routine mach_vm_page_range_query */ | |
#ifdef mig_external | |
mig_external | |
#else | |
extern | |
#endif /* mig_external */ | |
kern_return_t mach_vm_page_range_query | |
( | |
vm_map_t target_map, | |
mach_vm_offset_t address, | |
mach_vm_size_t size, | |
mach_vm_address_t dispositions, | |
mach_vm_size_t *dispositions_count | |
); | |
__END_DECLS | |
/********************** Caution **************************/ | |
/* The following data types should be used to calculate */ | |
/* maximum message sizes only. The actual message may be */ | |
/* smaller, and the position of the arguments within the */ | |
/* message layout may vary from what is presented here. */ | |
/* For example, if any of the arguments are variable- */ | |
/* sized, and less than the maximum is sent, the data */ | |
/* will be packed tight in the actual message to reduce */ | |
/* the presence of holes. */ | |
/********************** Caution **************************/ | |
/* typedefs for all requests */ | |
#ifndef __Request__mach_vm_subsystem__defined | |
#define __Request__mach_vm_subsystem__defined | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
int flags; | |
} __Request__mach_vm_allocate_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
} __Request__mach_vm_deallocate_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
boolean_t set_maximum; | |
vm_prot_t new_protection; | |
} __Request__mach_vm_protect_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
vm_inherit_t new_inheritance; | |
} __Request__mach_vm_inherit_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
} __Request__mach_vm_read_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_read_entry_t data_list; | |
natural_t count; | |
} __Request__mach_vm_read_list_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_ool_descriptor_t data; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_msg_type_number_t dataCnt; | |
} __Request__mach_vm_write_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t source_address; | |
mach_vm_size_t size; | |
mach_vm_address_t dest_address; | |
} __Request__mach_vm_copy_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
mach_vm_address_t data; | |
} __Request__mach_vm_read_overwrite_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
vm_sync_t sync_flags; | |
} __Request__mach_vm_msync_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
vm_behavior_t new_behavior; | |
} __Request__mach_vm_behavior_set_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_port_descriptor_t object; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
mach_vm_offset_t mask; | |
int flags; | |
memory_object_offset_t offset; | |
boolean_t copy; | |
vm_prot_t cur_protection; | |
vm_prot_t max_protection; | |
vm_inherit_t inheritance; | |
} __Request__mach_vm_map_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
vm_machine_attribute_t attribute; | |
vm_machine_attribute_val_t value; | |
} __Request__mach_vm_machine_attribute_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_port_descriptor_t src_task; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
mach_vm_address_t target_address; | |
mach_vm_size_t size; | |
mach_vm_offset_t mask; | |
int flags; | |
mach_vm_address_t src_address; | |
boolean_t copy; | |
vm_inherit_t inheritance; | |
} __Request__mach_vm_remap_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_offset_t offset; | |
} __Request__mach_vm_page_query_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
natural_t nesting_depth; | |
mach_msg_type_number_t infoCnt; | |
} __Request__mach_vm_region_recurse_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
vm_region_flavor_t flavor; | |
mach_msg_type_number_t infoCnt; | |
} __Request__mach_vm_region_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_port_descriptor_t parent_handle; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
memory_object_size_t size; | |
memory_object_offset_t offset; | |
vm_prot_t permission; | |
} __Request___mach_make_memory_entry_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
vm_purgable_t control; | |
int state; | |
} __Request__mach_vm_purgable_control_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
vm_page_info_flavor_t flavor; | |
mach_msg_type_number_t infoCnt; | |
} __Request__mach_vm_page_info_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
mach_vm_offset_t address; | |
mach_vm_size_t size; | |
mach_vm_address_t dispositions; | |
mach_vm_size_t dispositions_count; | |
} __Request__mach_vm_page_range_query_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#endif /* !__Request__mach_vm_subsystem__defined */ | |
/* union of all requests */ | |
#ifndef __RequestUnion__mach_vm_subsystem__defined | |
#define __RequestUnion__mach_vm_subsystem__defined | |
union __RequestUnion__mach_vm_subsystem { | |
__Request__mach_vm_allocate_t Request_mach_vm_allocate; | |
__Request__mach_vm_deallocate_t Request_mach_vm_deallocate; | |
__Request__mach_vm_protect_t Request_mach_vm_protect; | |
__Request__mach_vm_inherit_t Request_mach_vm_inherit; | |
__Request__mach_vm_read_t Request_mach_vm_read; | |
__Request__mach_vm_read_list_t Request_mach_vm_read_list; | |
__Request__mach_vm_write_t Request_mach_vm_write; | |
__Request__mach_vm_copy_t Request_mach_vm_copy; | |
__Request__mach_vm_read_overwrite_t Request_mach_vm_read_overwrite; | |
__Request__mach_vm_msync_t Request_mach_vm_msync; | |
__Request__mach_vm_behavior_set_t Request_mach_vm_behavior_set; | |
__Request__mach_vm_map_t Request_mach_vm_map; | |
__Request__mach_vm_machine_attribute_t Request_mach_vm_machine_attribute; | |
__Request__mach_vm_remap_t Request_mach_vm_remap; | |
__Request__mach_vm_page_query_t Request_mach_vm_page_query; | |
__Request__mach_vm_region_recurse_t Request_mach_vm_region_recurse; | |
__Request__mach_vm_region_t Request_mach_vm_region; | |
__Request___mach_make_memory_entry_t Request__mach_make_memory_entry; | |
__Request__mach_vm_purgable_control_t Request_mach_vm_purgable_control; | |
__Request__mach_vm_page_info_t Request_mach_vm_page_info; | |
__Request__mach_vm_page_range_query_t Request_mach_vm_page_range_query; | |
}; | |
#endif /* !__RequestUnion__mach_vm_subsystem__defined */ | |
/* typedefs for all replies */ | |
#ifndef __Reply__mach_vm_subsystem__defined | |
#define __Reply__mach_vm_subsystem__defined | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_address_t address; | |
} __Reply__mach_vm_allocate_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_deallocate_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_protect_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_inherit_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_ool_descriptor_t data; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
mach_msg_type_number_t dataCnt; | |
} __Reply__mach_vm_read_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_read_entry_t data_list; | |
} __Reply__mach_vm_read_list_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_write_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_copy_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_size_t outsize; | |
} __Reply__mach_vm_read_overwrite_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_msync_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
} __Reply__mach_vm_behavior_set_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_address_t address; | |
} __Reply__mach_vm_map_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
vm_machine_attribute_val_t value; | |
} __Reply__mach_vm_machine_attribute_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_address_t target_address; | |
vm_prot_t cur_protection; | |
vm_prot_t max_protection; | |
} __Reply__mach_vm_remap_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
integer_t disposition; | |
integer_t ref_count; | |
} __Reply__mach_vm_page_query_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
natural_t nesting_depth; | |
mach_msg_type_number_t infoCnt; | |
int info[19]; | |
} __Reply__mach_vm_region_recurse_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_port_descriptor_t object_name; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
mach_vm_address_t address; | |
mach_vm_size_t size; | |
mach_msg_type_number_t infoCnt; | |
int info[10]; | |
} __Reply__mach_vm_region_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
/* start of the kernel processed data */ | |
mach_msg_body_t msgh_body; | |
mach_msg_port_descriptor_t object_handle; | |
/* end of the kernel processed data */ | |
NDR_record_t NDR; | |
memory_object_size_t size; | |
} __Reply___mach_make_memory_entry_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
int state; | |
} __Reply__mach_vm_purgable_control_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_msg_type_number_t infoCnt; | |
int info[32]; | |
} __Reply__mach_vm_page_info_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#ifdef __MigPackStructs | |
#pragma pack(4) | |
#endif | |
typedef struct { | |
mach_msg_header_t Head; | |
NDR_record_t NDR; | |
kern_return_t RetCode; | |
mach_vm_size_t dispositions_count; | |
} __Reply__mach_vm_page_range_query_t __attribute__((unused)); | |
#ifdef __MigPackStructs | |
#pragma pack() | |
#endif | |
#endif /* !__Reply__mach_vm_subsystem__defined */ | |
/* union of all replies */ | |
#ifndef __ReplyUnion__mach_vm_subsystem__defined | |
#define __ReplyUnion__mach_vm_subsystem__defined | |
union __ReplyUnion__mach_vm_subsystem { | |
__Reply__mach_vm_allocate_t Reply_mach_vm_allocate; | |
__Reply__mach_vm_deallocate_t Reply_mach_vm_deallocate; | |
__Reply__mach_vm_protect_t Reply_mach_vm_protect; | |
__Reply__mach_vm_inherit_t Reply_mach_vm_inherit; | |
__Reply__mach_vm_read_t Reply_mach_vm_read; | |
__Reply__mach_vm_read_list_t Reply_mach_vm_read_list; | |
__Reply__mach_vm_write_t Reply_mach_vm_write; | |
__Reply__mach_vm_copy_t Reply_mach_vm_copy; | |
__Reply__mach_vm_read_overwrite_t Reply_mach_vm_read_overwrite; | |
__Reply__mach_vm_msync_t Reply_mach_vm_msync; | |
__Reply__mach_vm_behavior_set_t Reply_mach_vm_behavior_set; | |
__Reply__mach_vm_map_t Reply_mach_vm_map; | |
__Reply__mach_vm_machine_attribute_t Reply_mach_vm_machine_attribute; | |
__Reply__mach_vm_remap_t Reply_mach_vm_remap; | |
__Reply__mach_vm_page_query_t Reply_mach_vm_page_query; | |
__Reply__mach_vm_region_recurse_t Reply_mach_vm_region_recurse; | |
__Reply__mach_vm_region_t Reply_mach_vm_region; | |
__Reply___mach_make_memory_entry_t Reply__mach_make_memory_entry; | |
__Reply__mach_vm_purgable_control_t Reply_mach_vm_purgable_control; | |
__Reply__mach_vm_page_info_t Reply_mach_vm_page_info; | |
__Reply__mach_vm_page_range_query_t Reply_mach_vm_page_range_query; | |
}; | |
#endif /* !__RequestUnion__mach_vm_subsystem__defined */ | |
#ifndef subsystem_to_name_map_mach_vm | |
#define subsystem_to_name_map_mach_vm \ | |
{ "mach_vm_allocate", 4800 },\ | |
{ "mach_vm_deallocate", 4801 },\ | |
{ "mach_vm_protect", 4802 },\ | |
{ "mach_vm_inherit", 4803 },\ | |
{ "mach_vm_read", 4804 },\ | |
{ "mach_vm_read_list", 4805 },\ | |
{ "mach_vm_write", 4806 },\ | |
{ "mach_vm_copy", 4807 },\ | |
{ "mach_vm_read_overwrite", 4808 },\ | |
{ "mach_vm_msync", 4809 },\ | |
{ "mach_vm_behavior_set", 4810 },\ | |
{ "mach_vm_map", 4811 },\ | |
{ "mach_vm_machine_attribute", 4812 },\ | |
{ "mach_vm_remap", 4813 },\ | |
{ "mach_vm_page_query", 4814 },\ | |
{ "mach_vm_region_recurse", 4815 },\ | |
{ "mach_vm_region", 4816 },\ | |
{ "_mach_make_memory_entry", 4817 },\ | |
{ "mach_vm_purgable_control", 4818 },\ | |
{ "mach_vm_page_info", 4819 },\ | |
{ "mach_vm_page_range_query", 4820 } | |
#endif | |
#ifdef __AfterMigUserHeader | |
__AfterMigUserHeader | |
#endif /* __AfterMigUserHeader */ | |
#endif /* _mach_vm_user_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Brandon Azad (@_bazad) | |
#include <assert.h> | |
#include <errno.h> | |
#include <mach/mach.h> | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#if defined(__x86_64__) | |
#include <libproc.h> | |
#include <mach/mach_vm.h> | |
#endif | |
#if defined(__arm64__) | |
#include "libproc.h" | |
#include "mach_vm.h" | |
#endif | |
static void | |
format_display_size(char buf[5], uint64_t size) { | |
const char scale[] = { 'B', 'K', 'M', 'G', 'T', 'P', 'E' }; | |
double display_size = size; | |
unsigned scale_index = 0; | |
while (display_size >= 999.5) { | |
display_size /= 1024; | |
scale_index++; | |
} | |
assert(scale_index < sizeof(scale) / sizeof(scale[0])); | |
int precision = 0; | |
if (display_size < 9.95 && display_size - (float)((int)display_size) > 0) { | |
precision = 1; | |
} | |
int len = snprintf(buf, 5, "%.*f%c", precision, display_size, scale[scale_index]); | |
assert(len > 0 && len < 5); | |
} | |
static void | |
format_memory_protection(char buf[4], int prot) { | |
int len = snprintf(buf, 4, "%c%c%c", | |
(prot & VM_PROT_READ ? 'r' : '-'), | |
(prot & VM_PROT_WRITE ? 'w' : '-'), | |
(prot & VM_PROT_EXECUTE ? 'x' : '-')); | |
assert(len == 3); | |
} | |
static const char * | |
share_mode_name(unsigned char share_mode) { | |
switch (share_mode) { | |
case SM_COW: return "COW"; | |
case SM_PRIVATE: return "PRV"; | |
case SM_EMPTY: return "NUL"; | |
case SM_SHARED: return "ALI"; | |
case SM_TRUESHARED: return "SHR"; | |
case SM_PRIVATE_ALIASED: return "P/A"; | |
case SM_SHARED_ALIASED: return "S/A"; | |
case SM_LARGE_PAGE: return "LPG"; | |
default: return "???"; | |
} | |
} | |
static bool | |
vmmap(task_t task, uintptr_t start, uintptr_t end, uint32_t depth) { | |
int pid = -1; | |
pid_for_task(task, &pid); | |
for (bool first = true;; first = false) { | |
mach_vm_address_t address = start; | |
mach_vm_size_t size = 0; | |
uint32_t depth0 = depth; | |
vm_region_submap_info_data_64_t info; | |
mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; | |
kern_return_t kr = mach_vm_region_recurse(task, &address, &size, | |
&depth0, (vm_region_recurse_info_t)&info, &count); | |
if (kr != KERN_SUCCESS || address > end) { | |
if (first) { | |
if (start == end) { | |
printf("no virtual memory region contains address %p\n", | |
(void *)start); | |
} else { | |
printf("no virtual memory region intersects %p-%p\n", | |
(void *)start, (void *)end); | |
} | |
} | |
break; | |
} | |
if (first) { | |
printf(" START - END [ VSIZE ] " | |
"PRT/MAX SHRMOD DEPTH RESIDENT REFCNT TAG" | |
" FILE\n"); | |
} | |
char vsize[5]; | |
format_display_size(vsize, size); | |
char cur_prot[4]; | |
format_memory_protection(cur_prot, info.protection); | |
char max_prot[4]; | |
format_memory_protection(max_prot, info.max_protection); | |
// Get the file name for this region. | |
char filename[4 + 4096] = {}; | |
memset(filename, ' ', 4); | |
errno = 0; | |
int ret = proc_regionfilename(pid, address, filename + 4, sizeof(filename) - 4); | |
if (ret <= 0 || errno != 0) { | |
filename[0] = 0; | |
} | |
printf("%016llx-%016llx [ %5s ] %s/%s %6s %5u %8u %6u %3u%s\n", | |
address, address + size, | |
vsize, | |
cur_prot, max_prot, | |
share_mode_name(info.share_mode), | |
depth0, | |
info.pages_resident, | |
info.ref_count, | |
info.user_tag, | |
filename); | |
start = address + size; | |
} | |
return true; | |
} | |
int | |
main(int argc, const char *argv[]) { | |
uint32_t depth = 2048; | |
char *end = NULL; | |
int argidx = 1; | |
// Options | |
for (;;) { | |
if (argidx >= argc) { | |
goto arguments; | |
} | |
// -d <depth> | |
if (strcmp(argv[argidx], "-d") == 0) { | |
argidx++; | |
if (argidx >= argc) { | |
goto usage; | |
} | |
uint64_t value = strtoul(argv[argidx], &end, 0); | |
if (*end != 0 || value > UINT32_MAX) { | |
goto usage; | |
} | |
depth = value; | |
} else { | |
goto arguments; | |
} | |
argidx++; | |
} | |
usage: | |
printf("usage: vmmap [-d <depth>] <pid>\n"); | |
return 1; | |
// Arguments | |
arguments: | |
if (argidx >= argc) { | |
goto usage; | |
} | |
// pid | |
uint64_t value = strtoul(argv[argidx], &end, 0); | |
if (*end != 0 || value > 1000000) { | |
goto usage; | |
} | |
int pid = value; | |
argidx++; | |
// End of arguments | |
if (argidx != argc) { | |
goto usage; | |
} | |
// Implementation. | |
mach_port_t task = MACH_PORT_NULL; | |
kern_return_t kr = task_for_pid(mach_task_self(), pid, &task); | |
if (kr != KERN_SUCCESS) { | |
printf("task_for_pid(%d) failed: %s\n", pid, mach_error_string(kr)); | |
return 1; | |
} | |
printf("Virtal Memory Map (depth=%u) for PID %d\n", depth, pid); | |
vmmap(task, 0, -1, depth); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>com.apple.private.debug_port</key> | |
<true/> | |
<key>com.apple.private.iosurfaceinfo</key> | |
<true/> | |
<key>com.apple.private.security.no-container</key> | |
<true/> | |
<key>com.apple.private.security.storage.AppDataContainers</key> | |
<true/> | |
<key>com.apple.security.iokit-user-client-class</key> | |
<array> | |
<string>IOSurfaceRootUserClient</string> | |
</array> | |
<key>com.apple.system-task-ports</key> | |
<true/> | |
<key>platform-application</key> | |
<true/> | |
<key>task_for_pid-allow</key> | |
<true/> | |
</dict> | |
</plist> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment