Javada Disassembler ve Decompiler İşlemleri

Java ile yazılan uygulamalar bilindiği gibi .java uzantılı kaynak dosyalara sahiptir.

Uygulamayı çalıştırabilmek için ise, öncelikle Java derleyicisi (compiler) ile bu kaynak dosyaları JVM (Java Virtual Machine) nin anlayacağı bytecode lara derlememiz gerekiyor. Bytecode, .java uzantılı kaynak dosyaların JVM üzerinde çalıştırılabilir formu olan ve .class uzantılı Java dosyalarıdır.

Elimizdeki .class uzantılı dosyaları Java platformunun sunduğu araçları kullanarak, kaynak dosyadaki bileşenlere ayrıştırılmış halini elde edebiliyoruz. Bu işleme disassemble adı veriliyor.

Daha da önemli ve ilginç olanı ise, .class uzantılı derlenmiş bytecodeları, ek birtakım araçlar kullanarak tekrar kaynak dosya biçimine çevirebiliyoruz. Bu işleme de decompile adı veriliyor.

Bu yazıda bu iki işlemin Javada nasıl yapıldığını anlatmaya çalışıcam. Öncelikle konuyu örnekler üzerinden ele alacağım için, Test.java adında basit bir Java uygulaması yazalım. Decompiler ve Disassembler işlemlerini bu kaynak dosya üzerinde örneklendirmeye çalışıcaz.

Aşağıdaki kaynak dosyayı :

javac Test.java

komutu ile .class uzantılı bytecodelara derleyin.

//Test.java kaynak dosyası
 
public class Test
{
    public static String mesaj = "Java ile Disassembler ve Decompiler İşlemleri";
    public static void main(String[] args)
    {
        String mesajEk = "Gayet Basit";
        mesaj(mesajEk);
        for(int i = 0;i < 10 ; i++)
        {
            System.out.println(i);
        }
    }
    public static void mesaj(String mesajEk)
    {
        System.out.println(mesaj + " " + mesajEk);
    }
} // end of class

Javada Disassembler İşlemi

Java bytecodeları üzerinde disassembler işlemini gerçekleştirmek için Java platformunun sunduğu javap komutunu kullanıyoruz.

Yukarıda yazdığımız ve bytecodea çevirdiğimiz .class uzantılı dosyayı javap ile disassembler yapmak için, komut satırı ya da terminal üzerinde

javap Test

komutunu vermek yeterli. Çıktı olarak, kaynak dosya üzerindeki bileşenleri ekranda göreceksiniz.

Komutu verdikten sonra çıktı şu şekilde olması gerek.

javap Test
Compiled from "Test.java"
public class Test extends java.lang.Object {
    public static java.lang.String mesaj;
    public Test();
    public static void main(java.lang.String[]);
    public static void mesaj(java.lang.String);
    static {}
}

Müthiş değil mi. Böylece bir Java kayak dosyasının aslında ne şekilde derlendiğini de bu sayede görebiliyoruz. Farkettiğiniz üzere, herhangi bir sınıf oluşturulduğunda, derleme sırasında otomatik olarak java.lang.Object sınıfından türetiliyor (inanmayanlar için bir kanıt :) ) Ayrıca eğer bir yapılandırıcı (constructor) method tanımlamazsak, Java bizim için boş bir constructor methodu yine otomatik olarak tanımlıyor. Bir de, çağrılan diğer sınıflar, doğrudan paket uzantısı ile ele alınıyor.

Javap komutunu -c uzantısı ile çalıştırırsanız, kaynak dosyanızın bytecode bilgisini de ekrana yazdırabilirsiniz.

javap -c Test

Javada DeCompiler İşlemi

Java ile Disassembler işleminden sonra, artık .class uzantılı bytecodeları tekrar kaynak dosya haline çevirme (decompile) işleminden bahsedebiliriz. Bytecodelar bilindiği gibi, JVM nin anlayacağı bir ara formdur. Doğrudan bytecode dosyasını bir metin editörü ile açıp, Java kaynak kodlarına ulaşmak mümkün değil. Ancak JAD Java Decompiler adındaki bir yazılım sayesinde, bytecode dosyalarını Java kaynak dosyalarına tekrar çevirebiliyoruz.Yapmamız gerekenler çok basit.

Öncelikle şu adresden JAD Java Decompiler programını indirin.

İndirdiğiniz dosya tek bir çalıştırılabilir (executable) dosyadan oluşuyor. Jad adındaki bu program ile decompile işlemini başlatabiliriz.

Kaynak dosyamızı derlediğimiz klasöre jad programını kopyalayın. Daha sonra yine terminal veya komut satırı üzerinden :

jad Test

komutunu vererek, bytecode dosyasını tekrar Java kaynak dosyasına dönüştürme işlemini başlatın. Program, kaynak kodları içeren .jad uzantılı bir dosya (Test.jad) üretecek. İşte bu dosya, içeriğinde bytecode dosyasının decompile edilmiş saj Java kodlarını içerir.

Test.jad dosyasının içeriği

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name:   Test.java
 
import java.io.PrintStream;
 
public class Test
{
 
    public Test()
    {
    }
 
    public static void main(String args[])
    {
        String s = "Gayet Basit";
        mesaj(s);
        for(int i = 0; i < 10; i++)
            System.out.println(i);
 
    }
 
    public static void mesaj(String s)
    {
        System.out.println((new StringBuilder()).append(mesaj).append(" ").append(s).toString());
    }
 
    public static String mesaj = "Java ile Disassembler ve Decompiler \u0130\u015Flemleri";
}

Gördüğünüz gibi bytecode dosyasından, tekrar Java kaynak dosyasını elde ettik. Burda dikkat edilmesi gereken nokta, Java derleyicisi Java kaynak dosyasını derlerken birtakım kod optimizasyonları yapmış.


İlgili Yazılar:

  1. Java Scanner ve Formatter Sınıfları ile Dosya İşlemleri
  2. Javada Karar Mekanizmaları – if ve switch komutları
  3. Javada Sayılar ve Number Sınıfı
  4. Java Programlama Ama Nasıl ve Nerden Başlamalı?
  5. Javada Döngüler (Loops)

Yorum bırakmak için buraya, Sitenizden trackback vermek için buraya tıklayabilirsiniz.

Leave a Reply