Files
vatrog-vm-introspection-engine/src/gpa.c
T
lirent 1ec70b7ede Windows guest VMI core: host library, CLI, guest agent
Static library over a flat RW mmap of guest RAM: GPA/GVA paging walks,
beacon-driven bootstrap, dynamic struct-offset profiling, process and
module enumeration, a region map, and value/pointer/signature scanners on
a shared windowed sweep. Public API in include/; internals under src/.

Thin CLI demonstrator over the public API. Guest agent cross-compiled to
Windows x86-64 via mingw-w64. CMake: static library + CLI + guest target,
C17.
2026-06-14 21:47:56 +03:00

106 lines
2.3 KiB
C

#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "include/memory.h"
#define RAM_H (1ul<<32)
#define PROT_RW (PROT_READ | PROT_WRITE)
__attribute__((hot))
static int gpa_offset(const gpa_ctx* ctx, uintptr_t offs, uintptr_t* out) {
if (offs < ctx->low) {
*out = offs;
return 0;
}
if (offs >= RAM_H) {
const uint64_t x = ctx->low + (offs - RAM_H);
if (x < ctx->fsize) {
*out = x;
return 0;
} else { /* Out of bounds */ }
} else { /* Not RAM */ }
return -1;
}
static void clean_ctx(gpa_ctx* ctx) {
memset(ctx, 0, sizeof(gpa_ctx));
ctx->fd = -1;
}
static int out_of_bounds(gpa_ctx* ctx, uintptr_t* offs, const size_t nmemb) {
return gpa_offset(ctx, *offs, offs) || *offs + nmemb > ctx->fsize;
}
__attribute__((hot))
int gpa_read(gpa_ctx* ctx, uintptr_t offs, void* buf, const size_t nmemb) {
if (out_of_bounds(ctx, &offs, nmemb)) {
return -1;
}
memcpy(buf, ctx->pa + offs, nmemb);
return 0;
}
int gpa_write(gpa_ctx* ctx, uintptr_t offs, const void* src, const size_t nmemb) {
if (out_of_bounds(ctx, &offs, nmemb)) {
return -1;
}
memcpy(ctx->pa + offs, src, nmemb);
return 0;
}
/* Zero-copy host pointer to [offs, offs+nmemb) GPA, or NULL if that range is not
* fully backed by the mapped image. Same split + bounds check as gpa_read. */
void* gpa_ptr(gpa_ctx* ctx, uintptr_t offs, const size_t nmemb) {
if (out_of_bounds(ctx, &offs, nmemb)) {
return NULL;
}
return (uint8_t*)ctx->pa + offs;
}
__attribute__((cold))
int gpa_open(gpa_ctx* ctx, const char* path, uintptr_t low) {
struct stat st;
if ((ctx->fd = open(path, O_RDWR)) < 0) {
goto ret_;
}
if (fstat(ctx->fd, &st)) {
goto close_;
}
if ((ctx->pa = mmap(NULL, st.st_size, PROT_RW, MAP_SHARED, ctx->fd, 0)) == MAP_FAILED) {
close_:
close(ctx->fd);
ret_:
clean_ctx(ctx);
return -1;
}
ctx->fsize = st.st_size;
ctx->low = low;
return 0;
}
__attribute__((cold))
void gpa_close(gpa_ctx* ctx) {
if (ctx->pa) {
munmap(ctx->pa, ctx->fsize);
}
if (ctx->fd >= 0) {
close(ctx->fd);
}
clean_ctx(ctx);
}