Jenis konversi kode yang digunakan dalam file yang dapat dieksekusi Linux

13

Saya ingin bertanya bahwa jenis pengkodean apa yang digunakan untuk membuat file yang dapat dieksekusi linux mis. Hexadecemal, biner atau yang lainnya. bagaimana cara dikonversi? Apakah ada cara untuk mendapatkan kembali kode asli dari file yang dapat dieksekusi ini?

Berikut sedikit kode yang saya miliki:

ELF���������>�����%|�����@�������������������@�8��@���������������������@�������@�����7<�����7<������� ������������������f�����f���������������������� ������[�UPX!L
h�h�8����������?�E�h=��ڊ̓�N�    4���9ISloB�q�w�]ȉ.��,ς��Q䝦����#e��-�N����/�b,���d<��'��-E��6E�s�/�U���ly�V�Y2]"a��S�.�hU�|�S�J�I�2���X}
�G0�;���5d�$���.)

apa maksudnya artinya?

Redchief
sumber
Meskipun itu tidak akan membantu Anda mendapatkan banyak hal kembali, perlu dicatat bahwa stringsprogram filter dapat sangat berguna dalam mengidentifikasi apa program biner tertentu atau tidak karena akan mencetak semua string teks yang tertanam lebih lama dari panjang yang ditentukan dalam sebuah file biner dan melihat pesan dalam suatu program terkadang memberi tahu Anda banyak tentang apa itu dan apa yang dilakukannya.
Joe
Kemungkinan duplikat / parsial? stackoverflow.com/questions/193896/whats-a-good-c-decompiler
arielf

Jawaban:

29

Ini biner. Kode sumber telah dikompilasi. Anda dapat melihatnya di editor (editor heksa seperti blessmungkin membuat lebih banyak perubahan yang disempurnakan) tetapi Anda benar-benar perlu tahu apa yang Anda lakukan. Sepertinya hanya bagus untuk membuat perubahan string.

Untuk yang lebih hardcore, Anda bisa mulai merekayasa balik biner menjadi kode assembly . Ini sering dianggap sebagai tingkat komputer yang dapat diurai oleh manusia tingkat terendah.

objdump -d helloworld | less

Tapi itu akan mencakup banyak kompiler juga omong kosong. Misalnya, jika Anda mengkompilasi yang paling sederhanahelloworld.cpp dengan G ++ lalu objdump, Anda berakhir dengan 226 baris (208 dilucuti) dari yuck. Anda bisa menulis "halo dunia" hanya dalam 15 baris perakitan , kompilasi dan objdumpitu tetapi masih mekar menjadi 166 baris (dilucuti).

Jika Anda cukup baik dengan perakitan, ini mungkin memberi Anda cukup akses untuk memahami apa yang terjadi, dan bahkan membiarkan Anda mengubahnya ... Tetapi untuk menjawab pertanyaan awal Anda:

Anda tidak dapat mengubah kode yang dikompilasi kembali menjadi kode sumber asli .

Maaf. Ini adalah transformasi satu arah yang kehilangan informasi (komentar, pemformatan, konsep algoritma yang dapat dibaca, dll), secara statis terkait dengan hal-hal lain dan umumnya dioptimalkan sedemikian rupa yang akan membuatnya tidak dapat dipahami oleh apa pun kecuali programmer terbaik dan paling berpengalaman.

Untuk memberi Anda gambaran tentang skala masalah, seluruh gagasan perangkat lunak rekayasa terbalik memiliki situs Stack Exchange sendiri .

