Skip to content

eversinc33/Karyo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Karyo

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.

Quick start

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

Using Karyo as a git submodule

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.

Building

# 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

Requirements

  • CMake >= 3.20
  • C++17 compiler (GCC >= 9, Clang >= 10)
  • LLVM (same version as your consuming lifter)

About

[100% AI Generated Code] Lightweight LLVM Symbolic Execution Engine

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors