
مكتبة لتحليل الملفات الثنائية مبنية على LLVM لتفكيك الشيفرة الآلية ورفعها وتنفيذها رمزياً عبر معماريات x86 وARM وRISC-V، مع استرداد CFG والحل باستخدام Z3.
مكتبة لتحليل الملفات الثنائية (binary analysis) مخصصة لتفكيك (disassembling) وتجميع (assembling) وتحليل الشيفرة الآلية (machine code) عبر معماريات متعددة. مبنية على LLVM 21.
الميزات:
Function مستردة، أو كتلة IGNIL مسطّحة واحدة (دون الحاجة إلى CFG)، إلى LLVM IR، مع خط أنابيب تحسين (mem2reg/instcombine/GVN/DCE) فوق ذلك.patLoadedImage: الأقسام ومقاطع ELF PT_LOAD عند عناوينها الافتراضية مع أذونات R/W/X، ونقطة الدخول، وقاعدة الصورة (image base)، والرموز مع أعلام الاستيراد/التصدير، والمعمارية المكتشفة تلقائيًا من الترويسة (دون حاجة لتسميتها). تنتقل loader::disassembleImage من ملف إلى Graph مملوء في استدعاء واحد. مبنية على llvm::object الخاصة بـ LLVM، لذا لا تبعية إضافيةdisassembler CLI — أداة سطر أوامر تحمّل ملفًا ثنائيًا ELF أو PE وتُخرج التفكيك، مفيدة للفحص السريع والبرمجة النصية (scripting)dragon_c.h) وواجهة Python API (cffi) تغطيان معظم مجموعة الميزات أعلاه (بعض الزوايا الخاصة بـ C++ فقط — قوالب DSL لمطابقة الأنماط، ومساعدات تصنيف التعليمات الخاصة بالمعمارية، وما شابه — موثّقة على هذا النحو في docs/cpp_api.md)تُشحن الإصدارات الموسومة بأرشيف SDK مكتفٍ ذاتيًا لكل منصة
(dragon-<version>-{linux-x64,macos-arm64,windows-x64}.{tar.gz,zip}) على
صفحة Releases في GitHub. يتم ربط 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-compile) ومحاكاة البايتات الخام تحت Unicorn عبر حاصل ضرب تبادلي كبير من مدخلات الحالات الحدّية (آلاف من عمليات الذهاب والإياب لكل منها). وهي موسومة بـ [.][expensive]، مما يخفيها عن تشغيل ctest الافتراضي كي يبقى سريعًا. شغّلها صراحةً — عادةً على جهاز أكثر قوة أو في CI — باستخدام:
./build/bin/dragon_tests "[expensive]"
على Windows، يحتاج اكتشاف التبعيات في CMakeLists.txt إلى بعض التلميحات،
لأنه مكتوب لتخطيطات حزم Linux: يتم تحديد موقع Z3 عبر وحدة FindZ3.cmake
المرفقة مع LLVM، ويتم تحديد موقع Unicorn عبر pkg-config.
لا تعرف أي من الآليتين أين يثبّت vcpkg الأشياء، ويتم العثور على LLVM عبر
LLVM_DIR بدلاً من مسار النظام. توفير ثلاثة تلميحات يحل كل ذلك.
المتطلبات الأساسية
C:\llvm-21 (إصدار
clang+llvm-*-x86_64-pc-windows-msvc المبني مسبقًا يعمل)1. ثبّت المكتبات باستخدام vcpkg (ثلاثية x64-windows؛ يوفر pkgconf
ملف pkg-config التنفيذي الذي يحتاجه اكتشاف Unicorn):
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 | السماح بالعثور على Unicorn عبر pkg-config | .../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
3ب. أو استخدم إعدادًا مسبقًا (موصى به)
احفظ الإعدادات مرة واحدة في CMakeUserPresets.json بجوار CMakeLists.txt،
ثم قم بالتهيئة باستخدام علامة واحدة. يحتوي هذا الملف على مسارات خاصة بالجهاز، لذا
أبقه خارج التحكم في الإصدارات (فهو مُتجاهَل بواسطة git).
{
"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_ROOT% وفقًا لذلك؛ وإذا فككت ضغط LLVM في مكان آخر، فوجّه LLVM_DIR
إلى lib/cmake/llvm في تلك الشجرة.-DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake) هنا. فهو يقيّد البحث عن الحزم
ويمنع CMake من العثور على LLVM الموجود خارج vcpkg، وهو الإعداد المعتاد
لهذا المشروع.pkg-config عامل يتم تعطيله ببساطة، ولا تُتخطّى
سوى اختبارات الذهاب والإياب في tests/semantic/. أما Z3، في المقابل، فهو
مطلوب كلما كان DRAGON_USE_Z3=ON.