1 poin oleh GN⁺ 2024-08-24 | 1 komentar | Bagikan ke WhatsApp
  • Ekstensi Ghidra ini mengekspor sebagian program sebagai file objek, dan file yang diekspor dapat diproses ulang oleh toolchain karena berisi metadata valid seperti simbol dan tabel relokasi
  • Kegunaan utamanya adalah patching biner tingkat lanjut, porting perangkat lunak, konversi format file, pembuatan library, serta pekerjaan mengimplementasikan ulang program dalam proyek dekompilasi dengan membaginya menjadi beberapa file objek
  • Kombinasi yang didukung adalah COFF x86/x86_64, ELF x86/x86_64/MIPS, OMF x86; COFF MIPS, OMF x86_64, dan OMF MIPS tidak didukung
  • Pengguna memilih rentang alamat yang akan diekstrak di Ghidra Listing, menjalankan analyzer Relocation table synthesizer, lalu memanggil exporter file objek yang dapat direlokasi dari File > Export Program…
  • Sintesis tabel relokasi bergantung pada akurasi database Ghidra, sehingga jika ada informasi yang salah atau hilang, relokasi bisa rusak atau terlewat; lebih aman menjalankan analyzer lagi tepat sebelum ekspor

Ekstensi ini melakukan apa

  • Object file exporter extension for Ghidra adalah ekstensi Ghidra yang memungkinkan sebagian program diekspor sebagai file objek
  • File objek yang dihasilkan berisi metadata valid seperti simbol dan tabel relokasi
  • Berkat metadata ini, file objek yang diekspor dapat digunakan kembali secara langsung di toolchain untuk pemrosesan lanjutan

Contoh penggunaan

  • Advanced binary patching
    • Alih-alih menyelaraskan bagian asli dan bagian yang dimodifikasi secara manual, linker dapat dimanfaatkan agar keduanya tersambung dengan benar
  • Software ports
    • Kode yang independen dari sistem dapat dipisahkan dari program, lalu sisanya diganti
  • Dapat mengonversi program atau file objek dari satu format file ke format file lain
  • Ekstraksi sebagian program dan pembuatan library
    • Sebagian program dapat diekstrak dan digunakan kembali dalam konteks lain
  • Dalam proyek dekompilasi, program dapat dibagi menjadi beberapa file objek dan diimplementasikan ulang dengan pendekatan Ship of Theseus

Arsitektur dan format file objek yang didukung

  • Matriks dukungannya adalah sebagai berikut
    • COFF: mendukung x86, x86_64 / tidak mendukung MIPS
    • ELF: mendukung x86, x86_64, MIPS
    • OMF: mendukung x86 / tidak mendukung x86_64, MIPS

Build dan instalasi

  • Prosedur build CLI
    • Clone repositori
    • Atur variabel lingkungan GHIDRA_INSTALL_DIR ke direktori instalasi Ghidra
    • Jalankan gradle buildExtension
    • Arsip ekstensi Ghidra yang dihasilkan akan dibuat di direktori dist/
  • Autentikasi diperlukan untuk mengunduh paket dari GitHub Maven repository
    • Buat GitHub classic token dengan izin read:packages, lalu tambahkan githubToken=ghp_xxx ke ${GRADLE_USER_HOME}/gradle.properties
    • Atau jalankan gradle installStandaloneDeps untuk membuild dan menginstal vendored dependency dari submodule
  • Prosedur instalasi
    • Unduh ekstensi dari releases page atau build secara lokal
    • Di Ghidra, instal ekstensi melalui File > Install Extensions…
    • Di jendela CodeBrowser, aktifkan plugin RelocationTableSynthesizedPlugin melalui File > Configure > Experimental

