LLVM lli加载afl-llvm-rt.so执行bitcode崩溃问题求助
解决lli动态链接afl-llvm-rt.so运行bitcode的段错误问题
我之前折腾过LLVM JIT动态链接AFL runtime的类似问题,给你几个实际可行的解决思路:
1. 先确认共享库符号导出与lli的符号搜索逻辑
首先排查基础的符号可见性问题:
- 用
nm -D ./afl-llvm-rt.so检查你需要的函数是否标记为T(全局导出)。如果有函数是隐藏的,重新编译afl-llvm-rt.so时加上-fPIC -Wl,--export-dynamic参数,强制导出所有符号。 - 尝试显式设置环境变量让lli能找到共享库:
LD_LIBRARY_PATH=. lli -dlopen ./afl-llvm-rt.so a.bc - 检查a.bc中函数声明的可见性:用
llvm-dis a.bc把bitcode转成.ll文件,看看调用的AFL函数是不是用declare dso_local声明的。如果是,改成declare dso_preemptable(告诉JIT这个符号可能来自动态库),再用llvm-as转回.bc文件。
2. 处理AFL Runtime的特殊初始化逻辑
AFL的LLVM runtime有特殊的初始化流程(比如forkserver、信号处理),JIT环境下不会像静态编译那样自动触发:
- 在你的a.bc入口函数(比如main)开头,显式调用
__afl_init()函数,确保JIT运行时先完成AFL的初始化。 - 如果runtime依赖线程本地存储(TLS),检查lli是否启用了TLS支持,尝试添加参数指定目标架构并开启TLS:
lli --mtriple=x86_64-linux-gnu --enable-tls -dlopen ./afl-llvm-rt.so a.bc
3. 切换到LLVM ORC JIT引擎
传统lli用的MCJIT引擎对动态链接的支持有限,LLVM newer的ORC JIT框架兼容性更好:
- 如果你的LLVM版本提供了
lli-orc工具,直接替换lli尝试:lli-orc -dlopen ./afl-llvm-rt.so a.bc - 没有
lli-orc的话,可以自己写一个简单的ORC JIT加载脚本(用LLVM C++ API),精细控制符号加载:
编译这个脚本:#include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/TargetSelect.h" using namespace llvm; using namespace llvm::orc; int main(int argc, char *argv[]) { InitLLVM X(argc, argv); InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input bitcode file>")); cl::opt<std::string> SharedLib(cl::Positional, cl::desc("<shared library>")); cl::ParseCommandLineOptions(argc, argv, "AFL JIT Loader\n"); auto JIT = ExitOnError(LLJITBuilder().create()); // 添加当前进程的符号(包括动态加载的库) ExitOnError(JIT->getMainJITDylib().addGenerator( ExitOnError(DynamicLibrarySearchGenerator::GetForCurrentProcess()))); // 显式加载目标共享库 ExitOnError(JIT->getMainJITDylib().addGenerator( ExitOnError(DynamicLibrarySearchGenerator::Load(SharedLib)))); auto M = ExitOnError(parseIRFile(InputFile, JIT->getContext())); ExitOnError(JIT->addIRModule(std::move(M))); // 查找并执行main函数 auto EntrySym = ExitOnError(JIT->lookup("main")); using MainFn = int (*)(int, char**); auto Main = reinterpret_cast<MainFn>(EntrySym.getAddress()); return Main(argc - 2, argv + 2); }
然后运行:clang++ jit-loader.cpp -o jit-loader `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native`./jit-loader a.bc ./afl-llvm-rt.so
4. 检查LLVM版本兼容性
确保你的a.bc、afl-llvm-rt.so、lli/lli-orc是用同一个LLVM版本编译的。不同版本的IR格式和JIT接口不兼容,会导致各种奇怪的崩溃。可以用lli --version、clang --version、llvm-dis a.bc查看顶部的版本信息,确保一致。
内容的提问来源于stack exchange,提问作者Alex Babushkin
相关产品推荐
相关产品推荐