Oli
sumber
Bisakah Anda ceritakan bagaimana cara membalikkannya dan mendapatkan kembali jumlah kode karena saya kehilangan sumber
redchief
7
Lihat hasil edit terbaru saya. Tidak akan kembali ke sumber aslinya. Dengan banyak pembelajaran dan banyak waktu, Anda mungkin dapat menulis ulang sumber berdasarkan kode perakitan yang dibongkar, tetapi dalam kebanyakan kasus, itu akan lebih murah (kecuali waktu Anda tidak berharga) dan lebih mudah untuk hanya menulis ulang dari awal.
Oli
1
Cara untuk mendapatkan kembali jumlah kode maksimum adalah dengan mengembalikan cadangan terbaru. Itu juga, kebetulan, satu - satunya cara untuk mendapatkan kembali sesuatu yang mirip dengan kode sumber asli.
CVn
1
Sama sekali tidak setuju dengan paragraf terakhir, hanya sebuah catatan: beberapa dekompiler IME bekerja dengan baik dalam memulihkan struktur kode yang tepat (selain tentu saja ketika Anda mengatakan komentar, format, nama simbol ...). Jika Anda tidak menulis program di tempat pertama kode sumber yang dipulihkan mungkin masih tidak dapat dipahami, namun saya pikir ini adalah pilihan bagus untuk memulihkan (setidaknya sebagian) kode sumber yang hilang / kode sumber yang tidak dikenal (dengan setidaknya sebagian dari itu sebenarnya dapat dipahami, tergantung pada kode spesifik dan apakah Anda beruntung juga)
kos
1
Itulah yang dikatakan oleh semua EULA di dunia perangkat lunak berpemilik yang tidak boleh Anda lakukan - rekayasa balik / pembongkaran. Mereka memasukkan klausa seperti ini karena itu mungkin dilakukan - tetapi tentu saja tidak mudah! Tapi seperti yang dikatakan @ MichaelKjörling, satu-satunya cara yang baik untuk mendapatkan kembali adalah dari berbagai tingkat cadangan untuk apa pun yang Anda pedulikan.
Joe
7

Saya tidak memiliki poin reputasi yang cukup untuk komentar sehingga itu adalah jawaban:

Tidak, tidak mungkin untuk mengubahnya "kembali". Anda menyebutkan upx packer, apakah Anda pernah membaca manual upx?

Jika Anda kehilangan sumbernya, atau tidak memiliki akses ke kode orang lain, tidak masalah di sini, tidak mungkin.

Eksekusi biner diproduksi dengan kompiler, jangan percaya apa pun yang dinyatakan di situs ini, cukup baca manual kompiler itu. Kemudian, Anda dapat menambahkan di sini, dalam bahasa apa kode asli ditulis, kompiler mana yang digunakan, dan kemudian Anda dapat mencatat sendiri bahwa langkah-langkah ini (preprocessing, kompilasi, menghubungkan, mungkin pengepakan) tidak terbalik secara keseluruhan, tetapi hanya bisa dianalisis apa yang dimaksudkan oleh penulis asli, dan ditulis.

justabot
sumber
3

Seperti yang ditunjukkan oleh Oli dalam jawabannya, Anda tidak bisa mendapatkan kode sumber asli dari file yang dapat dieksekusi.

Selama kompilasi kode sumber (kompilasi dimaksudkan sebagai dalam penerimaan umum yang lebih luas, maka sebagai keseluruhan proses yang "mengubah" kode sumber menjadi executable), banyak informasi yang hilang.

