forked from wh1te4ever/kfund
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkrw.m
203 lines (172 loc) · 4.86 KB
/
krw.m
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
//
// krw.c
// kfd
//
// Created by Seo Hyun-gyu on 2023/07/29.
//
#include "krw.h"
#include "libkfd.h"
#include "helpers.h"
#include "kpf/patchfinder.h"
uint64_t _kfd = 0;
uint64_t unsign_kptr(uint64_t pac_kaddr) {
if ((pac_kaddr & 0xFFFFFF0000000000) == 0xFFFFFF0000000000) {
return pac_kaddr;
}
if(T1SZ_BOOT != 0) {
return pac_kaddr |= ~((1ULL << (64U - T1SZ_BOOT)) - 1U);
}
return pac_kaddr;
}
uint64_t do_kopen(uint64_t puaf_pages, uint64_t puaf_method, uint64_t kread_method, uint64_t kwrite_method)
{
// remove([NSString stringWithFormat:@"%@/Documents/kfund_offsets.plist", NSHomeDirectory()].UTF8String); //TEMPORARY: remove offsets plist to check if patchfinder is working
_kfd = kopen(puaf_pages, puaf_method, kread_method, kwrite_method);
return _kfd;
}
void do_kclose(void)
{
kclose((struct kfd*)(_kfd));
}
void early_kread(uint64_t kfd, u64 kaddr, void* uaddr, u64 size)
{
kread((struct kfd*)(kfd), kaddr, uaddr, size);
}
uint64_t early_kread64(uint64_t kfd, uint64_t where) {
uint64_t out;
kread((struct kfd*)(kfd), where, &out, sizeof(uint64_t));
return out;
}
uint32_t early_kread32(uint64_t kfd, uint64_t where) {
return early_kread64(kfd, where) & 0xffffffff;
}
void early_kreadbuf(uint64_t kfd, uint64_t kaddr, void* output, size_t size)
{
uint64_t endAddr = kaddr + size;
uint32_t outputOffset = 0;
unsigned char* outputBytes = (unsigned char*)output;
for(uint64_t curAddr = kaddr; curAddr < endAddr; curAddr += 4)
{
uint32_t k = early_kread32(kfd, curAddr);
unsigned char* kb = (unsigned char*)&k;
for(int i = 0; i < 4; i++)
{
if(outputOffset == size) break;
outputBytes[outputOffset] = kb[i];
outputOffset++;
}
if(outputOffset == size) break;
}
}
void do_kread(u64 kaddr, void* uaddr, u64 size)
{
kread(_kfd, kaddr, uaddr, size);
}
void do_kwrite(void* uaddr, u64 kaddr, u64 size)
{
kwrite(_kfd, uaddr, kaddr, size);
}
uint64_t get_kslide(void) {
return ((struct kfd*)_kfd)->perf.kernel_slide;
}
uint64_t get_kernproc(void) {
return ((struct kfd*)_kfd)->info.kaddr.kernel_proc;
}
uint64_t get_selftask(void) {
return ((struct kfd*)_kfd)->info.kaddr.current_task;
}
uint64_t get_selfpmap(void) {
return ((struct kfd*)_kfd)->info.kaddr.current_pmap;
}
uint64_t get_kerntask(void) {
return ((struct kfd*)_kfd)->info.kaddr.kernel_task;
}
uint8_t kread8(uint64_t where) {
uint8_t out;
kread(_kfd, where, &out, sizeof(uint8_t));
return out;
}
uint32_t kread16(uint64_t where) {
uint16_t out;
kread(_kfd, where, &out, sizeof(uint16_t));
return out;
}
uint32_t kread32(uint64_t where) {
uint32_t out;
kread(_kfd, where, &out, sizeof(uint32_t));
return out;
}
uint64_t kread64(uint64_t where) {
uint64_t out;
kread(_kfd, where, &out, sizeof(uint64_t));
return out;
}
//Thanks @jmpews
uint64_t kread64_smr(uint64_t where) {
uint64_t value = unsign_kptr(kread64(where));
if((value & 0x400000000000) != 0)
value &= 0xFFFFFFFFFFFFFFE0;
return value;
}
void kwrite8(uint64_t where, uint8_t what) {
uint8_t _buf[8] = {};
_buf[0] = what;
_buf[1] = kread8(where+1);
_buf[2] = kread8(where+2);
_buf[3] = kread8(where+3);
_buf[4] = kread8(where+4);
_buf[5] = kread8(where+5);
_buf[6] = kread8(where+6);
_buf[7] = kread8(where+7);
kwrite((u64)(_kfd), &_buf, where, sizeof(u64));
}
void kwrite16(uint64_t where, uint16_t what) {
u16 _buf[4] = {};
_buf[0] = what;
_buf[1] = kread16(where+2);
_buf[2] = kread16(where+4);
_buf[3] = kread16(where+6);
kwrite((u64)(_kfd), &_buf, where, sizeof(u64));
}
void kwrite32(uint64_t where, uint32_t what) {
u32 _buf[2] = {};
_buf[0] = what;
_buf[1] = kread32(where+4);
kwrite((u64)(_kfd), &_buf, where, sizeof(u64));
}
void kwrite64(uint64_t where, uint64_t what) {
u64 _buf[1] = {};
_buf[0] = what;
kwrite((u64)(_kfd), &_buf, where, sizeof(u64));
}
uint64_t do_vtophys(uint64_t what) {
return vtophys((u64)(_kfd), what);
}
uint64_t do_phystokv(uint64_t what) {
return phystokv((u64)(_kfd), what);
}
uint64_t kread64_ptr(uint64_t kaddr) {
uint64_t ptr = kread64(kaddr);
if ((ptr >> 55) & 1) {
return unsign_kptr(ptr);
}
return ptr;
}
void kreadbuf(uint64_t kaddr, void* output, size_t size)
{
uint64_t endAddr = kaddr + size;
uint32_t outputOffset = 0;
unsigned char* outputBytes = (unsigned char*)output;
for(uint64_t curAddr = kaddr; curAddr < endAddr; curAddr += 4)
{
uint32_t k = kread32(curAddr);
unsigned char* kb = (unsigned char*)&k;
for(int i = 0; i < 4; i++)
{
if(outputOffset == size) break;
outputBytes[outputOffset] = kb[i];
outputOffset++;
}
if(outputOffset == size) break;
}
}