Dengan bahasa mesin virtual berbasis bytecode seperti Java, VB.NET, C #, ActionScript 3.0, dll. Anda kadang-kadang mendengar betapa mudahnya untuk hanya mengunduh beberapa decompiler dari Internet, menjalankan bytecode melewatinya sekali, dan seringkali, muncul dengan sesuatu yang tidak terlalu jauh dari kode sumber asli dalam hitungan detik. Seharusnya bahasa semacam ini sangat rentan terhadap hal itu.
Saya baru-baru ini mulai bertanya-tanya mengapa Anda tidak mendengar lebih banyak tentang ini tentang kode biner asli, ketika Anda setidaknya tahu bahasa mana itu ditulis pada awalnya (dan dengan demikian, bahasa mana untuk mencoba mendekompilasi ke dalam). Untuk waktu yang lama, saya pikir itu hanya karena bahasa mesin asli jauh lebih gila dan lebih kompleks daripada bytecode khas.
Tapi seperti apa bytecode? Ini terlihat seperti ini:
1000: 2A 40 F0 14
1001: 2A 50 F1 27
1002: 4F 00 F0 F1
1003: C9 00 00 F2
Dan seperti apa kode mesin asli (dalam hex)? Itu, tentu saja, terlihat seperti ini:
1000: 2A 40 F0 14
1001: 2A 50 F1 27
1002: 4F 00 F0 F1
1003: C9 00 00 F2
Dan instruksinya datang dari kerangka pikiran yang agak mirip:
1000: mov EAX, 20
1001: mov EBX, loc1
1002: mul EAX, EBX
1003: push ECX
Jadi, mengingat bahasa untuk mencoba mendekompilasi beberapa biner asli ke, katakanlah C ++, apa yang sulit tentang itu? Hanya dua ide yang langsung terlintas dalam pikiran adalah 1) itu benar-benar jauh lebih rumit daripada bytecode, atau 2) sesuatu tentang fakta bahwa sistem operasi cenderung membuat paginasi program dan menyebarkan potongan-potongan mereka menyebabkan terlalu banyak masalah. Jika salah satu dari kemungkinan itu benar, mohon jelaskan. Tapi bagaimanapun juga, mengapa Anda tidak pernah mendengar hal ini pada dasarnya?
CATATAN
Saya akan menerima salah satu jawabannya, tetapi saya ingin menyebutkan sesuatu terlebih dahulu. Hampir semua orang merujuk kembali pada fakta bahwa bagian-bagian berbeda dari kode sumber asli dapat dipetakan ke kode mesin yang sama; nama variabel lokal hilang, Anda tidak tahu jenis loop apa yang awalnya digunakan, dll.
Namun contoh-contoh seperti dua yang baru saja disebutkan itu agak sepele di mataku. Beberapa jawaban meskipun cenderung menyatakan bahwa perbedaan antara kode mesin dan sumber asli jauh lebih banyak daripada sesuatu yang sepele ini.
Tetapi misalnya, ketika sampai pada hal-hal seperti nama variabel lokal dan tipe loop, bytecode juga kehilangan informasi ini (setidaknya untuk ActionScript 3.0). Saya telah menarik hal itu kembali melalui dekompiler sebelumnya, dan saya tidak terlalu peduli apakah suatu variabel dipanggil strMyLocalString:String
atau loc1
. Saya masih bisa melihat dalam lingkup lokal kecil itu dan melihat bagaimana itu digunakan tanpa banyak masalah. Dan satu for
loop adalah hal yang persis sama dengan awhile
lingkaran, jika Anda memikirkannya. Juga bahkan ketika saya akan menjalankan sumber melalui irrFuscator (yang, tidak seperti secureSWF, tidak melakukan lebih dari sekadar mengacak variabel anggota dan nama fungsi), itu masih tampak seperti Anda bisa mulai mengisolasi variabel dan fungsi tertentu dalam kelas yang lebih kecil, bagaimana mereka digunakan, tetapkan nama Anda sendiri untuk mereka, dan bekerja dari sana.
Agar ini menjadi masalah besar, kode mesin harus kehilangan lebih banyak informasi dari itu, dan beberapa jawaban masuk ke ini.