CommonLib
Loading...
Searching...
No Matches
mem.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <vector>
5
6#include "ut/expr/string_expr.h"
7
8///
9/// Transforms a virtual address to the current module's ASLR base.
10///
11/// \param ADDRESS The address to transform.
12///
13/// \returns The input address transformed into the ASLR base.
14///
15#define ASLR(ADDRESS)
16 (hedgedev::csl::mem::to_aslr(reinterpret_cast<void*>(ADDRESS)))
17
18///
19/// Checks if the instruction at the given memory address is a
20/// no-operation (NOP) instruction.
21///
22/// \param ADDRESS The address to check.
23///
24/// \returns `true` if the instruction is no-operation (NOP). Otherwise, `false`.
25///
26#define IS_NOP(ADDRESS)
27 (hedgedev::csl::mem::is_nop(reinterpret_cast<void*>(ADDRESS)))
28
29///
30/// Reads a value in memory.
31///
32/// \param ADDRESS The address to read from.
33/// \param TYPE The type to read.
34///
35/// \returns An instance of the type read from memory.
36///
37#define READ(ADDRESS, TYPE)
38 (hedgedev::csl::mem::read<TYPE>(reinterpret_cast<void*>(ADDRESS)))
39
40///
41/// Reads an array of values in memory.
42///
43/// \param ADDRESS The address to read from.
44/// \param TYPE The type to read.
45/// \param COUNT The total number of values to read.
46///
47/// \returns An array of instances of the type read from memory.
48///
49#define READ_ARRAY(ADDRESS, TYPE, COUNT)
50 (hedgedev::csl::mem::read<TYPE, COUNT>(reinterpret_cast<void*>(ADDRESS)))
51
52///
53/// Reads the address of an instruction in memory.
54///
55/// \param ADDRESS The address of the instruction to read.
56/// \param TYPE The type to read.
57/// \param OFFSET The offset of the address after `ADDRESS`.
58/// \param STRIDE The length of the instruction that was read.
59///
60/// \returns The address referenced by the instruction.
61///
62#define READ_INSTR_ADDRESS(ADDRESS, TYPE, OFFSET, STRIDE)
63 (hedgedev::csl::mem::read_instr_address<TYPE>(reinterpret_cast<void*>(ADDRESS), OFFSET, STRIDE))
64
65///
66/// Reads the address of a call instruction in memory.
67///
68/// \param ADDRESS The address of the call instruction to read.
69///
70/// \returns The address referenced by the call instruction.
71///
72#define READ_CALL(ADDRESS)
73 (hedgedev::csl::mem::read_call(reinterpret_cast<void*>(ADDRESS)))
74
75///
76/// Reads the address of a jump instruction in memory.
77///
78/// \param ADDRESS The address of the jump instruction to read.
79///
80/// \returns The address referenced by the jump instruction.
81///
82#define READ_JUMP(ADDRESS)
83 (hedgedev::csl::mem::read_jump(reinterpret_cast<void*>(ADDRESS)))
84
85///
86/// Writes any number of values in memory.
87///
88/// \param ADDRESS The address to write to.
89/// \param TYPE The type to write.
90/// \param __VA_ARGS__ The values to write.
91///
92/// \returns `true` if the data was written successfully. Otherwise, `false`.
93///
94#define WRITE(ADDRESS, TYPE, ...)
95 (hedgedev::csl::mem::write<TYPE>(reinterpret_cast<void*>(ADDRESS), { __VA_ARGS__ }))
96
97///
98/// Writes an array of values in memory.
99///
100/// \param ADDRESS The address to write to.
101/// \param TYPE The type to write.
102/// \param DATA The collection of values to write.
103///
104/// \returns `true` if the data was written successfully. Otherwise, `false`.
105///
106#define WRITE_ARRAY(ADDRESS, TYPE, DATA)
107 (hedgedev::csl::mem::write<TYPE>(reinterpret_cast<void*>(ADDRESS), DATA))
108
109///
110/// Writes a call instruction in memory.
111///
112/// \param ADDRESS The address to write to.
113/// \param DESTINATION The address of the function to call.
114///
115/// \returns `true` if the call was written successfully. Otherwise, `false`.
116///
117#define WRITE_CALL(ADDRESS, DESTINATION)
118 (hedgedev::csl::mem::write_call(reinterpret_cast<void*>(ADDRESS), reinterpret_cast<void*>(DESTINATION)))
119
120///
121/// Writes a jump instruction in memory.
122///
123/// \param ADDRESS The address to write to.
124/// \param DESTINATION The address of the address to jump to.
125///
126/// \returns `true` if the jump was written successfully. Otherwise, `false`.
127///
128#define WRITE_JUMP(ADDRESS, DESTINATION)
129 (hedgedev::csl::mem::write_jump(reinterpret_cast<void*>(ADDRESS), reinterpret_cast<void*>(DESTINATION)))
130
131///
132/// Writes a no-operation (NOP) instruction in memory.
133///
134/// \param ADDRESS The address to write to.
135/// \param COUNT The total number of no-operation (NOP) instructions to write.
136///
137/// \returns `true` if the no-operation (NOP) instruction was written successfully.
138/// Otherwise, `false`.
139///
140#define WRITE_NOP(ADDRESS, COUNT)
141 (hedgedev::csl::mem::write_nop(reinterpret_cast<void*>(ADDRESS), COUNT))
142
143///
144/// Writes a string in memory.
145///
146/// \param ADDRESS The address to write to.
147/// \param STR The string to write.
148///
149/// \returns `true` if the string was written successfully. Otherwise, `false`.
150///
151#define WRITE_STRING(ADDRESS, STR)
152 (hedgedev::csl::mem::write_string(reinterpret_cast<void*>(ADDRESS), STR))
153
154///
155/// Writes a string of fixed length in memory.
156///
157/// \param ADDRESS The address to write to.
158/// \param STR The string to write.
159/// \param __VA_ARGS__ The length of the string to write.
160/// If zero or unspecified, the length will be determined by
161/// the length of an existing string located at `ADDRESS`.
162///
163/// \returns `true` if the string was written successfully. Otherwise, `false`.
164///
165#define WRITE_STRING_FIXED(ADDRESS, STR, ...)
166 (hedgedev::csl::mem::write_string_fixed_length(reinterpret_cast<void*>(ADDRESS), STR, __VA_ARGS__))
167
168namespace hedgedev::csl::mem
169{
190
191 enum class branch_type;
192 enum class branch_distance;
193 enum class branch_condition;
194
204
205 ///
206 /// Gets the original base address of the current module.
207 ///
208 inline void* get_original_module_base();
209
210 ///
211 /// Gets the system flags for the specified page protection.
212 ///
214
215 ///
216 /// Sets the protection of a page of memory.
217 ///
218 inline bool protect(void* in_address, size_t in_length, uint32_t in_new_protect_flags, uint32_t* out_old_protect_flags = nullptr);
219
220 ///
221 /// Transforms a virtual address to the current module's ASLR base.
222 ///
223 /// \param in_address The address to transform.
224 /// \param in_base_address The original base address of the module containing the
225 /// address (optional).
226 ///
227 /// \returns The input address transformed into the ASLR base.
228 ///
229 inline void* to_aslr(void* in_address, void* in_base_address = nullptr);
230
231 ///
232 /// Transforms a virtual address from the current module's ASLR base.
233 ///
234 /// \param in_address The address to transform.
235 /// \param in_base_address The original base address of the module containing the
236 /// address (optional).
237 ///
238 /// \returns The input address transformed from the ASLR base.
239 ///
240 inline void* from_aslr(void* in_address, void* in_base_address = nullptr);
241
242 ///
243 /// Checks if the instruction at the given memory address is a
244 /// no-operation (NOP) instruction.
245 ///
246 /// \param in_address The address to check.
247 ///
248 /// \returns `true` if the instruction is no-operation (NOP). Otherwise, `false`.
249 ///
250 inline bool is_nop(void* in_address);
251
252 ///
253 /// Aligns a memory address.
254 ///
255 /// \tparam T The integral type of the address and alignment.
256 ///
257 /// \param in_address The address to align.
258 /// \param in_alignment The alignment to use.
259 ///
260 /// \returns The aligned memory address.
261 ///
262 template <typename T> requires (std::is_integral_v<T>)
263 inline constexpr T align(T in_address, T in_alignment);
264
265 ///
266 /// Aligns a memory address.
267 ///
268 /// \param in_address The address to align.
269 /// \param in_alignment The alignment to use.
270 ///
271 /// \returns The aligned memory address.
272 ///
273 inline void* align(void* in_address, uintptr_t in_alignment);
274
275 ///
276 /// Reads a value in memory.
277 ///
278 /// \tparam T The type to read.
279 ///
280 /// \param in_address The address to read from.
281 ///
282 /// \returns An instance of the type read from memory.
283 ///
284 template <typename T>
285 inline T read(void* in_address);
286
287 ///
288 /// Reads an array of values in memory.
289 ///
290 /// \tparam T The type to read.
291 /// \tparam count The total number of values to read.
292 ///
293 /// \param in_address The address to read from.
294 ///
295 /// \returns An array of instances of the type read from memory.
296 ///
297 template <typename T, size_t count>
298 inline std::array<T, count> read(void* in_address);
299
300 ///
301 /// Gets information about a branch instruction in memory.
302 ///
303 /// \param in_address The address of the branch instruction.
304 ///
305 /// \returns A structure containing information about the branch.
306 ///
307 inline branch_info get_branch_info(void* in_address);
308
309 ///
310 /// Reads the address of an instruction in memory.
311 ///
312 /// \tparam T The type to read.
313 ///
314 /// \param in_address The address of the instruction to read.
315 /// \param in_offset The offset of the address after `in_address`.
316 /// \param in_stride The length of the instruction that was read.
317 ///
318 /// \returns The address referenced by the instruction.
319 ///
320 template <typename T>
321 inline void* read_instr_address(void* in_address, ptrdiff_t in_offset, size_t in_stride);
322
323 ///
324 /// Reads the address of a call instruction in memory.
325 ///
326 /// \param in_address The address of the call instruction to read.
327 ///
328 /// \returns The address referenced by the call instruction.
329 ///
330 inline void* read_call(void* in_address);
331
332 ///
333 /// Reads the address of a jump instruction in memory.
334 ///
335 /// \param in_address The address of the jump instruction to read.
336 ///
337 /// \returns The address referenced by the jump instruction.
338 ///
339 inline void* read_jump(void* in_address);
340
341 ///
342 /// Swaps the complete order of bytes for any type.
343 ///
344 /// \param in_value The value to swap.
345 ///
346 /// \returns The swapped value.
347 ///
348 template <typename T>
349 inline constexpr T byteswap(T in_value);
350
351 ///
352 /// Swaps the complete order of bytes for any type by reference.
353 ///
354 /// \param io_value The value to swap.
355 ///
356 template <typename T>
357 inline constexpr void byteswap_inplace(T& io_value);
358
359 ///
360 /// Writes a value in memory.
361 ///
362 /// \tparam T The type to write.
363 ///
364 /// \param in_address The address to write to.
365 /// \param in_data The data to write.
366 /// \param in_count The total number of values to write.
367 ///
368 /// \returns `true` if the data was written successfully. Otherwise, `false`.
369 ///
370 template <typename T>
371 inline bool write(void* in_address, const T& in_data, size_t in_count = 1);
372
373 ///
374 /// Writes an array of values in memory.
375 ///
376 /// \tparam T The type to write.
377 ///
378 /// \param in_address The address to write to.
379 /// \param in_data The collection of values to write.
380 ///
381 /// \returns `true` if the data was written successfully. Otherwise, `false`.
382 ///
383 template <typename T>
384 inline bool write(void* in_address, const std::vector<T>& in_data);
385
386 ///
387 /// Writes a call instruction in memory.
388 ///
389 /// \param in_address The address to write to.
390 /// \param in_destination The address of the function to call.
391 ///
392 /// \returns `true` if the call was written successfully. Otherwise, `false`.
393 ///
394 inline bool write_call(void* in_address, void* in_destination);
395
396 ///
397 /// Writes a jump instruction in memory.
398 ///
399 /// \param in_address The address to write to.
400 /// \param in_destination The address of the address to jump to.
401 /// \param in_call Determines whether the jump should be encoded as a
402 /// call instruction.
403 ///
404 /// \returns `true` if the jump was written successfully. Otherwise, `false`.
405 ///
406 inline bool write_jump(void* in_address, void* in_destination, bool in_call = false);
407
408 ///
409 /// Writes a no-operation (NOP) instruction in memory.
410 ///
411 /// \param in_address The address to write to.
412 /// \param in_count The total number of no-operation (NOP) instructions to write.
413 ///
414 /// \returns `true` if the no-operation (NOP) instruction was written successfully.
415 /// Otherwise, `false`.
416 ///
417 inline bool write_nop(void* in_address, size_t in_count = 1);
418
419 ///
420 /// Writes a string in memory.
421 ///
422 /// \param in_address The address to write to.
423 /// \param in_str The string to write.
424 ///
425 /// \returns `true` if the string was written successfully. Otherwise, `false`.
426 ///
427 template <ut::expr::any_string T>
428 inline bool write_string(void* in_address, const T& in_str);
429
430 ///
431 /// Writes a string of fixed length in memory.
432 ///
433 /// \param in_address The address to write to.
434 /// \param in_str The string to write.
435 /// \param in_length The length of the string to write.
436 /// If zero, the length will be determined by the length of an existing string
437 /// located at `in_address`.
438 ///
439 /// \returns `true` if the string was written successfully. Otherwise, `false`.
440 ///
441 template <ut::expr::any_string T>
442 inline bool write_string_fixed_length(void* in_address, const T& in_str, size_t in_length = 0);
443}
444
445#include "mem.inl"
446
447#if defined(CMNLIB_X64) || defined(CMNLIB_X86)
448#include "arch/mem_x86.inl"
449#endif
450
451#ifdef WIN32
452#include "os/mem_win32.inl"
453#endif
Definition string_expr.h:92
Definition string_expr.h:116
Definition string_expr.h:122
Definition string_expr.h:110
Definition string_expr.h:104
Definition string_expr.h:98
Definition container_expr.h:21
Definition string_expr.h:74
Definition string_expr.h:38
Definition string_expr.h:56
Definition string_expr.h:62
Definition string_expr.h:50
Definition string_expr.h:44
Definition container_expr.h:15
Definition this_process_win32.inl:13
std::filesystem::path get_executable_root()
Definition this_process.inl:7
bool is_neighbour(const std::filesystem::path &in_path)
Definition this_process.inl:12
Definition mem.h:169
void * to_aslr(void *in_address, void *in_base_address=nullptr)
Definition mem_win32.inl:63
bool write_string_fixed_length(void *in_address, const T &in_str, size_t in_length=0)
Definition mem.inl:156
void * read_jump(void *in_address)
Definition mem_x86.inl:141
void * read_call(void *in_address)
Definition mem_x86.inl:136
bool write(void *in_address, const std::vector< T > &in_data)
Definition mem.inl:130
bool write_string(void *in_address, const T &in_str)
Definition mem.inl:147
bool write(void *in_address, const T &in_data, size_t in_count=1)
Definition mem.inl:110
void * read_instr_address(void *in_address, ptrdiff_t in_offset, size_t in_stride)
Definition mem_x86.inl:128
branch_info get_branch_info(void *in_address)
Definition mem_x86.inl:44
uint32_t get_protect_flags(page_protection in_protection)
Definition mem_win32.inl:21
bool write_jump(void *in_address, void *in_destination, bool in_call=false)
Definition mem_x86.inl:151
constexpr T byteswap(T in_value)
Definition mem.inl:46
constexpr T align(T in_address, T in_alignment)
Definition mem.inl:18
std::array< T, count > read(void *in_address)
Definition mem.inl:35
branch_distance
Definition mem_x86.inl:13
bool write_nop(void *in_address, size_t in_count=1)
Definition mem_x86.inl:188
void * from_aslr(void *in_address, void *in_base_address=nullptr)
Definition mem_win32.inl:71
void * align(void *in_address, uintptr_t in_alignment)
Definition mem.inl:23
bool is_nop(void *in_address)
Definition mem_x86.inl:39
bool write_call(void *in_address, void *in_destination)
Definition mem_x86.inl:146
T read(void *in_address)
Definition mem.inl:29
bool protect(void *in_address, size_t in_length, uint32_t in_new_protect_flags, uint32_t *out_old_protect_flags=nullptr)
Definition mem_win32.inl:51
void * get_original_module_base()
Definition mem_win32.inl:9
page_protection
Definition mem.h:171
@ read_write
Definition mem.h:178
@ no_access
Definition mem.h:172
@ read_write_execute
Definition mem.h:180
@ read_execute
Definition mem.h:179
branch_condition
Definition mem_x86.inl:20
constexpr void byteswap_inplace(T &io_value)
Definition mem.inl:104
branch_type
Definition mem_x86.inl:6
Definition encoding.h:10
constexpr size_t get_bom_length()
Definition encoding.inl:73
constexpr size_t get_bom_length(encoding_type in_encoding)
Definition encoding.inl:53
std::array< T_result, sizeof...(T_args)> precedent_convert(const T_args &... in_args)
Definition encoding.inl:79
bool try_convert(const T_str &in_str, T_result &out_result, encoding_type in_dst_encoding=expr::get_char_encoding_type< T_result >(), encoding_type in_src_encoding=expr::get_char_encoding_type< T_str >())
Definition encoding.inl:126
std::vector< uint8_t > get_bom(encoding_type in_encoding)
Definition encoding.inl:30
T_result convert(const T_str &in_str, encoding_type in_dst_encoding=expr::get_char_encoding_type< T_result >(), encoding_type in_src_encoding=expr::get_char_encoding_type< T_str >())
Definition encoding.inl:15
encoding_type
Definition encoding_type.h:6
@ utf32_be
Definition encoding_type.h:12
@ utf16_be
Definition encoding_type.h:10
@ unknown
Definition encoding_type.h:7
@ utf32_le
Definition encoding_type.h:11
@ latin1
Definition encoding_type.h:13
@ utf8
Definition encoding_type.h:8
@ utf16_le
Definition encoding_type.h:9
typename get_encoding_char_type< encoding >::type get_encoding_char_type_t
Definition encoding_expr.h:35
constexpr bool is_char_encoding_type_v
Definition encoding_expr.h:74
constexpr bool is_all_same_v
Definition expr.h:38
constexpr bool is_same_underlying_char_type_v
Definition string_expr.h:128
constexpr encoding::encoding_type get_char_encoding_type()
Definition encoding_expr.inl:9
constexpr size_t get_string_type_precedence()
Definition string_expr.inl:23
constexpr encoding::encoding_type get_native_encoding_type(encoding::encoding_type in_encoding)
Definition encoding_expr.inl:43
constexpr T_result create_inferred_string(const T_str &in_str)
Definition string_expr.inl:6
constexpr size_t get_encoding_char_size(encoding::encoding_type in_encoding)
Definition encoding_expr.inl:71
constexpr bool is_char_encoding_type(encoding::encoding_type in_encoding)
Definition encoding_expr.inl:92
constexpr bool is_supported_template_v
Definition expr.h:46
Definition filesystem.h:6
std::error_code truncate_files_by_age(const std::filesystem::path &in_path, std::string_view in_extension, size_t in_max=10)
Definition filesystem.inl:46
bool is_neighbour(const std::filesystem::path &in_left, const std::filesystem::path &in_right)
Definition filesystem.inl:7
std::error_code truncate_files(const std::filesystem::path &in_path, std::string_view in_extension, size_t in_max, T &&in_compare_func)
Definition filesystem.inl:13
Definition string.h:11
expr::inferred_string_t< T_str > trim_start(const T_str &in_str, std::optional< std::vector< T_trim_chars > > in_trim_chars={})
Definition string.inl:326
expr::inferred_string_t< T > format(const T in_str,...)
Definition string.inl:82
expr::inferred_string_t< T > lower(const T &in_str)
Definition string.inl:288
expr::inferred_string_t< T_str > trim(const T_str &in_str, std::optional< std::vector< T_trim_chars > > in_trim_chars={})
Definition string.inl:365
bool is_null_or_empty(const T &in_str)
Definition string.inl:160
T_result hyperlink(const T_str &in_str, const T_url &in_url)
Definition string.inl:140
expr::inferred_string_t< T_str > remove_xml_tags(const T_str &in_str)
Definition string.inl:247
bool is_null_or_whitespace(const T &in_str)
Definition string.inl:172
expr::inferred_string_t< T_str > trim_end(const T_str &in_str, std::optional< std::vector< T_trim_chars > > in_trim_chars={})
Definition string.inl:345
expr::inferred_string_t< T_str > wrap(const T_str &in_str, size_t in_max_width)
Definition string.inl:505
bool compare(const T_left &in_left, const T_right &in_right, bool in_case_sensitive=true)
Definition string.inl:18
T_result join(const T_delimiter &in_delimiter, const T_args &... in_args)
Definition string.inl:214
std::vector< T_result > split(const T_str &in_str, const T_delimiter &in_delimiter)
Definition string.inl:257
expr::inferred_string_t< T > upper(const T &in_str)
Definition string.inl:307
bool try_parse(const T_str &in_str, T_result &out_result)
Definition string.inl:447
expr::inferred_string_t< T_str > escape(const T_str &in_str, T_str_char in_search_char, T_str_char in_escape_char=T_str_char('\\'))
Definition string.inl:66
bool contains(const T_str &in_str, const T_substr &in_substr, bool in_case_sensitive=true)
Definition string.inl:35
T_result pad(const T_str &in_str, const T_pad_str &in_pad_str)
Definition string.inl:222
T_result hex(T_value in_value, size_t in_max_length=sizeof(size_t) *2, bool in_prefix=true)
Definition string.inl:420
T_result parse(const T_str &in_str)
Definition string.inl:237
size_t get_width(const T &in_str)
Definition string.inl:126
expr::inferred_string_t< T > truncate(const T &in_str, size_t in_max_length, bool in_truncate_end=true, bool in_ellipsis=true)
Definition string.inl:371
expr::inferred_string_t< T_strings > join(const T_delimiter &in_delimiter, const std::vector< T_strings > &in_strings)
Definition string.inl:186
Definition expr.h:7
void * destination
Definition mem.h:202
branch_condition condition
Definition mem.h:199
uint8_t instr_length
Definition mem.h:201
branch_type type
Definition mem.h:197
uint8_t opcode_length
Definition mem.h:200
branch_distance distance
Definition mem.h:198
Definition string_expr.h:19
char type
Definition encoding_expr.h:11
Definition string_expr.h:65