mirror of
https://dev.lirent.ru/Vatrog/vm-introspection-engine.git
synced 2026-07-09 00:46:36 +03:00
Add operand-normalized semantic code signatures
New semsig_hash(mem_view_t) primitive (include/semsig.h): a position-,
register-, immediate- and instruction-order-invariant function fingerprint.
It folds per-instruction operand-canonical tokens, splitting the body into
basic blocks via cfg_blocks and using a within-block order-insensitive
sort-then-fold (between-block order preserved), so it survives compiler
register reallocation and instruction scheduling that the byte-mask
func_hash/sig_generate cannot. Distinct hash domain from func_hash.
The operand decode is delegated to an OPTIONAL external disassembler behind
a private adapter seam (src/handlers/semsig_backend.h); semsig.c stays
backend-neutral and includes no backend header. VMIE_DISASM={OFF|zydis|
capstone} gates the build: OFF (default) compiles only semsig_stub.c and
keeps the zero-dependency build (VMIE_HAVE_DISASM=0, packages unchanged).
The backend is brought from VMIE_DISASM_SRC or find_package - never
vendored. Adds the vmie_win32_func_semsig wrapper.
The CI deb job builds with the Zydis backend (libzydis-dev); the runtime
package dependency on libzydis is derived automatically by dpkg-shlibdeps.
This commit is contained in:
@@ -12,6 +12,18 @@ include(GNUInstallDirs)
|
||||
|
||||
option(VMIE_LTO "Enable LTO" OFF) # build-only; shipped default is -O2, no LTO
|
||||
|
||||
# ---- optional semantic-signature backend (operand disassembler) ----------
|
||||
# VMIE_DISASM selects the OPTIONAL operand-decode backend for the semantic
|
||||
# signature feature (semsig.h). OFF (default) ships the 0.1.6 behaviour: the
|
||||
# generic symbol exists via semsig_stub.c, returns 0, VMIE_HAVE_DISASM=0, and no
|
||||
# external library is pulled - CI and the .deb packages are unchanged. A backend
|
||||
# (zydis|capstone) is NEVER vendored: it is brought from OUTSIDE the tree, either
|
||||
# by VMIE_DISASM_SRC (a path to the backend's own source tree, add_subdirectory'd)
|
||||
# or, failing that, by find_package of an already-installed library.
|
||||
set(VMIE_DISASM "OFF" CACHE STRING "Semantic-signature backend: OFF | zydis | capstone")
|
||||
set_property(CACHE VMIE_DISASM PROPERTY STRINGS OFF zydis capstone)
|
||||
set(VMIE_DISASM_SRC "" CACHE PATH "Path to the disassembler backend source tree (external; add_subdirectory'd)")
|
||||
|
||||
# ---- host: VMI core objects (single owner of the source list) -----------
|
||||
add_library(vmie_obj OBJECT
|
||||
src/core/gpa.c
|
||||
@@ -31,6 +43,23 @@ add_library(vmie_obj OBJECT
|
||||
src/handlers/x86dec.c
|
||||
src/handlers/pmap.c
|
||||
src/handlers/snapdiff.c)
|
||||
|
||||
# semantic-signature TUs: OFF compiles ONLY the stub (which carries the whole
|
||||
# generic symbol and returns 0); a backend compiles the core (semsig.c) + the one
|
||||
# backend TU that talks to the disassembler. semsig.c is never built in OFF (it
|
||||
# calls the backend decode, absent there) - so there is no dead/unresolved call.
|
||||
if(VMIE_DISASM STREQUAL "OFF")
|
||||
target_sources(vmie_obj PRIVATE src/handlers/semsig_stub.c)
|
||||
elseif(VMIE_DISASM STREQUAL "zydis")
|
||||
target_sources(vmie_obj PRIVATE src/handlers/semsig.c
|
||||
src/handlers/semsig_backend_zydis.c)
|
||||
elseif(VMIE_DISASM STREQUAL "capstone")
|
||||
target_sources(vmie_obj PRIVATE src/handlers/semsig.c
|
||||
src/handlers/semsig_backend_capstone.c)
|
||||
else()
|
||||
message(FATAL_ERROR "VMIE_DISASM must be OFF, zydis, or capstone (got '${VMIE_DISASM}')")
|
||||
endif()
|
||||
|
||||
target_include_directories(vmie_obj
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include # public API: include/*.h
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include # private: core.h
|
||||
@@ -42,11 +71,49 @@ if(VMIE_LTO)
|
||||
target_link_options(vmie_obj PRIVATE -flto)
|
||||
endif()
|
||||
|
||||
# Resolve the backend target/package name (the actual link/define is applied to
|
||||
# vmie_obj here AND re-applied to the static/shared libs below, because
|
||||
# $<TARGET_OBJECTS:vmie_obj> carries object files only - not link/define usage
|
||||
# requirements). The backend is PRIVATE (an implementation detail), while
|
||||
# VMIE_HAVE_DISASM is PUBLIC (visible through semsig.h). The backend comes from
|
||||
# VMIE_DISASM_SRC (external sources) or find_package - never from in-tree sources.
|
||||
if(NOT VMIE_DISASM STREQUAL "OFF")
|
||||
if(VMIE_DISASM STREQUAL "zydis")
|
||||
set(VMIE_DISASM_LINK "Zydis::Zydis")
|
||||
set(_vmie_disasm_pkg "Zydis")
|
||||
else()
|
||||
set(VMIE_DISASM_LINK "capstone::capstone")
|
||||
set(_vmie_disasm_pkg "capstone")
|
||||
endif()
|
||||
|
||||
if(VMIE_DISASM_SRC)
|
||||
# Build the backend from its OWN external source tree (kept out of this
|
||||
# repo). Its CMake exports the imported target linked below.
|
||||
add_subdirectory(${VMIE_DISASM_SRC} ${CMAKE_CURRENT_BINARY_DIR}/_disasm_backend)
|
||||
else()
|
||||
find_package(${_vmie_disasm_pkg} REQUIRED)
|
||||
endif()
|
||||
|
||||
target_link_libraries(vmie_obj PRIVATE ${VMIE_DISASM_LINK})
|
||||
target_compile_definitions(vmie_obj PUBLIC VMIE_HAVE_DISASM=1)
|
||||
else()
|
||||
set(VMIE_DISASM_LINK "")
|
||||
target_compile_definitions(vmie_obj PUBLIC VMIE_HAVE_DISASM=0)
|
||||
endif()
|
||||
|
||||
# ---- host: static library (in-tree consumers: CLIs + test) --------------
|
||||
# $<TARGET_OBJECTS:> carries object files only, not usage requirements:
|
||||
# re-declare the PUBLIC include scope so vmie_cli/vmie_scan still see include/.
|
||||
add_library(vmie STATIC $<TARGET_OBJECTS:vmie_obj>)
|
||||
target_include_directories(vmie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
# Re-apply the feature macro (PUBLIC: seen by in-tree consumers + the test) and
|
||||
# the backend link (PRIVATE), which $<TARGET_OBJECTS> does not carry over.
|
||||
if(VMIE_DISASM STREQUAL "OFF")
|
||||
target_compile_definitions(vmie PUBLIC VMIE_HAVE_DISASM=0)
|
||||
else()
|
||||
target_compile_definitions(vmie PUBLIC VMIE_HAVE_DISASM=1)
|
||||
target_link_libraries(vmie PRIVATE ${VMIE_DISASM_LINK})
|
||||
endif()
|
||||
|
||||
# ---- host: shared library (external delivery: libvmie.so.*) -------------
|
||||
add_library(vmie_shared SHARED $<TARGET_OBJECTS:vmie_obj>)
|
||||
@@ -58,6 +125,12 @@ set_target_properties(vmie_shared PROPERTIES
|
||||
if(VMIE_LTO)
|
||||
target_link_options(vmie_shared PRIVATE -flto)
|
||||
endif()
|
||||
if(VMIE_DISASM STREQUAL "OFF")
|
||||
target_compile_definitions(vmie_shared PUBLIC VMIE_HAVE_DISASM=0)
|
||||
else()
|
||||
target_compile_definitions(vmie_shared PUBLIC VMIE_HAVE_DISASM=1)
|
||||
target_link_libraries(vmie_shared PRIVATE ${VMIE_DISASM_LINK})
|
||||
endif()
|
||||
|
||||
# ---- host: CLI demonstrator over the library ----------------------------
|
||||
add_executable(vmie_cli src/cli.c)
|
||||
|
||||
Reference in New Issue
Block a user