Preprocessor C, untuk satu, akan melakukan hal berikut (antara lain):

  • Menafsirkan, mengeksekusi dan menghapus arahan preprocessor ( #pernyataan)
  • Hapus komentar
  • Hapus spasi yang tidak perlu

Di sisi lain, apa yang tidak hilang selama kompilasi kode sumber secara teknis dapat dikembalikan ke kode sumber yang secara fungsional setara.

Hal ini karena:

  • Instruksi biner memiliki korrispondensi 1: 1 dengan instruksi perakitan; perakitan kode sumber rakitan hanya merupakan konversi belaka dari instruksi rakitan menjadi instruksi biner berdasarkan tabel korespondensi; instruksi biner tunggal selalu dapat diidentifikasi dan dapat dikembalikan ke instruksi assembly tunggal ;
  • Instruksi perakitan tidak memiliki korrispondensi 1: 1 dengan instruksi C; kompilasi kode sumber C biasanya bukan hanya konversi belaka dari instruksi C ke instruksi perakitan berdasarkan pada tabel korrispondensi, bahkan seringkali sebaliknya; biasanya instruksi C dikonversi menjadi instruksi perakitan multipel (seringkali berbeda berdasarkan kompiler); namun, pola instruksi rakitan banyak biasanya dapat diidentifikasi dan dapat dikembalikan ke instruksi C tunggal ;

Ada alat yang disebut pengurai yang tujuannya adalah untuk mencoba mengembalikan yang dapat dieksekusi ke kode sumber yang secara fungsional setara; namun hasilnya biasanya sesuatu yang jauh dari kode sumber asli (dan biasanya juga tidak dapat dikompilasi);

Pertimbangkan program ini:

#include <stdio.h>

#define MESSAGE "Literal strings will be recovered" // This preprocessor directive won't be recovered

/*

This comment and the comment above won't be recovered

*/

int main(int argc, char* argv[]) {
    printf(MESSAGE);
    return 0;
}

Dengan mengkompilasinya menjadi yang dapat dieksekusi dan mendekompilasinya menjadi kode sumber lagi, ini kurang lebih apa yang biasanya Anda dapatkan kembali (dalam kasus khusus ini saya menggunakan gcc/ Boomerang ):

// address: 0x80483fb
int main(int argc, char **argv, char **envp) {
    printf("Literal strings will be recovered");
    return 0;
}

Seperti yang diperkirakan:

  • Arahan preprosesor tidak ada
  • Komentar tidak ada (selain dari // address: 0x80483fb, yang telah ditambahkan oleh dekompiler)
  • Ruang kosong yang tidak perlu hilang (selain dari baris baru dan tabulasi, yang telah ditambahkan oleh dekompiler)

Ini juga hasil yang cukup bagus; tidak jarang mendapatkan instruksi perakitan inline ke dalam kode:

asm("assembly_instruction");
__asm__("assembly_instruction");

Intinya adalah (seperti yang sudah ditunjukkan dalam jawaban lain): Anda tidak bisa mendapatkan sumber asli dari file executable *.

* Namun, tergantung pada executable dan keberuntungan Anda, Anda mungkin bisa mendapatkan sesuatu menggunakan dekompiler.

kos
sumber
2

File executable biasanya biner jika Anda berbicara tentang program yang dikompilasi. Anda dapat menemukan informasi lebih lanjut dengan menggunakan file path/to/executable. Anda dapat menampilkan file biner yang dapat dieksekusi dalam heksadesimal dengan menggunakan eg hexdump -C path/to/executable | less(apa pun baiknya Anda). Jika Anda ingin "mengubahnya kembali ke bentuk aslinya" Anda harus menggunakan dekompiler yang sesuai untuk melihat posting ini, misalnya , meskipun itu akan memberi Anda kode yang cukup tidak terbaca bukan yang asli dari mana ia dikompilasi. Jika bukan biner yang dikompilasi, itu akan menjadi semacam skrip yang dapat dieksekusi, yang harus mudah dibaca di editor teks apa pun. Apa yang Anda tunjukkan di sini mungkin adalah executable yang dikompilasi. ELF berarti "Format yang dapat dijalankan dan Menghubungkan" yang merupakan format biner umum pada sistem Linux / Unix. Sana'strings path/to/executable, jika ini yang Anda butuhkan.

Hinz
sumber
Saya mencoba untuk merekayasa balik dengan upx packer tetapi tidak berhasil dan juga dengan pos yang Anda sarankan. Jadi tolong beri tahu saya jika ada cara lain.
redchief
Maaf, tapi saya tidak bisa memberi tahu Anda lebih dari apa yang tertulis di pos luar biasa @ Oli.
Hinz