mirror of
https://dev.lirent.ru/Vatrog/vm-introspection-engine.git
synced 2026-06-18 02:06:36 +03:00
Add a dump-scan demonstrator (vmie_scan)
A thin CLI proving the OS-agnostic dump path end to end: open one or more raw memory dumps as flat identity images (vmie_mem) and scan them all for an IDA-style pattern, printing each hit as source:gpa. Two-pass (count, then size the buffer exactly) so nothing is silently truncated. Kept separate from vmie_cli rather than folded in as a subcommand: vmie_cli demonstrates live win32 bring-up, this demonstrates the source-agnostic scan. Its source includes only the public memmodel/sigscan/scan headers and names no Windows symbol - it compiles against include/ alone.
This commit is contained in:
@@ -35,6 +35,11 @@ add_executable(vmie_cli src/cli.c)
|
||||
target_link_libraries(vmie_cli PRIVATE vmie) # public include/ comes via vmie (PUBLIC)
|
||||
target_compile_options(vmie_cli PRIVATE -Wall -Wextra)
|
||||
|
||||
# ---- host: dump-scan demonstrator (OS-agnostic, no win32) ----------------
|
||||
add_executable(vmie_scan src/scan_cli.c)
|
||||
target_link_libraries(vmie_scan PRIVATE vmie)
|
||||
target_compile_options(vmie_scan PRIVATE -Wall -Wextra)
|
||||
|
||||
# ---- guest: cross-compile to Windows x86-64 via mingw-w64 ---------------
|
||||
find_program(MINGW_CC NAMES x86_64-w64-mingw32-gcc REQUIRED)
|
||||
set(VMIE_STARTUP ${CMAKE_CURRENT_BINARY_DIR}/vmie-startup.exe)
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/* scan_cli.c - thin demonstrator of the OS-agnostic dump -> signature path.
|
||||
*
|
||||
* Opens one or more raw memory dumps as flat physical images (vmie_mem) and
|
||||
* scans them all for an IDA-style byte pattern, printing every hit as
|
||||
* "source:gpa". No guest, no bootstrap, no win32: this links only the dump
|
||||
* source (core), the physical signature bridge, and the pure matcher - proof
|
||||
* that scanning a dump needs nothing from the Windows engine.
|
||||
*
|
||||
* argv[1] IDA pattern, e.g. "48 8B 05 ? ? ? ? 48 85 C0"
|
||||
* argv[2..] one or more dump files, each mapped as a flat identity image
|
||||
* (reported GPA == file offset)
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include "memmodel.h" /* vmie_mem_open / vmie_mem_close */
|
||||
#include "sigscan.h" /* sig_parse_ida / sig_pattern_t / sig_free */
|
||||
#include "scan.h" /* sig_scan_sources / sig_hit_src */
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s <ida-pattern> <dump-file> [dump-file...]\n",
|
||||
argc > 0 ? argv[0] : "vmie_scan");
|
||||
return 2;
|
||||
}
|
||||
|
||||
sig_pattern_t pat;
|
||||
if (!sig_parse_ida(argv[1], &pat)) {
|
||||
fprintf(stderr, "error: bad IDA pattern: '%s'\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const int nsrc = argc - 2;
|
||||
vmie_mem** srcs = calloc((size_t)nsrc, sizeof *srcs);
|
||||
if (!srcs) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
sig_free(&pat);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rc = 0, opened = 0;
|
||||
for (int i = 0; i < nsrc; i++) {
|
||||
const char* path = argv[2 + i];
|
||||
srcs[i] = vmie_mem_open(path, ~0ull); /* low >= fsize => flat identity dump */
|
||||
if (!srcs[i]) {
|
||||
fprintf(stderr, "error: cannot open dump '%s'\n", path);
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
opened++;
|
||||
}
|
||||
|
||||
{
|
||||
/* count pass (out == NULL), then size the buffer exactly: no caps, no
|
||||
* silent truncation. */
|
||||
const int total = sig_scan_sources(srcs, nsrc, &pat, NULL, 0);
|
||||
if (total < 0) {
|
||||
fprintf(stderr, "error: scan failed (%d)\n", total);
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
if (total == 0) {
|
||||
printf("no matches in %d source(s)\n", nsrc);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sig_hit_src* hits = malloc((size_t)total * sizeof *hits);
|
||||
if (!hits) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
rc = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
const int got = sig_scan_sources(srcs, nsrc, &pat, hits, total);
|
||||
for (int i = 0; i < got; i++) {
|
||||
printf("%d:%016" PRIx64 " %s\n",
|
||||
hits[i].source, hits[i].gpa, argv[2 + hits[i].source]);
|
||||
}
|
||||
printf("%d match(es) across %d source(s)\n", got, nsrc);
|
||||
free(hits);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
for (int i = 0; i < opened; i++) {
|
||||
vmie_mem_close(srcs[i]);
|
||||
}
|
||||
free(srcs);
|
||||
sig_free(&pat);
|
||||
return rc;
|
||||
}
|
||||
Reference in New Issue
Block a user