mirror of
https://dev.lirent.ru/Vatrog/vm-introspection-engine.git
synced 2026-06-18 04:16:39 +03:00
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.
This commit is contained in:
+112
@@ -0,0 +1,112 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "include/memory.h"
|
||||
#include "../include/include.h"
|
||||
|
||||
#define pr_(ctx) (ctx->prof)
|
||||
|
||||
#define RING_GUARD 100000u
|
||||
#define MOD_GUARD 4096u
|
||||
|
||||
static void grab_ustr(gva_ctx* ctx, uintptr_t cr3, uint64_t va, gtext* out) {
|
||||
uint16_t len = 0;
|
||||
uint64_t buf = 0;
|
||||
out->va = 0;
|
||||
out->len = 0;
|
||||
if (gva_read(ctx, cr3, va, &len, 2) || gva_read(ctx, cr3, va + 8, &buf, 8)) {
|
||||
return;
|
||||
}
|
||||
out->va = buf;
|
||||
out->len = len;
|
||||
}
|
||||
|
||||
int proc_list(gva_ctx* ctx, int skip_system, process* dst, size_t nmax) {
|
||||
const profile* p = &pr_(ctx);
|
||||
const uint64_t kcr3 = ctx->kcr3;
|
||||
if (!kcr3 || !ctx->sysproc) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t n = 0;
|
||||
unsigned guard = 0;
|
||||
uint64_t ep = ctx->sysproc, node;
|
||||
|
||||
do {
|
||||
uint64_t pid = 0, ppid = 0, dtb = 0, peb = 0;
|
||||
gva_read(ctx, kcr3, ep + p->ep_pid, &pid, 8);
|
||||
gva_read(ctx, kcr3, ep + p->ep_dtb, &dtb, 8);
|
||||
if (p->ep_peb) { gva_read(ctx, kcr3, ep + p->ep_peb, &peb, 8); }
|
||||
if (p->ep_ppid) { gva_read(ctx, kcr3, ep + p->ep_ppid, &ppid, 8); }
|
||||
|
||||
if (!skip_system || peb) {
|
||||
if (n >= nmax) {
|
||||
return (int)n;
|
||||
}
|
||||
process* q = &dst[n++];
|
||||
q->eprocess = ep;
|
||||
q->cr3 = dtb & PFN_MASK;
|
||||
q->peb = peb;
|
||||
q->pid = (uint32_t)pid;
|
||||
q->ppid = p->ep_ppid ? (uint32_t)ppid : (uint32_t)-1;
|
||||
q->create_time = 0;
|
||||
if (p->ep_createtime) {
|
||||
gva_read(ctx, kcr3, ep + p->ep_createtime, &q->create_time, 8);
|
||||
}
|
||||
memset(q->name, 0, sizeof q->name);
|
||||
gva_read(ctx, kcr3, ep + p->ep_name, q->name, sizeof q->name - 1);
|
||||
q->path.va = 0;
|
||||
q->path.len = 0;
|
||||
if (p->ep_imgpath) {
|
||||
grab_ustr(ctx, kcr3, ep + p->ep_imgpath, &q->path); /* read text under kcr3 */
|
||||
}
|
||||
}
|
||||
|
||||
if (gva_read(ctx, kcr3, ep + p->ep_links, &node, 8)) {
|
||||
break;
|
||||
}
|
||||
ep = node - p->ep_links;
|
||||
} while (ep != ctx->sysproc && ++guard < RING_GUARD);
|
||||
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
int proc_modules(gva_ctx* ctx, const process* pr, pmodule* dst, size_t nmax) {
|
||||
const profile* p = &pr_(ctx);
|
||||
const uint64_t cr3 = pr->cr3;
|
||||
if (!pr->peb || !cr3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t ldr = 0, head, link;
|
||||
if (gva_read(ctx, cr3, pr->peb + p->peb_ldr, &ldr, 8) || !ldr) {
|
||||
return 0;
|
||||
}
|
||||
head = ldr + p->ldr_loadlist;
|
||||
if (gva_read(ctx, cr3, head, &link, 8)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t n = 0;
|
||||
unsigned guard = 0;
|
||||
while (link != head && n < nmax && ++guard < MOD_GUARD) {
|
||||
const uint64_t entry = link; /* InLoadOrderLinks at offset 0 of the entry */
|
||||
uint64_t base = 0;
|
||||
uint32_t size = 0;
|
||||
gva_read(ctx, cr3, entry + p->lde_base, &base, 8);
|
||||
gva_read(ctx, cr3, entry + p->lde_size, &size, 4);
|
||||
|
||||
pmodule* m = &dst[n++];
|
||||
m->pr = pr;
|
||||
m->entry = entry;
|
||||
m->base = base;
|
||||
m->size = size;
|
||||
grab_ustr(ctx, cr3, entry + p->lde_name, &m->name);
|
||||
grab_ustr(ctx, cr3, entry + p->lde_fullname, &m->path);
|
||||
|
||||
if (gva_read(ctx, cr3, link, &link, 8)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (int)n;
|
||||
}
|
||||
Reference in New Issue
Block a user