|
2 | 2 | A modern, high-performance library for C++20 designed around game hacking |
3 | 3 |
|
4 | 4 | ## Feature overview |
5 | | -- Windows x86/x64 support |
6 | | -- Partial Linux and macOS support |
7 | 5 | - Vectorized scanning for byte patterns |
8 | 6 | - SSE 4.1 and AVX2 on x86/x64 |
9 | 7 | - AVX-512 on x64 |
| 8 | + - Neon on ARM/ARM64 |
10 | 9 | - RAII memory protector |
11 | 10 | - Convenience wrappers over OS APIs |
12 | 11 | - Language bindings (C, C#, Java) |
| 12 | +- Full Windows support |
| 13 | +- Partial (WIP) Linux, macOS, and Android support |
13 | 14 |
|
14 | 15 | ## Versioning |
15 | 16 | This project adheres to [semantic versioning](https://semver.org/spec/v2.0.0.html). Any declaration that |
@@ -100,19 +101,21 @@ BM_Throughput_UC2/256MiB 261157833 ns 261160714 ns |
100 | 101 |
|
101 | 102 | Below is a summary of the current support for libhat's platform-dependent APIs: |
102 | 103 |
|
103 | | -| | Windows | Linux | macOS | |
104 | | -|--------------------------------|:-------:|:-----:|:-----:| |
105 | | -| `hat::get_system` | ✅ | ✅ | ✅ | |
106 | | -| `hat::memory_protector` | ✅ | ✅ | | |
107 | | -| `hp::get_process_module` | ✅ | ✅ | | |
108 | | -| `hp::get_module` | ✅ | ✅ | | |
109 | | -| `hp::module_at` | ✅ | | | |
110 | | -| `hp::is_readable` | ✅ | ✅ | | |
111 | | -| `hp::is_writable` | ✅ | ✅ | | |
112 | | -| `hp::is_executable` | ✅ | ✅ | | |
113 | | -| `hp::module::get_module_data` | ✅ | ✅ | | |
114 | | -| `hp::module::get_section_data` | ✅ | | | |
115 | | -| `hp::module::for_each_segment` | ✅ | ✅ | | |
| 104 | +### APIs |
| 105 | + |
| 106 | +| | Windows | Linux | macOS | Android | |
| 107 | +|--------------------------------|:-------:|:-----:|:-----:|:-------:| |
| 108 | +| `hat::get_system` | ✅ | ✅ | ✅ | ✅ | |
| 109 | +| `hat::memory_protector` | ✅ | ✅ | | ✅ | |
| 110 | +| `hp::get_process_module` | ✅ | ✅ | ✅ | ✅ | |
| 111 | +| `hp::get_module` | ✅ | ✅ | ✅ | ✅ | |
| 112 | +| `hp::module_at` | ✅ | | | | |
| 113 | +| `hp::is_readable` | ✅ | ✅ | | ✅ | |
| 114 | +| `hp::is_writable` | ✅ | ✅ | | ✅ | |
| 115 | +| `hp::is_executable` | ✅ | ✅ | | ✅ | |
| 116 | +| `hp::module::get_module_data` | ✅ | ✅ | | ✅ | |
| 117 | +| `hp::module::get_section_data` | ✅ | | | | |
| 118 | +| `hp::module::for_each_segment` | ✅ | ✅ | ✅ | ✅ | |
116 | 119 |
|
117 | 120 | ## Quick start |
118 | 121 | ### Defining patterns |
@@ -189,19 +192,24 @@ const std::byte* address = result.get(); |
189 | 192 | const std::byte* relative_address = result.rel(3); |
190 | 193 | ``` |
191 | 194 |
|
192 | | -libhat has a few optimizations for searching for patterns in `x86_64` machine code: |
| 195 | +libhat has a few optimizations for searching for patterns in `x86_64` and `AArch64` machine code: |
193 | 196 | ```cpp |
194 | 197 | #include <libhat/scanner.hpp> |
195 | 198 |
|
196 | | -// If a byte pattern matches at the start of a function, the result will be aligned on 16-bytes. |
197 | | -// This can be indicated via the defaulted `alignment` parameter (all overloads have this parameter): |
| 199 | +// Compilers will often align the start address of a function on 16-bytes. Scanning for patterns that |
| 200 | +// match the start of a function can take advantage of this by specifying the defaulted `alignment` |
| 201 | +// parameter (all overloads have this parameter): |
198 | 202 | std::span<std::byte> range = /* ... */; |
199 | 203 | hat::signature_view pattern = /* ... */; |
200 | 204 | hat::scan_result result = hat::find_pattern(range, pattern, hat::scan_alignment::X16); |
201 | 205 |
|
202 | | -// Additionally, x86_64 contains a non-uniform distribution of byte pairs. By passing the `x86_64` |
203 | | -// scan hint, the search can be based on the least common byte pair that is found in the pattern. |
204 | | -hat::scan_result result = hat::find_pattern(range, pattern, hat::scan_alignment::X1, hat::scan_hint::x86_64); |
| 206 | +// Or, if the architecture has byte-aligned instructions (such as ARM and AArch64): |
| 207 | +hat::scan_result result = hat::find_pattern(range, pattern, hat::scan_alignment::X4); |
| 208 | + |
| 209 | +// Additionally, machine code contains a non-uniform distribution of bytes. By passing the respective |
| 210 | +// scan hint (either `x86_64` or `aarch64`), the search anchor can be tuned to the least frequent |
| 211 | +// bytes that are present in the pattern. |
| 212 | +hat::scan_result result = hat::find_pattern(range, pattern, hat::scan_alignment::X1, hat::scan_hint::x86_64); |
205 | 213 | ``` |
206 | 214 |
|
207 | 215 | ### Accessing members |
|
0 commit comments