KittyMemoryEx 1.0.0
Dedicated library for runtime code patching, memory scanning, tracing, injection and some more useful memory utilities. works for both Android and Linux
Loading...
Searching...
No Matches
KittyPtrValidator.hpp
1#pragma once
2
3#include <inttypes.h>
4#include <algorithm>
5#include <cstdint>
6#include <fcntl.h>
7#include <string>
8#include <sys/stat.h>
9#include <unistd.h>
10#include <vector>
11#include <cstdio>
12#include <cstdlib>
13
14#include "KittyUtils.hpp"
15
16#ifdef __APPLE__
17#include <mach/mach.h>
18
25{
26private:
27 struct RegionInfo
28 {
29 uintptr_t start;
30 uintptr_t end;
31 bool readable;
32 bool writable;
33 bool executable;
34
35 RegionInfo(uintptr_t s, uintptr_t e, bool r, bool w, bool x)
36 : start(s), end(e), readable(r), writable(w), executable(x)
37 {
38 }
39
40 inline bool canMergeWith(const RegionInfo &other) const
41 {
42 return end == other.start && readable == other.readable && writable == other.writable &&
43 executable == other.executable;
44 }
45 };
46
47 std::vector<RegionInfo> cachedRegions_;
48 const mach_port_t task_;
49 const size_t page_size_;
50 bool use_cache_;
51 size_t last_region_index_;
52
53 bool _findRegion(uintptr_t addr, RegionInfo *region);
54
55public:
56 KittyPtrValidator()
57 : task_(mach_task_self()), page_size_(sysconf(_SC_PAGESIZE)), use_cache_(false), last_region_index_(0)
58 {
59 }
60
67 KittyPtrValidator(mach_port_t task, bool use_cache)
68 : task_(task), page_size_(sysconf(_SC_PAGESIZE)), use_cache_(use_cache), last_region_index_(0)
69 {
70 if (use_cache_)
72 }
73
79 inline void setUseCache(bool use_cache)
80 {
81 use_cache_ = use_cache;
82 if (!use_cache_)
83 {
84 cachedRegions_.clear();
85 last_region_index_ = 0;
86 }
87 else
88 {
90 }
91 }
92
100 bool isPtrReadable(uintptr_t ptr, size_t len = sizeof(void *));
101
109 bool isPtrWritable(uintptr_t ptr, size_t len = sizeof(void *));
110
118 bool isPtrExecutable(uintptr_t ptr, size_t len = sizeof(void *));
119
126 inline bool isPtrInAddressSpace(uintptr_t ptr)
127 {
128 if (ptr == 0)
129 return false;
130 RegionInfo region(0, 0, false, false, false);
131 return _findRegion(ptr, &region);
132 }
133
134 inline bool isPtrReadable(const void *ptr, size_t len = sizeof(void *))
135 {
136 return ptr && isPtrReadable(uintptr_t(ptr), len);
137 }
138 inline bool isPtrWritable(const void *ptr, size_t len = sizeof(void *))
139 {
140 return ptr && isPtrWritable(uintptr_t(ptr), len);
141 }
142 inline bool isPtrExecutable(const void *ptr, size_t len = sizeof(void *))
143 {
144 return ptr && isPtrExecutable(uintptr_t(ptr), len);
145 }
146 inline bool isPtrInAddressSpace(const void *ptr)
147 {
148 return ptr && isPtrInAddressSpace(uintptr_t(ptr));
149 }
150
154 inline void clearCache()
155 {
156 cachedRegions_.clear();
157 last_region_index_ = 0;
158 }
159
163 void refreshRegionCache();
164
170 inline std::vector<RegionInfo> cachedRegions() const
171 {
172 return cachedRegions_;
173 }
174};
175
176#else
177
183class KittyPtrValidator
184{
185private:
186 struct RegionInfo
187 {
188 uintptr_t start;
189 uintptr_t end;
190 bool readable;
191 bool writable;
192 bool executable;
193
194 RegionInfo(uintptr_t s, uintptr_t e, bool r, bool w, bool x)
195 : start(s), end(e), readable(r), writable(w), executable(x)
196 {
197 }
198
199 inline bool canMergeWith(const RegionInfo &other) const
200 {
201 return end == other.start && readable == other.readable && writable == other.writable &&
202 executable == other.executable;
203 }
204 };
205
206 std::vector<RegionInfo> cachedRegions_;
207 pid_t pid_;
208 const size_t page_size_;
209 bool use_cache_;
210 size_t last_region_index_;
211
212 bool _parseMapsLine(const char *line, RegionInfo *region);
213
214 bool _findRegion(uintptr_t addr, RegionInfo *region);
215
216public:
217 KittyPtrValidator() : pid_(getpid()), page_size_(sysconf(_SC_PAGESIZE)), use_cache_(false), last_region_index_(0)
218 {
219 }
220
227 KittyPtrValidator(pid_t pid, bool use_cache)
228 : pid_(pid), page_size_(sysconf(_SC_PAGESIZE)), use_cache_(use_cache), last_region_index_(0)
229 {
230 if (use_cache_)
232 }
233
239 inline void setUseCache(bool use_cache)
240 {
241 use_cache_ = use_cache;
242 if (!use_cache_)
243 {
244 cachedRegions_.clear();
245 last_region_index_ = 0;
246 }
247 else
248 {
250 }
251 }
252
258 inline void setPID(pid_t pid)
259 {
260 cachedRegions_.clear();
261 last_region_index_ = 0;
262 pid_ = pid;
263
264 if (use_cache_)
265 {
267 }
268 }
269
277 bool isPtrReadable(uintptr_t ptr, size_t len = sizeof(void *));
278
286 bool isPtrWritable(uintptr_t ptr, size_t len = sizeof(void *));
287
295 bool isPtrExecutable(uintptr_t ptr, size_t len = sizeof(void *));
296
303 inline bool isPtrInAddressSpace(uintptr_t ptr)
304 {
305 if (ptr == 0)
306 return false;
307 ptr = KittyUtils::untagPointer(ptr);
308 RegionInfo region(0, 0, false, false, false);
309 return _findRegion(ptr, &region);
310 }
311
312 inline bool isPtrReadable(const void *ptr, size_t len = sizeof(void *))
313 {
314 return ptr && isPtrReadable(uintptr_t(ptr), len);
315 }
316 inline bool isPtrWritable(const void *ptr, size_t len = sizeof(void *))
317 {
318 return ptr && isPtrWritable(uintptr_t(ptr), len);
319 }
320 inline bool isPtrExecutable(const void *ptr, size_t len = sizeof(void *))
321 {
322 return ptr && isPtrExecutable(uintptr_t(ptr), len);
323 }
324 inline bool isPtrInAddressSpace(const void *ptr)
325 {
326 return ptr && isPtrInAddressSpace(uintptr_t(ptr));
327 }
328
332 inline void clearCache()
333 {
334 cachedRegions_.clear();
335 last_region_index_ = 0;
336 }
337
342
348 inline std::vector<RegionInfo> cachedRegions() const
349 {
350 return cachedRegions_;
351 }
352};
353
354#endif
Validates the memory access rights for a given address range.
Definition KittyPtrValidator.hpp:184
bool isPtrReadable(uintptr_t ptr, size_t len=sizeof(void *))
Checks if a pointer is readable.
void clearCache()
Clears the cached region information.
Definition KittyPtrValidator.hpp:332
void setUseCache(bool use_cache)
Sets whether to use cached region information.
Definition KittyPtrValidator.hpp:239
void refreshRegionCache()
Refreshes the cached region information.
std::vector< RegionInfo > cachedRegions() const
Retrieves the cached region information.
Definition KittyPtrValidator.hpp:348
bool isPtrWritable(uintptr_t ptr, size_t len=sizeof(void *))
Checks if a pointer is writable.
void setPID(pid_t pid)
Sets the process ID to query memory regions.
Definition KittyPtrValidator.hpp:258
bool isPtrExecutable(uintptr_t ptr, size_t len=sizeof(void *))
Checks if a pointer is executable.
bool isPtrInAddressSpace(uintptr_t ptr)
Checks if a pointer is within the address space of the current process.
Definition KittyPtrValidator.hpp:303
KittyPtrValidator(pid_t pid, bool use_cache)
Constructs a KittyPtrValidator object with the specified process ID and whether to use a cache.
Definition KittyPtrValidator.hpp:227
uintptr_t untagPointer(uintptr_t ptr)
Removes AArch64 top-byte pointer tags from an address.
Definition KittyUtils.hpp:474