-
Notifications
You must be signed in to change notification settings - Fork 176
/
os_osx.h
151 lines (119 loc) · 3.03 KB
/
os_osx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include <errno.h>
#include <mach/mach_init.h>
#include <mach/mach_traps.h>
#include <mach/mach_port.h>
#include <mach/vm_map.h>
static void os_startup()
{
}
static kinfo_proc* os_processes;
static size_t os_process_count;
static size_t os_process_idx;
static bool os_enum_start()
{
static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
size_t length;
os_processes = NULL;
int err;
bool done = false;
do
{
err = sysctl((int*)name, (sizeof(name)/sizeof(*name)) - 1, NULL, &length, NULL, 0);
if (err == -1)
{
break;
}
os_processes = (kinfo_proc*)realloc(os_processes, length);
if (os_processes == NULL)
{
err = -1;
break;
}
err = sysctl((int*)name, (sizeof(name)/sizeof(*name)) - 1, os_processes, &length, NULL, 0);
if (err == -1 && errno == ENOMEM)
{
continue;
}
break;
}
while (err == 0 && ! done);
if (err != 0)
{
free(os_processes);
return false;
}
os_process_count = length / sizeof(kinfo_proc);
os_process_idx = 0;
return true;
}
static uint32_t os_enum_next(const char* name)
{
while (os_process_idx < os_process_count)
{
kinfo_proc* p = os_processes + os_process_idx++;
if (strcmp(name, p->kp_proc.p_comm) == 0)
{
return p->kp_proc.p_pid;
}
}
return 0;
}
static void os_enum_end()
{
free(os_processes);
}
static task_t os_process_task;
static vm_address_t os_process_addr;
static vm_size_t os_process_size;
static bool os_process_begin(uint32_t pid)
{
kern_return_t kr = task_for_pid(mach_task_self(), pid, &os_process_task);
if (kr != KERN_SUCCESS)
{
return false;
}
os_process_addr = 0;
os_process_size = 0;
return true;
}
static uint64_t os_process_next(uint64_t* size)
{
for (;;)
{
os_process_addr += os_process_size;
uint32_t depth = 1;
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
vm_region_submap_info_64 info;
mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
kern_return_t kr = vm_region_recurse_64(os_process_task, &os_process_addr, &os_process_size, &depth, (vm_region_info_64_t)&info, &count);
if (kr != KERN_SUCCESS)
{
return 0;
}
if ((info.protection & VM_PROT_READ) == 0)
{
continue;
}
*size = os_process_size;
return os_process_addr;
}
}
static uint32_t os_process_read(uint64_t addr, void* buffer, uint32_t size)
{
vm_size_t read = size;
if (vm_read_overwrite(os_process_task, addr, size, (vm_address_t)buffer, &read) != KERN_SUCCESS)
{
return 0;
}
return (uint32_t)read;
}
static void os_process_end()
{
mach_port_deallocate(mach_task_self(), os_process_task);
}