
LLVM 기반으로 구축된 바이너리 분석 라이브러리로, x86, ARM, RISC-V 전반에 걸쳐 기계어를 디스어셈블링, 리프팅, 기호 실행하며, CFG 복구와 Z3 솔빙을 지원합니다.
여러 아키텍처에 걸쳐 기계어를 디스어셈블, 어셈블, 분석하기 위한 바이너리 분석 라이브러리입니다. LLVM 21을 기반으로 구축되었습니다.
기능:
Function 또는 단일 평탄화된 IGNIL 블록(CFG 불필요)을 LLVM IR로 리프팅하며, 그 위에 최적화 파이프라인(mem2reg/instcombine/GVN/DCE)을 적용.pat 시그니처 데이터베이스로부터 알려진 함수를 식별LoadedImage로 파싱: 가상 주소에 R/W/X 권한과 함께 배치된 섹션 및 ELF PT_LOAD 세그먼트, 진입점, 이미지 베이스, 임포트/익스포트 플래그가 있는 심볼, 그리고 헤더로부터 자동 감지된 아키텍처(이름을 지정할 필요 없음). loader::disassembleImage는 파일에서 채워진 Graph까지 한 번의 호출로 처리. LLVM의 llvm::object 기반이므로 추가 의존성 없음disassembler CLI — ELF 또는 PE 바이너리를 로드하고 디스어셈블리를 덤프하는 명령줄 도구로, 빠른 검사와 스크립팅에 유용dragon_c.h)과 Python API(cffi)로 위 기능 대부분을 커버(패턴 매칭 DSL 템플릿, 아키텍처별 명령어 분류 헬퍼 등 일부 C++ 전용 부분은 docs/cpp_api.md에 그렇게 문서화됨)태그된 릴리스는 플랫폼별 자체 포함 SDK 아카이브
(dragon-<version>-{linux-x64,macos-arm64,windows-x64}.{tar.gz,zip})를
GitHub Releases 페이지에서 제공합니다. LLVM이
라이브러리에 정적으로 링크되어 있으므로 이를 사용하는 데 시스템 LLVM 설치가 필요하지 않습니다; Z3는 함께 번들로 제공됩니다. 각 아카이브에는 다음이 포함됩니다:
lib/ libdragon + libdragon_c (shared) and the bundled Z3 runtime
bin/ the `disassembler` CLI (plus the DLLs on Windows)
include/ the C++ headers (dragon/...) and the C-shim header (dragon/dragon_c.h)
share/dragon/python/dragon.py the Python API
Python API가 번들 라이브러리를 가리키도록 DRAGON_C_LIB=/path/to/lib/libdragon_c.so를 설정하세요 (.dylib/.dll은 환경에 맞게).
대신 소스에서 빌드하려면:
mkdir build && cd build
cmake ..
cmake --build .
테스트를 실행하려면:
ctest --output-on-failure
x86 시맨틱 왕복 테스트 중 일부는 비용이 많이 듭니다. 이 테스트들은 리프팅된 IR을 JIT 컴파일하고 Unicorn 아래에서 원시 바이트를 대규모 엣지 케이스 입력의 교차곱(각각 수천 번의 왕복)에 걸쳐 에뮬레이션합니다. 이 테스트들은 [.][expensive] 태그가 붙어 있어 기본 ctest 실행에서는 숨겨지므로 빠르게 유지됩니다. 일반적으로 더 강력한 머신이나 CI에서 다음과 같이 명시적으로 실행하십시오:
./build/bin/dragon_tests "[expensive]"
Windows에서는 CMakeLists.txt의 의존성 탐색에 몇 가지 힌트가 필요합니다.
이는 Linux 패키지 레이아웃을 기준으로 작성되었기 때문입니다. Z3는 LLVM에
번들로 포함된 FindZ3.cmake 모듈을 통해 찾고, Unicorn은 pkg-config를
통해 찾습니다. 두 메커니즘 모두 vcpkg가 어디에 설치하는지 알지 못하며,
LLVM은 시스템 경로가 아닌 LLVM_DIR을 통해 찾습니다. 세 가지 힌트를
제공하면 이 모든 문제가 해결됩니다.
사전 요구 사항
C:\llvm-21 (미리 빌드된
clang+llvm-*-x86_64-pc-windows-msvc 릴리스가 작동함)1. vcpkg로 라이브러리 설치 (x64-windows 트리플릿, pkgconf가
Unicorn 탐색에 필요한 pkg-config 실행 파일을 제공함):
vcpkg install z3:x64-windows unicorn:x64-windows pkgconf:x64-windows
2. CMake에 필요한 세 가지 힌트
| 힌트 | 목적 | 예시 값 |
|---|---|---|
LLVM_DIR | LLVM 21 위치 지정 | C:/llvm-21/lib/cmake/llvm |
CMAKE_PREFIX_PATH | FindZ3가 vcpkg 트리를 볼 수 있도록 함 | C:/vcpkg/installed/x64-windows |
PKG_CONFIG_EXECUTABLE + PKG_CONFIG_PATH | pkg-config를 통해 Unicorn을 찾을 수 있도록 함 | .../tools/pkgconf/pkgconf.exe 및 .../installed/x64-windows/lib/pkgconfig |
3a. 구성 및 빌드 (단일 명령)
$env:PKG_CONFIG_PATH = "C:/vcpkg/installed/x64-windows/lib/pkgconfig"
cmake -S . -B build `
-DLLVM_DIR=C:/llvm-21/lib/cmake/llvm `
-DCMAKE_PREFIX_PATH=C:/vcpkg/installed/x64-windows `
-DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe `
-DDRAGON_USE_Z3=ON -DDRAGON_USE_UNICORN=ON
cmake --build build --config Release
성공적으로 configure를 실행하면 다음이 출력됩니다:
-- Found LLVM 21.1.8 at C:/llvm-21/lib/cmake/llvm
-- Found Z3 5.0.0 at C:/vcpkg/installed/x64-windows/lib/libz3.lib
-- Found Unicorn 2.1.4
3b. 또는 프리셋 사용(권장)
CMakeLists.txt 옆에 있는 CMakeUserPresets.json에 설정을 한 번 저장한 다음,
플래그 하나로 구성하세요. 이 파일에는 머신별 경로가 포함되므로
버전 관리에서 제외하세요(git-ignore됨).
{
"version": 3,
"configurePresets": [
{
"name": "win-vcpkg",
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"LLVM_DIR": "C:/llvm-21/lib/cmake/llvm",
"CMAKE_PREFIX_PATH": "C:/vcpkg/installed/x64-windows",
"PKG_CONFIG_EXECUTABLE": "C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe",
"DRAGON_USE_Z3": "ON",
"DRAGON_USE_UNICORN": "ON"
},
"environment": {
"PKG_CONFIG_PATH": "C:/vcpkg/installed/x64-windows/lib/pkgconfig"
}
}
],
"buildPresets": [
{ "name": "win-vcpkg", "configurePreset": "win-vcpkg", "configuration": "Release" }
]
}
cmake --preset win-vcpkg
cmake --build build --config Release
참고 사항
경로를 자신의 머신에 맞게 조정하세요. vcpkg가 다른 곳에 있다면 %VCPKG_ROOT%를 그에 맞게 설정하고, LLVM을 다른 곳에 압축 해제했다면 LLVM_DIR을 해당 트리의 lib/cmake/llvm을 가리키도록 하세요.
여기서 vcpkg의 툴체인 파일(-DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake)을 전달하지 마세요. 이 파일은 패키지 검색을 제한하여 CMake가 vcpkg 외부에 있는 LLVM을 찾지 못하게 하는데, 이는 이 프로젝트의 일반적인 설정입니다.
Unicorn은 선택 사항입니다. 작동하는 pkg-config가 없으면 단순히 비활성화되며 tests/semantic/ 왕복 테스트만 건너뜁니다. 반면 Z3는 DRAGON_USE_Z3=ON일 때마다 필수입니다.
항상 Release 구성을 빌드하세요. 미리 빌드된 clang+llvm-*-windows-msvc 패키지는 Release 라이브러리만 제공하며, 이는 동적 릴리스 CRT(/MD)를 사용합니다. Visual Studio 생성기는 --config가 주어지지 않으면 기본적으로 Debug(/MDd)를 사용하며, Debug 프로젝트 코드를 Release LLVM에 링크하면 수백 개의 LNK2038 런타임 라이브러리 / _ITERATOR_DEBUG_LEVEL 불일치가 발생하고 결국 LNK1319로 끝납니다. 모든 cmake --build에서 --config Release를 전달하세요(또는 역시 /MD인 RelWithDebInfo를 사용하세요):
cmake --build build --config Release -j
include/ C++ public headers (dragon/)
lib/ C++ implementation
c_shim/ C API (dragon_c.h + libdragon_c.so)
python/ Python API (cffi, wraps the C shim)
tool/ CLI tools (disassembler, opcode_audit)
tests/ Catch2 test suite
docs/ API documentation, examples, and the manual
공개 헤더는 include/dragon/ 아래에 있으며, 영역별로 그룹화되어 있습니다
(disassembler/, lifters/, analysis/, loader/, sigs/). 전체 API 표면은
아래의 API 문서를 참조하세요.
모든 API 계층에 대한 전체 예제는 docs/에 있습니다:
docs/cpp_api.md — C++ APIdocs/c_api.md — C shim APIdocs/python_api.md — Python APIIGNIL.md — IGNIL 설계 및 구현 가이드클래스가 아닌 작업 기준으로 구성된 실습 안내서는
docs/manual/에 있습니다 — 원시 바이트에서 IGNIL과 LLVM
IR을 거쳐 심볼릭 실행까지 다룹니다.
C++
#include <dragon/disassembler/Disassembler.hpp>
dragon::Configuration config;
dragon::Disassembler dis(dragon::Architecture::X86_64, config);
auto instructions = dis.disassemble(bytes, base_address);
for (const auto& insn : instructions)
std::cout << std::hex << insn.address() << " " << insn.disassembly() << "\n";
Python
import sys
sys.path.insert(0, 'python')
import dragon