Чтение и запись памяти произвольного процесса в Windows без OpenProcess /
ReadProcessMemory / WriteProcessMemory. Страница цели переводится в
физический адрес по её таблицам страниц, физическая страница маппится в наш
процесс через section над \Device\PhysicalMemory — маппинг выполняет
подписанный уязвимый драйвер Panda Security (\Device\PSMEMDriver,
бинарники в driver/). Классическая BYOVD-техника.
Проект предназначен для авторизованных исследований (воспроизведение техники, построение детекций) на собственной лабораторной VM.
main.cpp CLI-харнесс
|
gomik.mirror C_Mirror: окна страниц цели + LRU, Pin/Read/Write/Snapshot
gomik.xlate C_Translator: CR3 цели (EPROCESS), ходок по таблицам страниц
gomik.mem примитивы драйвера: MDL copy-out, section, map/unmap view
gomik.driver C_Driver: \\.\PSMEMDriver, DeviceIoControl, JSONL-трейс
gomik.abi раскладка запросов драйвера (pack(1))
Непрерывный по VA регион цели физически фрагментирован, поэтому «зеркало» — таблица окон: одна физическая страница цели = один view у нас. Два режима: оконный (устойчивые указатели, LRU-вытеснение) и snapshot (map→memcpy→unmap).
Linux → Windows x64 кроссом (clang + MinGW-w64, Ninja):
cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=<путь>/windows-clang-mingw.cmake
cmake --build buildC++20 modules, сторонних зависимостей нет.
После сборки забери build/gomik.exe и driver/*.sys на целевую машину
(например, driver/ рядом с exe).
Драйвер загружается один раз через SCM (нужен админ); путь по умолчанию —
driver\Priorly1064.sys рядом с exe:
gomik driver load
gomik driver unload
Зеркало памяти чужого процесса (пример — чтение KUSER_SHARED_DATA):
gomik mirror <pid> read 0x7FFE0000 0x40
gomik mirror <pid> write <va> <hexbytes>
gomik mirror <pid> pin <va>
Диагностика бутстрапа (база ntoskrnl, System EPROCESS, CR3):
gomik probe
Трассировка всех IOCTL в JSONL (по строке на вызов) — переменная окружения
GOMIK_TRACE=<файл>.
add_subdirectory(gomik)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE gomik_core)
set_property(TARGET my_app PROPERTY CXX_SCAN_FOR_MODULES ON)#include <windows.h>
import gomik;
int main() noexcept
{
gomik::C_Mirror mirror(targetPid);
if (mirror.initialize() != gomik::gomik_error_e::OK) {
return 1;
}
uint8_t buffer[64];
mirror.Read(0x7FFE0000, buffer, sizeof(buffer)); // KUSER_SHARED_DATA цели
return 0;
}Ошибки — gomik::expected<T, gomik_error_e> (мини-класс в src/util/expected.h),
исключения не используются. Устойчивый указатель на страницу цели даёт Pin,
разовое чтение без кэша окон — Snapshot.
Выяснено экспериментально на Win10 x64 (build 19044):
| # | Особенность | Следствие |
|---|---|---|
| 1 | MDL-чтение не обновляет outStatus |
успех = bytesReturned == 65 + size |
| 2 | MDL-чтение > 8 байт: 0x40 — отказ, page-size — подвешивает систему |
чтения режутся на 8 байт (MDL_MAX_CHUNK) |
| 3 | MDL-чтение работает только по образу ntoskrnl, pool-адреса — отказ | CR3 ищется fallback'ом: скан RAM на self-map PML4 → EPROCESS физическими окнами |
| 4 | CREATE_SECTION возвращает STATUS_PENDING, не SUCCESS |
валидация по хэндлу, статус игнорируется |
| 5 | Состояние драйвера деградирует после убитых клиентов | лечение — перезагрузка VM |
driver/ бинарники драйвера (Priorly*.sys)
src/gomik.cppm зонтик: export module gomik
src/defs/ коды ошибок, константы
src/abi/ структуры запросов драйвера
src/driver/ транспорт + трассировка
src/mem/ примитивы A-D
src/xlate/ таблицы страниц, EPROCESS, RAM-диапазоны
src/mirror/ зеркальная сессия
src/util/ expected, seh_guard, lru_cache, noncopyable