Rellic เป็นการดำเนินการตามอัลกอริทึมการจัดโครงสร้างแบบอิสระเพื่อสร้างเอาต์พุต C Goto-Free จาก LLVM BitCode
ปรัชญาการออกแบบที่อยู่เบื้องหลังโครงการคือการจัดหารหัสฐานที่ค่อนข้างเล็กและแฮ็กได้ง่ายพร้อมการทำงานร่วมกันที่ยอดเยี่ยมกับโครงการ LLVM และ Remill อื่น ๆ
| โปรแกรมดั้งเดิม | รวบรวมด้วย -emit-llvm -O0 และ decompiled |
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
แว่นขยาย: การทดลองกับการสลายตัวแบบโต้ตอบ
| ผู้เชี่ยวชาญ | |
|---|---|
| ลินเวกซ์ |
หากคุณกำลังประสบปัญหาที่ไม่มีเอกสารเกี่ยวกับ Rellic ให้ขอความช่วยเหลือในช่อง #binary-lifting ของ Empire Hacking Slack
Rellic ได้รับการสนับสนุนบนแพลตฟอร์ม Linux และได้รับการทดสอบใน Ubuntu 22.04
การพึ่งพาของ Rellic ส่วนใหญ่สามารถจัดหาได้โดยที่เก็บ CXX-Common Trail of Bits เป็นโฮสต์ CXX-common เวอร์ชันที่สร้างไว้ล่วงหน้าซึ่งทำให้ง่ายขึ้นอย่างมากในการทำงานกับ Rellic อย่างไรก็ตามตารางต่อไปนี้แสดงถึงการพึ่งพาส่วนใหญ่ของ Rellic
| ชื่อ | รุ่น |
|---|---|
| กระตวน | ล่าสุด |
| cmake | 3.21+ |
| Google Flags | ล่าสุด |
| Google Log | ล่าสุด |
| LLVM | 16 |
| เสียงดัง | 16 |
| Z3 | 4.7.1+ |
รูปภาพ Docker ที่สร้างไว้ล่วงหน้ามีอยู่ใน Docker Hub และ GitHub Package Registry
ขั้นแรกให้อัปเดตความถนัดและรับการติดตั้งการพึ่งพาพื้นฐาน
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/
ขั้นตอนต่อไปคือการโคลนที่เก็บ Rellic
git clone --recurse-submodules https://github.com/lifting-bits/rellic.git ในที่สุดเราก็สร้างและแพ็คเกจ Rellic สคริปต์นี้จะสร้างไดเรกทอรีอื่น rellic-build ในไดเรกทอรีการทำงานปัจจุบัน การพึ่งพาที่เหลือทั้งหมดที่ RELLIC ต้องการจะถูกดาวน์โหลดและวางไว้ในไดเรกทอรีหลักพร้อมกับการชำระเงินคืนใน 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 คุณสามารถทำสิ่งต่อไปนี้ได้โดยได้รับไฟล์ BitCode 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ตรวจสอบให้แน่ใจว่ามีการเปิดตัว CXX-common ล่าสุดสำหรับ LLVM 16 จากนั้นสร้างด้วย
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 -j8อิมเมจนักเทียบท่าควรให้สภาพแวดล้อมที่สามารถตั้งค่าสร้างและเรียกใช้ Rellic ภาพนักเทียบท่าจะถูกพารามิเตอร์โดย Ubuntu Verison เวอร์ชัน LLVM และสถาปัตยกรรม
ในการสร้างอิมเมจนักเทียบท่าโดยใช้ LLVM 16 สำหรับ Ubuntu 22.04 คุณสามารถเรียกใช้คำสั่งต่อไปนี้:
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}ในการเรียกใช้ decompiler ententpoint ได้รับการตั้งค่าแล้ว แต่ตรวจสอบให้แน่ใจว่า bitcode ที่คุณกำลังถอดรหัสเป็นเวอร์ชัน 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 ) เราใช้การรวมการรวมและการทดสอบหน่วยเพื่อทดสอบ Rellic
การทดสอบไป RoundTrip จะใช้รหัส 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 เป็นตัวอย่างของไฟล์ 1,000 ไฟล์ (สถาปัตยกรรม x 4 ดังนั้นการทดสอบทั้งหมด 4,000 ครั้ง) จากโปรแกรมเต็มล้านโปรแกรมที่มาพร้อมกับ Anghabench การทดสอบนี้จะตรวจสอบว่า BitCode สำหรับโปรแกรมเหล่านี้แปลเป็น C ไม่ใช่ความน่ารักหรือการทำงานของการแปลที่เกิดขึ้น ในการเรียกใช้การทดสอบนี้ก่อนอื่นให้ติดตั้งการพึ่งพา python ที่ต้องการที่พบใน scripts/requirements.txt แล้วเรียกใช้:
scripts/test-angha-1k.sh --rellic-cmd < path_to_rellic_decompiler_exe > โปรดใช้ตัวอย่าง Bibtex ต่อไปนี้เพื่ออ้างอิง Rellic:
@online{rellic,
title={Rellic},
author={Surovič, Marek and Bertolaccini, Francesco},
organization={Trail of Bits},
url={https://github.com/lifting-bits/rellic}
}