Alur penggunaan dan catatan penting

  • Prosedur penggunaan dasar
    • Di tampilan Listing, pilih kumpulan alamat yang akan diekstrak
    • Jalankan analyzer Relocation table synthesizer yang disediakan dalam mode one-shot
    • Panggil exporter file objek yang dapat direlokasi dari File > Export Program…
  • Relokasi yang direkonstruksi dapat dilihat di Window > Relocation table (synthesized)
  • Laporan evaluasi terperinci dapat diaktifkan dengan mengatur opsi Evaluation report policy pada analyzer Relocation table synthesizer di dialog Analysis > Auto Analyze...
  • Tidak perlu melakukan reverse engineering seluruh program terlebih dahulu sebelum menggunakan ekstensi ini
  • Delinking yang berhasil umumnya sangat bergantung pada metadata di bagian yang akan diekspor dan referensi eksternal
    • Fungsi dan pointer yang digunakan sebagai lokasi relokasi
    • Footprint simbol yang digunakan sebagai target relokasi
    • Referensi di antara keduanya
  • Analyzer Relocation table synthesizer bergantung pada akurasi database Ghidra
    • Informasi yang tidak akurat atau hilang dapat menyebabkan relokasi rusak atau relokasi terlewat saat analisis
  • Exporter file objek bergantung pada hasil analisis Relocation table synthesizer
    • Jika ragu, jalankan analyzer tepat sebelum mengekspor file objek untuk memastikan tabel relokasi sudah mutakhir

Cara kerjanya

  • File objek terdiri dari tiga bagian
    • Byte section yang dapat direlokasi
    • Tabel simbol

      • Tabel relokasi
      • Pekerjaan yang dilakukan linker saat membuat executable dari beberapa file objek
      • Menempatkan section di memori
      • Menghitung alamat simbol di ruang alamat virtual
      • Menerapkan relokasi pada byte section berdasarkan alamat simbol final
      • Biasanya, setelah proses ini selesai, tabel relokasi dibuang
      • Jika simbol debugging tidak dipertahankan, tabel simbol juga dibuang, dan yang tersisa hanya byte section yang tidak dapat direlokasi
      • Ekstensi ini dapat membuat ulang data tersebut melalui analisis yang cermat, sehingga program dapat di-delink kembali menjadi file objek

