Decompiler adalah nama yang diberikan untuk sebuah program komputer yang melakukan, sejauh mungkin, operasi terbalik dengan sebuah compiler. Artinya, ia menterjemahkan sebuah file yang berisi informasi pada tingkat yang relatif rendah abstraksi (biasanya dirancang untuk menjadi komputer yang dapat dibaca daripada yang dapat dibaca manusia) menjadi bentuk yang memiliki tingkat abstraksi yang lebih tinggi (biasanya dirancang untuk dapat dibaca manusia). Decompiler tidak merekonstruksi kode sumber asli, dan output yang jauh kurang dimengerti oleh manusia dari kode sumber aslinya.
Disassembly
Tahap logis berikutnya adalah pembongkaran instruksi kode mesin menjadi
representasi mesin menengah independen (IR). Sebagai contoh, instruksi mesin
Pentium
mov eax, [ebx +0 x04]
mungkin diterjemahkan ke IR
eax: = m [ebx +4];
Idiom
Urutan kode mesin idiomatic adalah urutan kode yang gabungan semantik adalah
tidak segera jelas dari semantik individu petunjuk '. Baik sebagai bagian dari
tahap pembongkaran, atau sebagai bagian dari analisis kemudian, urutan ini
idiomatic perlu diterjemahkan ke dalam IR setara dikenal. Sebagai contoh, kode assembly x86 :
CDQ eax; edx diatur untuk perpanjangan pendaftaran dari eax
xor eax, edx
sub eax, edx
dapat diterjemahkan ke
eax: = abs (eax);
Beberapa urutan idiomatik adalah mesin independen, beberapa hanya melibatkan
satu instruksi. Sebagai contoh,
xor eax,
eax
membersihkan eax
register (set ke nol). Ini dapat diimplementasikan dengan aturan mesin
penyederhanaan independen, seperti a xor a
= 0
.
Secara umum, yang terbaik adalah untuk menunda deteksi urutan idiomatic jika
mungkin, untuk tahap selanjutnya yang kurang dipengaruhi oleh instruksi
pemesanan. Misalnya, penjadwalan instruksi fase kompilator dapat menyisipkan
instruksi lain ke urutan idiomatic, atau mengubah pemesanan instruksi dalam
urutan. Sebuah pencocokan pola proses dalam tahap pembongkaran mungkin tidak
mengenali pola berubah. Tahap selanjutnya instruksi ekspresi kelompok menjadi
ekspresi yang lebih kompleks, dan mengubah mereka menjadi bentuk (standar)
kanonik, sehingga kemungkinan bahwa bahkan idiom diubah akan cocok dengan pola
tingkat yang lebih tinggi kemudian di dekompilasi.
Sangat penting untuk mengenali idiom compiler untuk subroutine panggilan, exception handling , dan pernyataan saklar . Beberapa bahasa juga
memiliki dukungan luas untuk string atau bilangan bulat panjang .
Analisis Program
Analisis berbagai program dapat diterapkan untuk IR. Secara khusus, propagasi
ekspresi menggabungkan semantik dari beberapa instruksi menjadi ekspresi yang
lebih kompleks. Sebagai contoh,
mov eax, [ebx +0 x04]
add eax, [ebx +0 x08]
sub [ebx +0 x0C], eax
dapat mengakibatkan IR berikut setelah propagasi ekspresi:
m [ebx +12]: = m [ebx +12] - (m [ebx +4] + m [ebx +8]);
Ekspresi yang dihasilkan lebih seperti bahasa tingkat tinggi, dan juga telah
menghapuskan penggunaan mesin mendaftar
eax
. Kemudian analisis dapat menghilangkan ebx
mendaftar. Analisis data aliran
Tempat di mana daftar isi didefinisikan dan digunakan harus ditelusuri
dengan menggunakan analisis aliran data . Analisis yang sama
dapat diterapkan pada lokasi yang digunakan untuk revision dan data lokal.
Sebuah nama yang berbeda maka dapat dibentuk untuk setiap set terhubung seperti
definisi nilai dan kegunaan. Ada kemungkinan bahwa lokasi lokal variabel yang
sama digunakan untuk lebih dari satu variabel dalam berbagai bagian dari
program asli. Lebih buruk lagi adalah mungkin untuk analisis aliran data untuk
mengidentifikasi jalur dimana nilai dapat mengalir antara dua penggunaan
tersebut meskipun tidak akan pernah benar-benar terjadi atau masalah dalam
kenyataan. Ini mungkin dalam kasus-kasus buruk menyebabkan perlu mendefinisikan
lokasi sebagai kesatuan jenis. Decompiler dapat memungkinkan pengguna untuk
secara eksplisit melanggar dependensi yang tidak alami seperti yang akan
menyebabkan kode yang lebih jelas. Ini tentu saja berarti suatu variabel
berpotensi digunakan tanpa dimulai dan sehingga mengindikasikan adanya masalah
dalam program asli.
Jenis analisis
Sebuah mesin yang baik Decompiler kode akan melakukan analisis jenis. Di
sini, cara register atau lokasi memori yang digunakan mengakibatkan kendala
pada jenis kemungkinan lokasi. Sebagai contoh, sebuah
and
instruksi menyiratkan bahwa operan
adalah bilangan bulat; program tidak menggunakan seperti operasi pada floating point nilai (kecuali dalam kode
perpustakaan khusus) atau pointer . Sebuah add
hasil instruksi dalam tiga kendala, karena operan mungkin baik integer, atau
satu integer dan satu pointer (dengan hasil integer dan pointer masing-masing;
kendala ketiga berasal dari urutan dari dua operan ketika jenis berbeda).
Berbagai ekspresi tingkat tinggi dapat diakui yang memicu pengakuan struktur
atau array. Namun, sulit untuk membedakan banyak kemungkinan, karena kebebasan
yang kode mesin atau bahkan beberapa bahasa tingkat tinggi seperti C
memungkinkan dengan gips dan aritmetik pointer.
Contoh dari bagian sebelumnya dapat mengakibatkan kode berikut tingkat
tinggi:
struct T1 * ebx;
struct {T1
int v0004;
int v0008;
int v000C;
};
ebx-> v000C - = ebx-> v0004 + ebx-> v0008;
Penataan
Tahap kedua dari belakang dekompilasi melibatkan penataan IR ke konstruksi
tingkat yang lebih tinggi seperti
while
loop dan if/then/else
pernyataan bersyarat. Sebagai contoh, kode mesin xor eax, eax
l0002:
atau ebx, ebx
jge l0003
add eax, [ebx]
mov ebx, [ebx +0 x4]
JMP l0002
l0003:
mov [0x10040000], eax
dapat diterjemahkan menjadi:
eax = 0;
sementara (ebx <0) {
eax + = ebx-> v0000;
ebx = ebx-> v0004;
}
v10040000 = eax;
Kode terstruktur lebih sulit diterjemahkan ke dalam kode terstruktur dari
kode yang sudah terstruktur. Solusi termasuk mereplikasi beberapa kode, atau
menambahkan variabel boolean.
Kode generasi
Tahap akhir adalah generasi dari kode tingkat tinggi di ujung belakang
decompiler ini. Sama seperti kompilator mungkin harus kembali beberapa berakhir
untuk menghasilkan kode mesin untuk arsitektur yang berbeda, Decompiler mungkin
memiliki beberapa ujung kembali untuk menghasilkan kode tingkat tinggi dalam
berbagai bahasa tingkat tinggi.
Tepat sebelum generasi kode, mungkin diinginkan untuk memungkinkan
penyuntingan interaktif dari IR, mungkin dengan menggunakan beberapa bentuk antarmuka pengguna grafis . Hal ini akan
memungkinkan pengguna untuk memasukkan komentar, dan non-generik variabel dan
nama fungsi. Namun, ini hampir sama dengan mudah masuk di posting dekompilasi
edit. Pengguna mungkin ingin mengubah aspek struktural, seperti mengkonversi
while
loop untuk sebuah for
loop. Ini kurang mudah dimodifikasi
dengan editor teks sederhana, meskipun sumber kode refactoring tools dapat membantu dengan
proses ini. Pengguna mungkin perlu memasukkan informasi yang gagal
diidentifikasi selama tahap analisis jenis, misalnya memodifikasi ekspresi
memori untuk ekspresi array atau struktur. Akhirnya, IR tidak benar mungkin
perlu dikoreksi, atau perubahan yang dibuat untuk menyebabkan kode output
menjadi lebih mudah dibaca.
Tidak ada komentar:
Posting Komentar