-
Notifications
You must be signed in to change notification settings - Fork 25
/
kernel_memory_helpers.c
156 lines (134 loc) · 3.21 KB
/
kernel_memory_helpers.c
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
152
153
154
155
156
#include <stdio.h>
#include <stdlib.h>
#include <mach/mach.h>
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
);
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
);
kern_return_t mach_vm_deallocate
(
vm_map_t target,
mach_vm_address_t address,
mach_vm_size_t size
);
mach_port_t kernel_task_port = MACH_PORT_NULL;
void init_kernel_memory_helpers(mach_port_t ktp) {
kernel_task_port = ktp;
}
mach_port_t _kernel_task_port() {
return kernel_task_port;
}
/* read */
uint32_t r32(mach_port_t tp, uint64_t addr) {
kern_return_t err;
vm_offset_t buf = 0;
mach_msg_type_number_t num = 0;
err = mach_vm_read(tp,
addr,
4,
&buf,
&num);
if (err != KERN_SUCCESS) {
printf("read failed!\n");
return 0;
}
uint32_t val = *(uint32_t*)buf;
mach_vm_deallocate(mach_task_self(), buf, num);
return val;
}
uint64_t r64(mach_port_t tp, uint64_t addr) {
kern_return_t err;
vm_offset_t buf = 0;
mach_msg_type_number_t num = 0;
err = mach_vm_read(tp,
addr,
8,
&buf,
&num);
if (err != KERN_SUCCESS){
printf("read failed!\n");
return 0;
}
uint64_t val = *(uint64_t*)buf;
mach_vm_deallocate(mach_task_self(), buf, num);
return val;
}
void* rmem(mach_port_t tp, uint64_t addr, uint64_t len) {
kern_return_t err;
vm_offset_t buf = 0;
mach_msg_type_number_t num = 0;
err = mach_vm_read(tp,
addr,
len,
&buf,
&num);
if (err != KERN_SUCCESS) {
printf("read failed\n");
return NULL;
}
uint8_t* outbuf = malloc(len);
memcpy(outbuf, (void*)buf, len);
mach_vm_deallocate(mach_task_self(), buf, num);
return outbuf;
}
/* write */
void w8(mach_port_t tp, uint64_t addr, uint8_t val) {
kern_return_t err =
mach_vm_write(tp,
addr,
(vm_offset_t)&val,
1);
if (err != KERN_SUCCESS) {
printf("write failed\n");
}
}
void w32(mach_port_t tp, uint64_t addr, uint32_t val) {
kern_return_t err =
mach_vm_write(tp,
addr,
(vm_offset_t)&val,
4);
if (err != KERN_SUCCESS) {
printf("write failed\n");
}
}
void w64(mach_port_t tp, uint64_t addr, uint64_t val) {
kern_return_t err =
mach_vm_write(tp,
addr,
(vm_offset_t)&val,
8);
if (err != KERN_SUCCESS) {
printf("write failed\n");
}
}
/* wrappers with implict kernel task port argument */
uint64_t rk64(uint64_t addr) {
return r64(kernel_task_port, addr);
}
uint32_t rk32(uint64_t addr) {
return r32(kernel_task_port, addr);
}
void* rkmem(uint64_t addr, uint64_t len) {
return rmem(kernel_task_port, addr, len);
}
void wk8(uint64_t addr, uint8_t val) {
w8(kernel_task_port, addr, val);
}
void wk32(uint64_t addr, uint32_t val) {
w32(kernel_task_port, addr, val);
}
void wk64(uint64_t addr, uint64_t val) {
w64(kernel_task_port, addr, val);
}