1.5.7881
Середина декабря — сканирование паттернов
C# Scripting — добавлено сканирование по сигнатурам
Что такое Pattern Scanning?
Pattern scanning — это способ поиска определённых последовательностей байтов в памяти. Он полезен, когда нужно найти функции, данные или участки кода, которые при каждом запуске программы могут находиться по разным адресам.
Зачем это нужно?
- Динамические адреса: программы часто загружают код и данные в разные места памяти при каждом запуске. Pattern scanning позволяет находить нужное независимо от того, где именно это оказалось.
- Уникальные совпадения: сигнатуры работают как отпечатки пальцев — они помогают распознавать конкретные области памяти по уникальным последовательностям байтов.
BytePattern
Добавлен класс BytePattern, который поддерживает несколько способов описания сигнатур. Это упрощает работу с разными типами шаблонов, которые обычно используются при сканировании памяти.
Сканирование по сигнатурам доступно для любого типа, реализующего интерфейс IMemory, например:
using var process = LocalProcess.ByProcessName("pathofexile"); //uses naive RPM under the hood
Log.Info($"Process: {process}");
var modules = process.GetProcessModules(); //enumerate all loaded modules
using var memory = process.MemoryOfModule("pathofexile.exe"); //memory implements IMemory
Log.Info($"Process memory: {memory}, base: {memory.BaseAddress.ToHexadecimal()}");
// will find a singular offset pointing at 4th byte in the sequence
var offset = memory.FindOffset(BytePattern.FromTemplate("55 8B ?? ^ EC 00"));
// will return dictionary with all found offsets for all given patterns
var playerPattern = BytePattern.FromTemplate("55 8B ?? ^ EC 00");
var targetPattern = BytePattern.FromTemplate("BB AA ??");
var offsetsByPattern = memory.FindOffset(playerPattern, targetPattern);
// by using Get* instead of Find* the code will throw an exception in case pattern is not found
var criticalOffset = memory.GetOffset(BytePattern.FromTemplate("55 8B ?? ^ EC 00"));
Поддерживаемые типы сигнатур
-
Массивы байтов
- Позволяют задавать сигнатуру точными значениями байтов.
- Пример:
var pattern = BytePattern.FromPattern(new byte[] {0x55, 0x8B, 0xEC});Точно совпадает с этими байтами.
-
Сигнатуры в C-стиле
- Используют escape-последовательности вида
\xAA\xBB\xCC, как в шаблонах C-style. - Пример:
var pattern = BytePattern.FromTemplate("\x55\x8B\xEC");Эквивалентно массиву байтов
[0x55, 0x8B, 0xEC]. - Используют escape-последовательности вида
-
Шестнадцатеричные строки с wildcards
- Сигнатура задаётся как hex-строка, где
??означает wildcard (любой байт). - Пример:
var pattern = BytePattern.FromTemplate("55 8B ?? 83");Совпадает с любой последовательностью, начинающейся с
55 8B, затем с любым байтом и потом83. - Сигнатура задаётся как hex-строка, где
-
Маскированные сигнатуры
- Сочетают массив байтов и маску, где фиксированные байты помечаются как
x, а wildcard — как?. - Пример:Совпадает с любой последовательностью, начинающейся с
var bytes = ; var mask = ; var pattern = BytePattern.FromMaskedPattern(new byte[] { 0x55, 0x8B, 0xEC, 0x00, 0x08 }, "xxx??");55 8B EC, после чего идут любые два байта.
- Сочетают массив байтов и маску, где фиксированные байты помечаются как
-
Шаблоны со смещением
- Позволяют задать сигнатуру через шаблон и отметить позицию итогового смещения символом
^. - Пример:
var pattern = BytePattern.FromTemplate("55 8B ?? ^ EC 00");В этом случае смещение ставится прямо перед
EC(то есть после пропуска3байтов). Это означает, что после нахождения сигнатуры итоговый offset будетOffset + 3. - Позволяют задать сигнатуру через шаблон и отметить позицию итогового смещения символом
Исправления и улучшения
- [UI] Небольшое исправление layout в вынесенном C# editor