#include #include #include #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; }