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