Rellic adalah implementasi algoritma penataan pola-independen untuk menghasilkan output C bebas goto dari bitcode LLVM.
Filosofi desain di balik proyek ini adalah untuk menyediakan basis kode yang relatif kecil dan mudah diretas dengan interoperabilitas yang hebat dengan proyek LLVM dan LAGI lainnya.
| Program asli | Disusun dengan -emit-llvm -O0 dan didekompilasi |
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 Struktur data Anda dengan rellic-headergen
Dekompilasi interaktif dengan rellic-xref
Pembesar: Eksperimen dengan dekompilasi interaktif
| menguasai | |
|---|---|
| Linux |
Jika Anda mengalami masalah tidak berdokumen dengan Rellic maka mintalah bantuan di saluran #binary-lifting dari Empire Hacking Slack.
Rellic didukung pada platform Linux dan telah diuji pada Ubuntu 22.04.
Sebagian besar dependensi Rellic dapat disediakan oleh repositori CXX-Common. Trail of Bits host yang dapat diunduh, versi CXX-COMMON yang dapat diunduh, yang membuatnya lebih mudah untuk bangun dan berjalan dengan Rellic. Meskipun demikian, tabel berikut mewakili sebagian besar dependensi Rellic.
| Nama | Versi |
|---|---|
| Git | Terbaru |
| Cmake | 3.21+ |
| Google Flags | Terbaru |
| Google Log | Terbaru |
| Llvm | 16 |
| Dentang | 16 |
| Z3 | 4.7.1+ |
Gambar Docker yang sudah dibangun tersedia di Docker Hub dan Registry Paket GitHub.
Pertama, perbarui bakat dan dapatkan instal dependensi dasar.
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-devJika distribusi yang Anda hadapi tidak termasuk rilis terbaru CMake (3.21 atau lebih baru), Anda harus menginstalnya. Untuk Ubuntu, lihat di sini https://apt.kitware.com/.
Langkah selanjutnya adalah mengkloning repositori rellic.
git clone --recurse-submodules https://github.com/lifting-bits/rellic.git Akhirnya, kami membangun dan mengemas rellic. Skrip ini akan membuat direktori lain, rellic-build , di direktori kerja saat ini. Semua dependensi yang tersisa yang dibutuhkan oleh Rellic akan diunduh dan ditempatkan di direktori induk di samping checkout repo dalam lifting-bits-downloads (lihat opsi skrip -h untuk detail lebih lanjut). Skrip ini juga membuat paket Deb, RPM, dan TGZ yang dapat diinstal.
cd rellic
./scripts/build.sh --llvm-version 16
# to install the deb package, then do:
sudo dpkg -i rellic-build/ * .debUntuk mencoba Rellic, Anda dapat melakukan hal berikut, mengingat file bitcode LLVM pilihan Anda.
# 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/stdoutPastikan untuk memiliki rilis terbaru CXX-Common untuk LLVM 16. Lalu, bangun dengan
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 -j8Gambar Docker harus menyediakan lingkungan yang dapat mengatur, membangun, dan menjalankan rellic. Gambar Docker diparameterisasi oleh Ubuntu Verison, versi LLVM, dan arsitektur.
Untuk membangun gambar Docker menggunakan LLVM 16 untuk Ubuntu 22.04 Anda dapat menjalankan perintah berikut:
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}Untuk menjalankan dekompiler, titik entri telah ditetapkan, tetapi pastikan kode bitcome yang Anda decompiling adalah versi LLVM yang sama dengan dekompiler, dan jalankan:
# 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/stdoutUntuk menjelaskan perintah di atas lebih banyak:
# Mount current directory and change working directory
-v $( pwd ) :/test -w /testDan
# Set the user to current user to ensure correct permissions
-u $( id -u ) : $( id -g ) Kami menggunakan beberapa tes integrasi dan unit untuk menguji rellic.
Tes RoundTrip akan mengambil kode C, membangunnya ke LLVM IR, dan kemudian menerjemahkan IR itu kembali ke C. Tes kemudian melihat jika C yang dihasilkan dapat dibangun dan jika kode yang diterjemahkan melakukan (kira -kira) hal yang sama seperti aslinya. Untuk menjalankan ini, gunakan:
cd rellic-build # or your rellic build directory
CTEST_OUTPUT_ON_FAILURE=1 cmake --build . --verbose --target test Anghabench 1000 adalah sampel dari 1000 file (arsitektur x 4, jadi total 4000 tes) dari juta program penuh yang datang dengan Anghabench. Tes ini hanya memeriksa apakah bitcode untuk program ini diterjemahkan menjadi C, bukan keindahan atau fungsi dari terjemahan yang dihasilkan. Untuk menjalankan tes ini, pertama instal dependensi Python yang diperlukan yang ditemukan dalam scripts/requirements.txt dan kemudian jalankan:
scripts/test-angha-1k.sh --rellic-cmd < path_to_rellic_decompiler_exe > Silakan gunakan cuplikan Bibtex berikut untuk mengutip Rellic:
@online{rellic,
title={Rellic},
author={Surovič, Marek and Bertolaccini, Francesco},
organization={Trail of Bits},
url={https://github.com/lifting-bits/rellic}
}