mirror of
https://dev.lirent.ru/Vatrog/vm-introspection-engine.git
synced 2026-06-18 03:06:37 +03:00
Add function inventory (.pdata), signature generation, and export/PDB symbols
Three reversing capabilities on the win32 surface plus a pure sig-gen handler:
- vmie_win32_functions enumerates a module's functions from the exception
directory (.pdata RUNTIME_FUNCTION), folding unwind chain continuations into
their primary - authoritative non-leaf boundaries, not prologue heuristics.
- vmie_win32_exports resolves the export table to {name, rva, ordinal,
forwarded}: named functions with no PDB or network. vmie_win32_pdb_ref pulls
the CodeView/RSDS {guid, age, pdb} from the debug directory - the symbol-server
key for any module (full PDB parsing stays out of scope).
- sig_generate (siggen.h) builds a unique masked signature for a code span,
wildcarding the rel/RIP-relative displacement bytes the x86 decoder locates and
growing until it matches the scope exactly once - the dual of sigscan.
The decoder now also reports disp_off/disp_len so a caller can mask the floating
bytes. The MZ/PE walk gains one shared data-directory accessor and one shared
CodeView/RSDS parser; the kernel bootstrap is moved onto both, removing its
private copies - one PE parser in the tree.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
/* siggen.h - x86-64 code signature generator (pure handler).
|
||||
*
|
||||
* Turns a span of code into a UNIQUE masked byte signature suitable for the
|
||||
* sigscan matcher: opcode/ModRM/fixed bytes are must-match; the rel/RIP-relative
|
||||
* displacement bytes - the ones that "float" with the load address and with
|
||||
* relocation - are wildcarded. The result is the dual of sigscan: feed its
|
||||
* output back into sig_all/sig_first to relocate the same code in another image.
|
||||
*
|
||||
* Pure: it depends only on sigscan.h (the pattern + view types and the matcher)
|
||||
* and x86dec.h (the length decoder that locates the displacement field). It
|
||||
* touches no vmie_mem and does no I/O; build a view (e.g. a section view) and
|
||||
* pass it in.
|
||||
*/
|
||||
#ifndef VMIE_SIGGEN_H
|
||||
#define VMIE_SIGGEN_H
|
||||
#include <stddef.h>
|
||||
#include "sigscan.h" /* sig_pattern_t, mem_view_t, sig_all, sig_free */
|
||||
#include "x86dec.h" /* x86_decode + x86_insn.disp_off/disp_len */
|
||||
|
||||
/* Build a unique masked signature for the code starting at scope.data[start_off].
|
||||
* Steps instructions with x86_decode; each instruction contributes its
|
||||
* opcode/ModRM/fixed bytes as must-match (mask x) and its rel/RIP-relative
|
||||
* displacement bytes (disp_off..disp_off+disp_len) as wildcards (mask ?), since
|
||||
* those move with load address / relocation. Grows instruction by instruction
|
||||
* until the pattern occurs EXACTLY ONCE in `scope` (verified with sig_all) or
|
||||
* `max_len` bytes are consumed.
|
||||
* scope - search space the signature must be unique within (e.g. a .text
|
||||
* section view). The coordinate of uniqueness is scope's own (use
|
||||
* a MODULE_RVA / SECTION_LOCAL view for an ASLR-stable result
|
||||
* origin).
|
||||
* start_off - byte offset in `scope` where the target code begins (must be <
|
||||
* scope.size).
|
||||
* max_len - cap on signature length in bytes (e.g. 64); guards against
|
||||
* non-unique code.
|
||||
* out - on success, the generated pattern (free with sig_free()).
|
||||
* Returns the pattern length in bytes on success, 0 if it cannot be made unique
|
||||
* within max_len, -1 on bad input. The result matches `scope` exactly once, at
|
||||
* start_off.
|
||||
*
|
||||
* v1 wildcards ONLY rel/RIP-relative displacements (the dominant floating bytes);
|
||||
* absolute immediate relocations are NOT auto-wildcarded (a .reloc cross-check is
|
||||
* a future extension).
|
||||
*
|
||||
* Example - generate a portable signature for a function in .text (MODULE_RVA
|
||||
* view => an ASLR-stable origin), then relocate it elsewhere:
|
||||
* sig_pattern_t p;
|
||||
* int len = sig_generate(text_view, fn_rva - text_view.base_va, 64, &p);
|
||||
* if (len > 0) {
|
||||
* uint64_t rva = sig_first(other_text_view, &p); // re-find the function
|
||||
* sig_free(&p);
|
||||
* } */
|
||||
int sig_generate(mem_view_t scope, size_t start_off, size_t max_len,
|
||||
sig_pattern_t* out);
|
||||
|
||||
#endif /* VMIE_SIGGEN_H */
|
||||
Reference in New Issue
Block a user