Nyxstone adalah perpustakaan perakitan dan pembongkaran yang kuat berdasarkan LLVM. Itu tidak memerlukan tambalan ke pohon sumber LLVM dan tautan terhadap pustaka LLVM standar yang tersedia di sebagian besar distribusi Linux. Diimplementasikan sebagai perpustakaan C ++, Nyxstone juga menawarkan binding karat dan python. Ini mendukung semua arsitektur LLVM resmi dan memungkinkan untuk mengonfigurasi pengaturan target khusus arsitektur.
Merakit dan membongkar kode untuk semua arsitektur yang didukung oleh LLVM tertaut, termasuk x86, ARM, MIPS, RISC-V dan lainnya.
Perpustakaan C ++ berdasarkan LLVM dengan binding karat dan python.
Dukungan platform asli untuk Linux dan MacOS.
Mendukung label di assembler, termasuk spesifikasi pemetaan label-ke-alamat
Merakit dan membongkar ke byte dan teks mentah, tetapi juga menyediakan objek instruksi terperinci yang berisi alamat, byte mentah, dan representasi perakitan.
Pembongkaran dapat dibatasi pada jumlah instruksi yang ditentukan pengguna dari urutan byte.
Memungkinkan untuk mengonfigurasi fitur target khusus arsitektur, seperti ekstensi ISA dan fitur perangkat keras.
Untuk daftar arsitektur yang didukung yang komprehensif, Anda dapat menggunakan clang -print-targets . Untuk daftar fitur yang komprehensif untuk setiap arsitektur, lihat llc -march=ARCH -mattr=help .
Catatan
Penafian: Nyxstone telah dikembangkan dan diuji untuk arsitektur X86_64, AARCH64, dan ARM32. Kami memiliki tingkat kepercayaan yang tinggi pada kemampuannya untuk secara akurat menghasilkan perakitan dan mengidentifikasi kesalahan untuk platform ini. Untuk arsitektur lain, efektivitas Nyxstone tergantung pada keandalan dan kinerja backend LLVM masing -masing.
Bagian ini memberikan instruksi tentang cara memulai dengan Nyxstone, mencakup prasyarat yang diperlukan, cara menggunakan alat CLI, dan pedoman langkah demi langkah untuk menggunakan perpustakaan dengan C ++, Rust, dan Python.
Sebelum membangun Nyxstone, pastikan dentang dan LLVM hadir di sistem Anda. Nyxstone mendukung LLVM Versi Utama 15-18. Saat membangunnya mencari llvm-config di $PATH sistem Anda atau variabel lingkungan yang ditentukan $NYXSTONE_LLVM_PREFIX/bin .
Opsi Instalasi untuk versi LLVM 15-18:
sudo apt install llvm- ${version} llvm- ${version} -devDebian LLVM versi 15 dan 16 tersedia melalui repositori Debian. Instalasi sama dengan untuk Ubuntu. Untuk versi 17 atau 18 lihat https://apt.llvm.org/ untuk instruksi instalasi.
Lengkungan
sudo pacman -S llvm llvm-libsbrew install llvm@18
export NYXSTONE_LLVM_PREFIX=/opt/homebrew/opt/llvm@18 Catatan : Pada Windows Anda perlu menjalankan perintah ini dari prompt perintah Visual Studio 2022 X64. Selain itu ganti ~lib/my-llvm-18 dengan jalur yang berbeda.
# checkout llvm
git clone -b release/18.x --single-branch https://github.com/llvm/llvm-project.git
cd llvm-project
# build LLVM with custom installation directory
cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_PARALLEL_LINK_JOBS=1
cmake --build build
cmake --install build --prefix ~ /lib/my-llvm-18
# export path
export NYXSTONE_LLVM_PREFIX= ~ /lib/my-llvm-18 Pastikan juga untuk menginstal perpustakaan tergantung sistem apa pun yang diperlukan oleh versi LLVM Anda untuk tautan statis. Mereka dapat dilihat dengan perintah llvm-config --system-libs ; Daftarnya bisa kosong. Di Ubuntu/Debian, Anda akan membutuhkan paket zlib1g-dev dan zlibstd-dev .
Nyxstone hadir dengan alat CLI yang praktis untuk tugas perakitan cepat dan pembongkaran. Periksa repositori Nyxstone, dan bangun alat dengan cmake:
# clone directory
git clone https://github.com/emproof-com/nyxstone
cd nyxstone
# build nyxstone
mkdir build && cd build && cmake .. && make Kemudian, nyxstone dapat digunakan dari baris perintah. Berikut output dari menu bantuannya:
$ ./nyxstone -h
Usage: nyxstone [-t=<triple>] [-p=<pc>] [-d] <input>
Examples:
# Assemble an instruction with the default architecture ('x86_64').
nyxstone 'push eax'
# Disassemble the bytes 'ffc300d1' as AArch64 code.
nyxstone -t aarch64 -d ffc300d1
Options:
-t, --triple=<triple> LLVM target triple or alias, e.g. 'aarch64'
-c, --cpu=<cpu> LLVM CPU specifier, e.g. 'cortex-a53'
-f, --features=<list> LLVM architecture/CPU feature list, e.g. '+mte,-neon'
-p, --address=<pc> Initial address to assemble/disassemble relative to
-l, --labels=<list> Label-to-address mappings (used when assembling only)
-d, --disassemble Treat <input> as bytes to disassemble instead of assembly
-h, --help Show this help and usage message
Notes:
The '--triple' parameter also supports aliases for common target triples:
'x86_32' -> 'i686-linux-gnu'
'x86_64' -> 'x86_64-linux-gnu'
'armv6m' -> 'armv6m-none-eabi'
'armv7m' -> 'armv7m-none-eabi'
'armv8m' -> 'armv8m.main-none-eabi'
'aarch64' -> 'aarch64-linux-gnueabihf'
The CPUs for a target can be found with 'llc -mtriple=<triple> -mcpu=help'.
The features for a target can be found with 'llc -mtriple=<triple> -mattr=help'.
Sekarang, kita dapat mengumpulkan instruksi untuk arsitektur x86_64:
$ ./nyxstone -t x86_64 "mov rax, rbx"
0x00000000: mov rax, rbx ; 48 89 d8
Kami juga dapat mengumpulkan urutan instruksi. Berikut ini, kami memanfaatkan pengalamatan berbasis label dan mengasumsikan instruksi pertama dipetakan untuk membahas 0xdeadbeef :
$ ./nyxstone -t x86_64 -p 0xdeadbeef "cmp rax, rbx; jz .exit; inc rax; .exit: ret"
0xdeadbeef: cmp rax, rbx ; 48 39 d8
0xdeadbef2: je .exit ; 74 03
0xdeadbef4: inc rax ; 48 ff c0
0xdeadbef7: ret ; c3
Selain itu, kami dapat membongkar instruksi untuk set instruksi yang berbeda, di sini set instruksi ibu jari ARM32:
$ ./nyxstone -t thumbv8 -d "13 37"
0x00000000: adds r7, #19 ; 13 37
Menggunakan dukungan untuk label yang ditentukan pengguna, kami dapat merakit cuplikan ini yang tidak berisi label .label dengan menentukan lokasi memori sendiri.
$ ./nyxstone -p "0x1000" -l ".label=0x1238" "jmp .label"
0x00001000: jmp .label ; e9 33 02 00 00
Untuk menggunakan Nyxstone sebagai perpustakaan C ++, kode C ++ Anda harus dihubungkan dengan Nyxstone dan LLVM.
Contoh cmake berikut mengasumsikan Nyxstone dalam nyxstone subdirektori dalam proyek Anda:
add_subdirectory (nyxstone)
add_executable (my_executable main.cpp)
target_link_libraries (my_executable nyxstone::nyxstone)Contoh penggunaan C ++ yang sesuai:
# include < cassert >
# include < iostream >
# include " nyxstone.h "
int main ( int , char **) {
// Create the nyxstone instance:
auto nyxstone {
NyxstoneBuilder ( " x86_64 " )
. build ()
. value ()
};
// Assemble to bytes
std::vector< uint8_t > bytes =
nyxstone-> assemble ( /* assembly= */ " mov rax, rbx " , /* address= */ 0x1000 , /* labels= */ {}). value ();
std::vector< uint8_t > expected { 0x48 , 0x89 , 0xd8 };
assert (bytes == expected);
return 0 ;
}Untuk contoh C ++ yang komprehensif, lihatlah Contoh.cpp.
Untuk menggunakan Nyxstone sebagai perpustakaan karat, tambahkan ke Cargo.toml Anda.toml dan gunakan seperti yang ditunjukkan pada contoh berikut:
use anyhow :: Result ;
use nyxstone :: { Nyxstone , NyxstoneConfig } ;
use std :: collections :: HashMap ;
fn main ( ) -> Result < ( ) > {
let nyxstone = Nyxstone :: new ( "x86_64" , NyxstoneConfig :: default ( ) ) ? ;
let bytes = nyxstone . assemble_with (
"mov rax, rbx; cmp rax, rdx; jne .label" ,
0x1000 ,
& HashMap :: from ( [ ( ".label" , 0x1200 ) ] ) ,
) ? ;
println ! ( "Bytes: {:x?}" , bytes ) ;
Ok ( ( ) )
}Untuk instruksi lebih lanjut tentang ikatan karat, lihatlah readme yang sesuai.
Untuk menggunakan Nyxstone dari Python, pasangnya menggunakan PIP:
pip install nyxstoneKemudian, Anda dapat menggunakannya dari Python:
$ python -q
>>> from nyxstone import Nyxstone
>>> nyxstone = Nyxstone("x86_64")
>>> nyxstone.assemble("jne .loop", 0x1100, {".loop": 0x1000})
Instruksi terperinci tersedia di readme yang sesuai.
Nyxstone memanfaatkan fungsi C ++ API publik dari LLVM seperti Target::createMCAsmParser dan Target::createMCDisassembler untuk melakukan tugas perakitan dan pembongkaran. Nyxstone juga memperluas dua kelas LLVM, MCELFStreamer dan MCObjectWriter , untuk menyuntikkan logika khusus dan mengekstrak informasi tambahan. Secara khusus, Nyxstone menambah proses perakitan dengan langkah -langkah berikut:
ELFStreamerWrapper::emitInstruction : Captures Majelis Representasi dan byte byte mentah awal dari instruksi jika objek instruksi terperinci diminta oleh pengguna.
ObjectWriterWrapper::writeObject : Menulis byte instruksi mentah akhir (dengan penyesuaian relokasi) ke objek instruksi terperinci. Selain itu, ia beralih output byte mentah dari file elf lengkap ke hanya bagian .text.
ObjectWriterWrapper::validate_fixups : Melakukan pemeriksaan tambahan, seperti memverifikasi jangkauan dan penyelarasan relokasi.
ObjectWriterWrapper::recordRelocation : Menerapkan relokasi tambahan. MCObjectWriter melewatkan beberapa relokasi yang hanya diterapkan selama tautan. Saat ini, ini hanya relevan untuk relokasi fixup_aarch64_pcrel_adrp_imm21 dari instruksi AARCH64 adrp .
Sementara memperluas kelas LLVM memperkenalkan beberapa kelemahan, seperti ketergantungan yang kuat pada versi LLVM tertentu, kami percaya pendekatan ini masih lebih disukai daripada alternatif yang membutuhkan sulit untuk mempertahankan tambalan di pohon sumber LLVM.
Kami berkomitmen untuk lebih mengurangi kompleksitas proyek dan terbuka untuk saran untuk perbaikan. Ke depan, kita dapat menghilangkan kebutuhan untuk memperluas kelas LLVM dengan memanfaatkan infrastruktur LLVM yang ada dengan cara yang lebih cerdas atau menggabungkan logika tambahan dalam langkah pasca pemrosesan.
Di bawah ini adalah beberapa ide dan perbaikan yang kami yakini akan secara signifikan memajukan Nyxstone. Item tidak tercantum dalam urutan tertentu:
Periksa keamanan utas
Tambahkan dukungan untuk lebih banyak versi LLVM (Auto Select tergantung pada versi perpustakaan LLVM yang ditemukan)
Jelajahi opsi untuk membuat LLVM menerapkan semua relokasi (termasuk adrp ) dengan mengonfigurasi MCObjectWriter secara berbeda atau menggunakan penulis yang berbeda
Jelajahi opsi untuk menghasilkan instruksi terperinci objek dengan membongkar output byte mentah dari proses perakitan alih -alih mengandalkan ekstensi kelas LLVM
Jelajahi opsi untuk mengimplementasikan rentang tambahan dan penyelarasan relokasi dalam langkah pasca pemrosesan alih-alih mengandalkan perpanjangan kelas LLVM
Nyxstone tersedia di bawah lisensi MIT.
Kami menyambut kontribusi dari komunitas! Jika Anda menghadapi masalah apa pun dengan Nyxstone, jangan ragu untuk membuka masalah GitHub.
Jika Anda tertarik untuk berkontribusi langsung ke proyek, Anda dapat misalnya:
Setelah siap, kirimkan permintaan tarik dengan perubahan Anda. Kami menantikan kontribusi Anda!
Kontributor saat ini adalah:
Inti :
Minor :
Untuk memastikan bahwa kami menautkan LLVM dengan benar dengan versi yang tepat di Rust, kami mengadaptasi build.rs dari LLVM-SYS.