Karyo is a lightweight C++ library for symbolic and concrete execution of Remill-generated LLVM bitcode (x86). It lets you execute a Remill IR function with a mix of concrete and symbolic input register values, observe intermediate state via callbacks, and query output register values as concrete values or symbolic expression trees. Built specifically for VMP handler analysis and similar Remill-based reverse engineering workflows.
Core value: Given a Remill handler in LLVM IR, determine the value of a register (e.g. EBP) at the dispatch point — as a concrete value or a symbolic expression over the handler's inputs.
#include "karyo/Engine.h"
karyo::Engine engine;
engine.setESI(llvm::APInt(32, 0x401000u)); // seed input registers
engine.setEBP(llvm::APInt(32, 0x1000u));
engine.on_indirect_branch = [](karyo::ExecutionState&) { /* dispatch reached */ };
auto results = engine.run(handler_fn); // handler_fn is an llvm::Function&
for (auto& state : results) {
auto ebp = karyo::Engine::getEBP(state); // concrete APInt or symbolic ExprRef
}Karyo is consumed as a CMake submodule. The parent project finds LLVM once,
then adds Karyo as a subdirectory and links the karyo::karyo target.
# Parent CMakeLists.txt
find_package(LLVM REQUIRED CONFIG) # Parent finds LLVM once (sets LLVM_FOUND)
add_subdirectory(third_party/karyo) # Karyo's if(NOT LLVM_FOUND) guard skips
# the redundant find_package (ENG-05)
add_executable(my_tool main.cpp)
target_link_libraries(my_tool PRIVATE karyo::karyo) # ENG-04
# Karyo's PUBLIC include dirs propagate automatically — no include_directories needed.Karyo links only the LLVM core and support components (not all 300+ libs),
and exposes its include/ directory PUBLIC while keeping LLVM include paths
PRIVATE — consumers get LLVM headers from their own find_package(LLVM).
Karyo must be built against the same LLVM version as the consuming lifter
to avoid ABI mismatch on llvm::Value* / llvm::LLVMContext pointers passed
across the boundary.
# Library only
cmake -S . -B build
cmake --build build
# With unit tests
cmake -S . -B build -DKARYO_BUILD_TESTS=ON
cmake --build build
ctest --test-dir build
# With examples (requires examples/vmp_handler.ll)
cmake -S . -B build -DKARYO_BUILD_EXAMPLES=ON
cmake --build build --target karyo_example
./build/examples/karyo_example- CMake >= 3.20
- C++17 compiler (GCC >= 9, Clang >= 10)
- LLVM (same version as your consuming lifter)