1 komentar

 
GN⁺ 2024-08-24
Komentar Hacker News
  • Senang melihat ini di sini. Menurutku ini proyek yang sangat keren, dan aku ikut membantu menambahkan dukungan MS COFF
    Hanya saja PR awalku masih cukup kurang dibanding dukungan ELF yang sudah ada, jadi kalau ada masalah mungkin itu salahku. Meski begitu, kelihatan terus membaik
    Aku belum mencobanya untuk pekerjaan besar, tapi hal paling seru yang pernah kucoba adalah melakukan delink pada executable Hello World yang dikompilasi dengan Visual Studio 2003, lalu menautkannya ulang dengan GCC+glibc di Linux x86, dan kemudian menautkannya ulang lagi dengan MinGW+msvcrt
    Yang lebih besar dari Hello World masih sulit, terutama karena aku juga belum terlalu paham Ghidra, jadi sampai sekarang aku juga belum menemukan cara yang bagus untuk memilih cakupan yang akan didelink pada biner besar
    Kebetulan hari ini paket turunan Nixpkgs untuk alat ini digabung, jadi di NixOS unstable sekarang bisa diinstal dengan ghidra.withExtensions. Lokasinya ghidra-extensions.ghidra-delinker-extension
    Hanya saja beberapa hari lalu versi baru sudah dirilis, dan karena PR-nya belum direbase, saat ini masih versi lama, tapi aku berencana segera mengirim pembaruannya

    • Salah satu cara untuk melacak target yang akan didelink adalah memakai folder dan fragmen di dalam program tree
      Misalnya, jika ada program Ghidra yang sudah mengetahui nama dan rentang beberapa object file yang membentuk executable asli, kamu bisa klik kanan folder atau fragmen tersebut > Select Addresses untuk memilih seluruhnya
      Analyzer sintesis relokasi dan proses ekspor juga masing-masing bisa dibuat skrip atau diotomatisasi lewat tree manager program, jadi kebutuhan untuk memilih rentang secara manual lalu menjalankan analyzer dan ekspor secara manual jadi berkurang
  • Terlihat cukup menarik, dan membuatku ingin melihat lagi proyek reverse engineering game yang beberapa tahun lalu kutinggalkan
    Akan bagus kalau ada contoh lengkap yang menunjukkan sampai akhir bagaimana ini dipakai dan bagaimana memanfaatkan hasil keluarannya

  • Aku penasaran berapa banyak pekerjaan yang dibutuhkan untuk mengetahui section executable mana yang harus diekspor
    Untuk game Win32 yang relatif modern sekitar 2008~2015, apakah realistis mengekspor ke object file lalu mengompilasi/menautkannya kembali menjadi executable lengkap dalam beberapa jam?

    • Selama tidak memotong di tengah variabel atau fungsi, kamu bisa mengekspor dengan cukup bebas, dan tidak harus mengikuti batas object file asli
      Apa yang harus diekspor adalah persoalan lain, jadi dibutuhkan pemahaman tentang program tersebut. Kalau ada debug symbol jauh lebih mudah, dan bahkan tanpa itu pun, setelah database Ghidra dibuat cukup akurat untuk memungkinkan ekspor, biasanya kamu sudah mulai punya gambaran apa ada di mana
      Dalam kasus penggunaan pada posting pengajuan, isu pertama diajukan pada awal Juli, dan sekitar pertengahan Agustus sudah didapat executable hasil relink yang berjalan secara fungsional identik
      Hanya saja saat itu masih banyak bug yang perlu diperbaiki pada ekspor COFF dan analyzer i386 juga masih perlu dibenahi, jadi harapannya sekarang orang lain akan lebih jarang menemui masalah yang sama
      Sulit menebak berapa lama tepatnya, tetapi kecuali ada debug symbol dan kamu benar-benar sangat beruntung, kemungkinan besar akan butuh lebih dari beberapa jam. Reverse engineer yang berpengalaman mungkin bisa membuat sesuatu yang setidaknya berjalan dalam waktu itu, tetapi bisa saja crash di tengah layar loading pertama, dan ini lebih mirip pekerjaan yang sampai selesai pun kamu tidak tahu kapan akan selesai
  • Kelihatannya keren. Mungkin suatu hari ini bisa membantu membongkar program yang sudah ada dengan lebih mudah lalu memakainya sesuai keinginan
    Ada riset seperti LLM Compiler milik Meta atau dekompilasi dengan LLM, dan pekerjaan memecah program lalu mengganti sebagian bagiannya bisa menjadi area menarik yang kaya data untuk dijelajahi dan diperbaiki sendiri oleh LLM
    Dari sudut pandang pembelajaran juga tampaknya ada banyak token menarik yang tersembunyi, dan sepertinya banyak hal yang bisa dilakukan dengannya

  • Sejujurnya terdengar seperti sihir. Aku harus coba memahami bagaimana ini bisa dilakukan

    • Sederhananya, file objek terdiri dari tiga bagian: byte section yang dapat direlokasi, tabel relokasi, dan tabel simbol.
      Saat linker membuat executable dari beberapa file objek, ia menempatkan section di memori, menghitung alamat simbol di ruang alamat virtual, lalu menerapkan relokasi pada byte section berdasarkan alamat simbol final.
      Trik delink adalah menemukan di mana relokasi itu diterapkan lalu membatalkannya, sehingga byte yang dapat direlokasi bisa didapat kembali. Setelah itu, berdasarkan hasil pembalikan tersebut, dibuat tabel relokasi dan tabel simbol, lalu dikemas menjadi file objek.
      Bagian yang benar-benar sulit adalah analisis untuk menemukan titik relokasi. Sebagian besar diserahkan ke Ghidra, tetapi tetap perlu mengubah referensi menjadi titik relokasi. Pada x86 ini relatif mudah, sedangkan pada MIPS sangat sulit seperti mimpi buruk. Ekstensi ini dibuat untuk mengotomatisasi pengumpulan data yang dibutuhkan dan serialisasi file objek
    • Ini memang tidak akan mudah di semua arsitektur CPU, tetapi juga tidak setidak masuk akalnya seperti yang terlihat. Pada dasarnya, perbedaan antara file objek dan executable atau shared library tidak terlalu besar.
      Di luar platform Microsoft, kadang format file nyatanya sama, misalnya ELF.
      Perbedaan besarnya ada pada relokasi. File objek memiliki informasi relokasi yang rinci, sedangkan executable biasanya tidak. Image executable di Windows hanya memiliki relokasi minimum yang menunjuk alamat kode dan data yang harus diperbaiki saat executable direlokasi, dan image itu sendiri hanya bisa direlokasi sebagai satu kesatuan terhadap base address image.
      Sebaliknya, file objek memiliki relokasi per simbol. Untuk merekonstruksi informasi ini dengan akurat, disassembly harus diberi informasi simbol yang cukup akurat.
      Perbedaan besar lainnya adalah file objek belum di-link. Tidak ada simbol yang sudah di-resolve. Ini justru lebih mudah diperbaiki: saat delink, jika suatu simbol berada di luar cakupan saat ini, biasanya cukup diubah menjadi simbol tak terselesaikan. Saat di-link ulang nanti, file objek atau library lain harus menyediakan simbol itu agar sambungannya pulih.
      Ada juga perbedaan kecil seperti tidak adanya entry point, tetapi itu tidak terlalu berarti.
      Jadi, batas untuk memotong file objek dari image executable atau shared object pada dasarnya bersifat arbitrer. Saat awal dikompilasi mungkin memang dibagi menurut translation unit, tetapi pada tahap linking batas-batas itu tidak terlalu diperhatikan. Tentu saja, jika ingin dekompilasi yang cocok persis, batas file objek yang salah bisa membuatnya jauh lebih sulit, jadi sebaiknya dicari tahu jika memungkinkan.
      Aku pernah menangani masalah ini secara nyata, tetapi mungkin ada beberapa detail yang sedikit keliru, jadi anggap saja sebagai referensi. Aku sempat ingin menulis artikel blog tentang file objek, dan sebenarnya sudah ada beberapa tulisan yang cukup bagus
  • Aku penasaran apakah proses ini benar-benar aman. Apakah selalu dijamin berhasil, atau analisisnya bekerja secara konservatif?
    Misalnya, jika ada fragmen, data, atau fungsi yang hilang di ELF, apakah delink akan gagal?

    • Jawabannya rumit.
      Analyzer milikku setidaknya bergantung pada database Ghidra yang akurat untuk bagian yang ingin diekspor. Aku sudah berusaha keras mencatat ke log berbagai masalah yang perlu diperbaiki, tetapi sesuatu yang tidak ada memang tidak bisa terlihat.
      Secara khusus, referensi yang hilang dan variabel yang terpotong tidak akan terdeteksi, dan bisa berujung pada undefined behavior yang aneh.
      Ada cara untuk melacak sebagian masalah seperti ini. Metode terbaik yang sejauh ini kutemukan adalah me-link ulang executable ke base address lain dan memastikan rentang alamat program asli tidak dipetakan. Dengan begitu, titik relokasi absolut yang terlewat akan memicu segmentation fault dan bisa di-debug. Namun ini hanya mungkin jika target memiliki MMU.
      Variabel yang terpotong sangat sulit dilacak, terutama kalau dari awal tidak dicurigai. Yang rusak adalah memori setelah variabel yang terpotong itu. Kasus ketika integer disalahartikan sebagai pointer juga sulit ditelusuri. Nilai integer berubah tergantung alamat tempat simbol target ditempatkan, sehingga perilaku program bisa menjadi tidak konsisten, terutama pada program yang dimuat sangat rendah di ruang alamat.
      Meski begitu, jika database Ghidra cukup akurat, lalu hasilnya diekspor kembali dalam format file objek yang sama seperti aslinya, dan menggunakan platform serta toolchain yang sama, kode dan data program berskala megabyte bisa berhasil di-delink. Kalau linker bisa melakukannya, mestinya proses membalikkannya juga mungkin.
      Sebaliknya, kalau mulai melakukan cross-delinking yang tidak sesuai dengan platform dan toolchain program asli—misalnya mendelink executable Linux i386 ELF menjadi file objek COFF untuk dipakai di toolchain i386 Windows—ceritanya jadi berbeda. Jika ekspornya bisa merepresentasikan relokasi, mungkin saja tetap didapat file objek relokatif yang berfungsi, tetapi Anda juga harus berhadapan dengan ketidakcocokan ABI. Itu mungkin dilakukan, tetapi bukan proyek pertama yang akan kurekomendasikan.
      Singkatnya, hasilnya bisa berkisar dari “langsung jalan” sampai “memohon belas kasihan pada Cthulhu”, tergantung apa yang Anda lakukan dan seberapa akurat database Ghidra-nya
    • Kalau sesuai maksud pertanyaannya, ini tidak sepenuhnya aman, dan memang tidak mungkin sepenuhnya aman.
      Misalnya, bayangkan fungsi seperti int getSpecialArrayElement(char *array, uint64 key) { i = computeOffset(key); return array[i]; }
      computeOffset bisa dibuat serumit apa pun, dan jika ingin obfuscation, bisa sengaja dibuat sulit dianalisis. Tidak ada yang mencegah fungsi ini mengakses lokasi arbitrer di memori.
      Kecuali Anda mencoba semua kemungkinan input, tidak ada cara untuk tahu apakah ia mengakses simbol yang sudah didefinisikan linker di memori, dan computeOffset bahkan bisa memuat jebakan Turing untuk menghalangi upaya semacam itu
  • Akan menarik jika dikaitkan dengan ide yang dulu hanya pernah saya bayangkan tapi tidak benar-benar saya buat. Yaitu membuat file header dari informasi debug, lalu jika perlu merapikannya dengan LLM

    • Memang sudah ada beberapa upaya seperti itu. Untuk Microsoft Program Database, ada ini
      https://github.com/wbenny/pdbex
      Soal bagian merapikan dengan LLM, tampaknya belum banyak contoh penerapan model LLM pada rekayasa balik yang meraih keberhasilan besar. Bisa jadi ini justru area tempat keterbatasan arsitektur LLM terlihat jelas
      Saya bukan ahli, tetapi jika harus memilih, untuk banyak kasus penggunaan rekayasa balik model difusi tampak lebih menarik
      Tidak persis sama, tetapi Binary Ninja punya fitur bernama Sidekick yang mencoba merapikan hasil disassembly dengan LLM. Secara pribadi saya tidak terlalu terkesan, tetapi mungkin berguna bagi orang lain
    • pahole dapat membuat file header C yang bisa dikompilasi dari informasi ELF DWARF
      Di sini LLM tampaknya tidak terlalu relevan. File header itu entah berisi semua tipe yang diekspor dari biner dengan benar beserta nilai aslinya sehingga bisa dipakai, atau memang salah maupun tidak lengkap. Membiarkan LLM mengarang sesuatu tidak akan membantu
      Ghidra juga punya fitur bawaan untuk mengekspor struktur data, dan bisa dibuat dari struktur DWARF. Klik kanan -> Export to C header
    • Beberapa tahun lalu saya membuat alat yang secara otomatis menghasilkan dan menyisipkan fuzzer yang sadar tipe untuk API C dari informasi DWARF: https://github.com/intel/fffc
      Pembuatan header, beserta pembuatan mutator yang kemudian bisa dimodifikasi agar sesuai dengan batasan tipe, juga merupakan bagian darinya
      Jika ditambah sisi LLM, tampaknya mungkin untuk memberi nama pada hal-hal seperti struct anonim, tetapi saya tidak yakin itu ide yang bagus. Yang lebih menarik mungkin mencoba membuat LLM menjelaskan dengan kata-kata batasan tipe yang sudah diketahui untuk tujuan dokumentasi
    • Sedikit topik berbeda, tetapi saya pernah memikirkan cara untuk meningkatkan pengalaman debugging dengan membuat simbol debug untuk file objek yang diekspor berdasarkan isi basis data Ghidra
      Alasan saya belum mengimplementasikannya adalah karena sejauh ini saya masih bisa bertahan tanpanya. Lagi pula, itu terdengar seperti lubang kelinci yang cukup dalam, dan lubang kelinci yang sedang saya masuki sekarang saja sudah cukup besar
  • Ini tampak sangat keren, dan juga berkaitan dengan ide modding game yang pernah saya pikirkan sebelumnya. Seri blog dekompilasi Tenchu juga bagus

    • Suatu hari saya harus kembali ke proyek ini. Saya perlu istirahat karena terlalu banyak sesi pelacakan versi berturut-turut, dan di tengah itu side quest delinking terus membesar di luar kendali
  • Tidak ada kegunaan langsung untuk pekerjaan saya saat ini, tetapi ini tampak seperti alat yang akan sangat berguna kalau saya masih mengerjakan hal yang dulu
    Semoga dalam waktu dekat saya punya waktu atau kesempatan untuk mencobanya