PE это формат .exe и .dll в Windows. В контексте Memory API это важно потому, что большая часть удобной работы идёт не с "произвольным адресом", а с конкретным модулем: его секциями, импортами, экспортами и RVA. Для внешнего контекста полезны Game Fundamentals, DLL Injector и PE/COFF Spec.
.exe или .dllRVA — адрес относительно базы модуляVA — абсолютный адрес в памяти процесса.text, .rdata, .dataЕсли база модуля 0x7FF700000000, а RVA равен 0x1234, то VA будет BaseAddress + 0x1234.
Нормальный маршрут почти всегда такой:
Для этого и нужен MemoryOfModule(...):
using System.Diagnostics;
using System.Linq;
using EyeAuras.Memory;
using EyeAuras.Memory.Scaffolding;
using var process = LocalProcess.ByProcessId(Process.GetCurrentProcess().Id);
using var kernel32 = process.MemoryOfModule("kernel32.dll");
После этого kernel32 это уже не вся память процесса, а окно на конкретный PE-образ.
Для PE-практики чаще всего нужны:
ReadSections()ReadExports()ReadImports()var sections = kernel32.ReadSections();
var exports = kernel32.ReadExports();
var mainModule = process.GetProcessModules()
.First(x => x.ModuleName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase));
using var mainMemory = process.MemoryOfModule(mainModule);
var imports = mainMemory.ReadImports();
Этого обычно хватает, чтобы:
IAT-patching, pattern scanning или code cavePE-база нужна почти везде, где вы хотите уйти от мышления "вот случайный адрес" к более устойчивой модели:
RVAИменно эта модель потом лучше всего стыкуется с сигнатурами, инжектом и patching-сценариями.