Code cave — это свободный участок внутри PE-модуля, обычно заполненный нулями. Его можно использовать под данные, небольшой payload, trampoline или служебный буфер. По общей идее полезны Code Caves & DLL's, DLL Memory Hack и DLL Injector.
Искать code cave нужно на памяти конкретного модуля:
using System.Diagnostics;
using EyeAuras.Memory;
using EyeAuras.Memory.Scaffolding;
using var process = LocalProcess.ByProcessId(Process.GetCurrentProcess().Id);
using var moduleMemory = process.MemoryOfModule("kernel32.dll");
После этого можно перечислить кандидатов:
var caves = moduleMemory.EnumerateCodeCaves(
minBytes: 64,
alignment: 16);
Каждый результат приходит как CodeCaveEntry. На практике чаще всего важны Section, StartVA, StartRva и Size.
Не каждый cave подходит для одних и тех же задач. Обычно сценарии делятся так:
readable + writable + not executable — строки, структуры, аргументы, служебные данныеreadable + executable — trampoline, payload, redirectionДля этого есть sectionFilter:
var dataCave = moduleMemory.EnumerateCodeCaves(
minBytes: 128,
alignment: 2,
sectionFilter: s => s.IsReadable && s.IsWritable && !s.IsExecutable)
.FirstOrDefault();
var execCave = moduleMemory.EnumerateCodeCaves(
minBytes: 64,
alignment: 16,
sectionFilter: s => s.IsReadable && s.IsExecutable)
.FirstOrDefault();
EnumerateCodeCaves(...):
jmpЭто только поиск подходящего места.
Если вам нужно не просто найти cave, а реально подготовить его под patching или payload, используйте явные ProtectMemory(...) и FreeMemory(...) из IProcessControlApi. Короткий стартовый пример есть в Memory API - С чего начать.
MemoryOfModule(...), а не на всей памяти процесса.LocalProcess, NativeLocalProcess или KDProcess.LCProcess поиск cave полезен как анализ, но не как обычный инструмент управления процессом.