Rellic是与模式无关的结构算法的实现,以从LLVM比特码产生无goto的C输出。
该项目背后的设计理念是提供一个相对较小且易于黑客入侵的代码库,与其他LLVM和Remill项目具有出色的互操作性。
| 原始程序 | 用-emit-llvm -O0编译并分解 |
int main () {
for ( int i = 0 ; i < 30 ; ++ i ) {
if ( i % 3 == 0 && i % 5 == 0 ) {
printf ( "fizzbuzzn" );
} else if ( i % 3 == 0 ) {
printf ( "fizzn" );
} else if ( i % 5 == 0 ) {
printf ( "buzzn" );
} else {
printf ( "%dn" , i );
}
}
} | int main () {
unsigned int var0 ;
unsigned int i ;
var0 = 0U ;
i = 0U ;
while (( int ) i < 30 ) {
if (( int ) i % 3 != 0U || !(( int ) i % 5 == 0U || ( int ) i % 3 != 0U )) {
if (( int ) i % 3 != 0U ) {
if (( int ) i % 5 != 0U ) {
printf ( "%dn" , i );
} else {
printf ( "buzzn" );
}
} else {
printf ( "fizzn" );
}
} else {
printf ( "fizzbuzzn" );
}
i = i + 1U ;
}
return var0 ;
} |
int main () {
int i = 0 ;
start:
i ++ ;
switch ( i ) {
case 1 : printf ( "%dn" , i ); goto start; break ;
case 2 : printf ( "%dn" , i ); goto start; break ;
case 3 : printf ( "%dn" , i ); break ;
}
} | int main () {
unsigned int var0 ;
unsigned int i ;
var0 = 0U ;
i = 0U ;
do {
i = i + 1U ;
if (!( i != 3U && i != 2U && i != 1U ))
if ( i == 3U ) {
printf ( "%dn" , i );
break ;
} else if ( i == 2U ) {
printf ( "%dn" , i );
} else {
printf ( "%dn" , i );
}
} while (!( i != 3U && i != 2U && i != 1U ));
return var0 ;
} |
int main () {
int x = atoi ( "5" );
if ( x > 10 ) {
while ( x < 20 ) {
x = x + 1 ;
printf ( "loop1 x: %dn" , x );
}
}
while ( x < 20 ) {
x = x + 1 ;
printf ( "loop2 x: %dn" , x );
}
} | int main () {
unsigned int var0 ;
unsigned int x ;
unsigned int call2 ;
var0 = 0U ;
call2 = atoi ( "5" );
x = call2 ;
if (( int ) x > 10 ) {
while (( int ) x < 20 ) {
x = x + 1U ;
printf ( "loop1 x: %dn" , x );
}
}
if (( int ) x <= 10 || ( int ) x >= 20 ) {
while (( int ) x < 20 ) {
x = x + 1U ;
printf ( "loop2 x: %dn" , x );
}
}
if (( int ) x >= 20 && (( int ) x <= 10 || ( int ) x >= 20 )) {
return var0 ;
}
} |
C您的数据结构用rellic-headergen
与rellic-xref交互式互动
放大镜:交互式解次数的实验
| 掌握 | |
|---|---|
| Linux |
如果您遇到Rellic的无证件问题,请在帝国黑客懈怠的#binary-lifting频道中寻求帮助。
Rellic在Linux平台上得到支持,并已在Ubuntu 22.04上进行了测试。
Rellic的大多数依赖关系都可以由CXX-Common存储库提供。 BITS的踪迹可下载可下载的CXX-Common版本,这使得与Rellic启动和运行变得更加容易。尽管如此,下表代表了Rellic的大部分依赖项。
| 姓名 | 版本 |
|---|---|
| git | 最新的 |
| cmake | 3.21+ |
| Google标志 | 最新的 |
| Google日志 | 最新的 |
| LLVM | 16 |
| 铛 | 16 |
| Z3 | 4.7.1+ |
预先建造的Docker图像可在Docker Hub和GitHub软件包注册表中获得。
首先,更新能力并安装基线依赖关系。
sudo apt update
sudo apt upgrade
sudo apt install
git
python3
wget
unzip
pixz
xz-utils
cmake
curl
build-essential
lsb-release
zlib1g-dev
libomp-dev
doctest-dev如果您的发行版不包括最近发布的CMake(3.21或更高版本),则需要安装它。对于Ubuntu,请参见此处https://apt.kitware.com/。
下一步是克隆校正存储库。
git clone --recurse-submodules https://github.com/lifting-bits/rellic.git最后,我们构建并打包了框。该脚本将在当前工作目录中创建另一个目录rellic-build 。 Rellic所需的所有剩余依赖项将被下载并放置在repo Checkout中,以lifting-bits-downloads (有关更多详细信息,请参见脚本-h选项)。该脚本还可以创建可安装的DEB,RPM和TGZ软件包。
cd rellic
./scripts/build.sh --llvm-version 16
# to install the deb package, then do:
sudo dpkg -i rellic-build/ * .deb要尝试Rellic,鉴于您选择的LLVM比特码文件,您可以执行以下操作。
# Create some sample bitcode or your own
clang-16 -emit-llvm -c ./tests/tools/decomp/issue_4.c -o ./tests/tools/decomp/issue_4.bc
./rellic-build/tools/rellic-decomp --input ./tests/tools/decomp/issue_4.bc --output /dev/stdout确保为LLVM 16提供最新版本的CXX-Common。然后,与
cmake
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
-DVCPKG_TARGET_TRIPLET=x64-osx-rel
-DRELLIC_ENABLE_TESTING=OFF
-DCMAKE_C_COMPILER= ` which clang `
-DCMAKE_CXX_COMPILER= ` which clang++ `
/path/to/rellic
make -j8Docker映像应提供可以设置,构建和运行Rellic的环境。 Docker图像由Ubuntu Verison,LLVM版本和体系结构进行了参数化。
要使用ubuntu 22.04使用LLVM 16构建Docker映像,您可以运行以下命令:
UBUNTU=22.04 ; LLVM=16 ; docker build .
-t rellic:llvm ${LLVM} -ubuntu ${UBUNTU}
-f Dockerfile
--build-arg UBUNTU_VERSION= ${UBUNTU}
--build-arg LLVM_VERSION= ${LLVM}为了运行分解器,已经设置了入口点,但是请确保您要分解的比特码与LLVM版本与分解器相同,然后运行:
# Get the bc file
clang-16 -emit-llvm -c ./tests/tools/decomp/issue_4.c -o ./tests/tools/decomp/issue_4.bc
# Decompile
docker run --rm -t -i
-v $( pwd ) :/test -w /test
-u $( id -u ) : $( id -g )
rellic:llvm16-ubuntu22.04 --input ./tests/tools/decomp/issue_4.bc --output /dev/stdout更多地解释上述命令:
# Mount current directory and change working directory
-v $( pwd ) :/test -w /test和
# Set the user to current user to ensure correct permissions
-u $( id -u ) : $( id -g ) 我们使用多个集成和单元测试来测试斜视。
往返测试将采用C代码,将其构建为LLVM IR,然后将IR转换回C。测试然后查看是否可以构建结果C,以及翻译的代码是否(大致)与原始代码相同。要运行这些,请使用:
cd rellic-build # or your rellic build directory
CTEST_OUTPUT_ON_FAILURE=1 cmake --build . --verbose --target test Anghabench 1000是来自Anghabench随附的全百万个程序的1000个文件(x 4架构,总计4000个测试)的样本。该测试仅检查这些程序的比特码是否转化为C,而不是所得翻译的优质或功能。要运行此测试,请首先安装在scripts/requirements.txt中找到所需的python依赖项,然后运行:
scripts/test-angha-1k.sh --rellic-cmd < path_to_rellic_decompiler_exe > 请使用以下Bibtex片段来引用标语:
@online{rellic,
title={Rellic},
author={Surovič, Marek and Bertolaccini, Francesco},
organization={Trail of Bits},
url={https://github.com/lifting-bits/rellic}
}