15 Nisan 2014

Android Uygulamalarının Reverse Engineering (Tersine Mühendislik) Yöntemi ile İncelenmesi


Tersine mühendislik  bir aygıtın, objenin veya sistemin; yapısının, işlevinin veya çalışmasının, çıkarımcı bir akıl yürütme analiziyle keşfedilmesi işlemidir. Makine veya mekanik alet, elektronik komponent, yazılım programı gibi parçalarına ayrılması ve çalışma prensiplerinin detaylı şekilde analizini içerir.

Bir android uygulamasını herhangi bir arşiv programı (Winrar,Winzip v.b.) ile açtığımızda içerisinde Meta-InfClass, Resorce, AndroidManifest ve Res dosyalarını barındırdığı görülür. Şimdi bu dosyaların genel anlamda içeriğinden bahsedelim.


·META-INF Klasörü

   o      MANIFEST.MF: Bildiri dosyası.
   o      CERT.RSA: Uygulama sertifikası.
   o      CERT.SF: Kaynakların listesi.

·res: Kaynakları içeren dizin.

·AndroidManifest.xml: Ek Android bildirim dosyası olup içinde, uygulamanın adını, versiyonu,     erişim bilgileri, lib dosyalarının kaynağını belirten bilgiler yer almaktadır. Bu android XML dosyası herkes tarafından açılıp okunabilen düz XML metin haline dönüştürülebilir.

·classes.dex: Dalvik sanal makinesi (Dalvik virtual machine) tarafından anlaşılabilir dex dosya biçiminde derlenmiş dosyadır.

·resources.arsc : Örneğin XML gibi derlenmiş kaynakların bulunduğu dosyadır.

Reverse işlemimizde  kullanacağımız araçlar ve indirme sayfaları;

Android crackme 03.apk: http://crackmes.de/users/deurus/android_crackme03/
APK-MultiTool: http://apkmultitool.com/?q=node/5
Notpad++: http://notepad-plus-plus.org/download/v6.5.5.html
Dex2jar: http://code.google.com/p/dex2jar/
Java decompiler: http://java.decompiler.free.fr/

Reverse işlemi uygulayacağımız Crackme03.apk uygulamasını telefonumuza veya emalutörümüze   kurulumunu gerçekleştirip uygulamamızın fonksiyonlarına göz atalım.


Uygulamada check butonuna bastığımızda bize “Min  4 chars” uyarısı verdiğini gözlemledik.


Enter Name” ve “Enter Serial” kısmını herhangi bir şeyler yazdığımızda “Bad boy” uyarısını gözlemledik.


Karşımıza çıkan uyarılar ilerleyen adımlarda reverse işleminde bizlere yardımcı olacak.
Şimdi Crackme03.apk’yı APK-MultiTool aracılığı ile decomplie edelim. Setup.bat’ı çalıştırıp Setup Directories seçelim. Daha sonrasında Crackme03.apk dosyasını “place-apk-here-for-modding” içerisine kopyalayalım.

Bu işlem sonrasında Script.bat’ı çalıştaralım ve Set current project(24) seçelim.
Karşımıza çıkan bu ekrandan hangi apk üzerinde çalışacağımızı seçelim(1). Son işlem olarak Decomplie apk(9)’yı seçelim.


APK-Multi-Tool\projects\Crackme03.apk\smali klasöründeki smali dosyalarınının hepsini Notpad++ ile açalım. Yukarıda aldığımız uyarıları “.smali” uzantılı dosyalarının içerisinde bulmaya çalışalım. Aldığımız uyarıları “HelloAndroid$2.smali” dosyasında bulduk. Smali kodumuzu incelemeden bir kaç önemli fonksiyonuna kısaca göz atalım.

move-object/from16 vAA, vBBBB (bir nesnenin yazmacını diğerine taşıma işlemi)
A:hedef yazmaç(register)
B:kaynak yazmaç


const vAA, #+BBBBBBBB (Sabit (#+BBBBBBBB) sayı değerli bir yazmaçın özel(vAA) bir yazmaça değerinin taşınması işlemi)
A:hedef yazmaç
B:kaynak 32-bitlik tanımlı sabit tamsayı değeri(integer)

invoke-virtual/range  { vA .. vX }, Lclass;->method()R
vA-vX: metoda geçirilmekte olan argümanların aralığı
class: Yöntemi içeren sınıfın adı
method: Çağırma yönteminin adı
R : Dödürülen değerin türü

Daha detaylı bilgiye https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html adresinden ulaşabilirsiniz.

Şimdi “HelloAndroid$2.smali” dosyasının önemli noktalarına bakalım.

//İlk metin kutusunun(Enter Name) içeriğinin okunması
const v23, 0x7f050004
//0x7f050004 bu yazmaçın karşılığı public.xml içerisinde txt_name olarak geçmekte
invoke-virtual/range {v22 .. v23}, Lcom/example/helloandroid/HelloAndroid;->findViewById(I)Landroid/view/View;
move-result-object v9


//İkinci metin kutusunun (Enter Serial) içeriğinin okunması işlemi.
const v23, 0x7f050006
invoke-virtual/range {v22 .. v23}, Lcom/example/helloandroid/HelloAndroid;->findViewById(I)Landroid/view/View;
move-result-object v21


//İsim (Name) uzunluğunun kontrolünün yapılması. (Minimum 4 karakterli olmalı)
const/16 v22, 0x4
move v0, v11
move/from16 v1, v22
if-ge v0, v1, :cond_0


//Min 4 chars uyarısının verildiği kısım
const-string v23, "Min 4 chars"
const/16 v24, 0x1
.line 86
invoke-static/range {v22 .. v24}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v13
.line 88
.local v13, notificacionToast:Landroid/widget/Toast;
invoke-virtual {v13}, Landroid/widget/Toast;->show()V


//karakter dizisinin integer'e dönüştürülmesi    
invoke-virtual {v10, v5}, Ljava/lang/String;->charAt(I)C
move-result v3

//Asciiye dönüştürlen ismin (Name) ilk 5 rakamanın seçilir
const/16 v22, 0x0
const/16 v23, 0x5
move-object v0, v12
move/from16 v1, v22
move/from16 v2, v23
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->i(II)Ljava/lang/String;


//Birici metin kutusuna girilen isimin ilk beş rakamı ile  0x6b016’nın xor edilme işlemi
invoke-static {v12}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v22
const v23, 0x6b016
//v22 değeri ile v23 değeri xor işlemine tabi tutuluyor.
xor-int v22, v22, v23


//Telefonun ime numarasına erişimin sağlanması
.local v8, mTelephonyMgr:Landroid/telephony/TelephonyManager;
invoke-virtual {v8}, Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String
move-result-object v6
.line 102
.local v6, imei2:Ljava/lang/String;


//Bu kısımda da sim kart seri numarasına erişim sağlanmakta
invoke-virtual {v8}, Landroid/telephony/TelephonyManager;->getSimSerialNumber()Ljava/lang/String;
move-result-object v16
.line 103
.local v16, simsn:Ljava/lang/String;
const-wide/16 v17, 0x0


//İme numarasının ve sim seri numarasının ilk altı rakamı alınıyor
.line 104
.local v17, temp01:J
const/16 v22, 0x0
const/16 v23, 0x6
move-object v0, v6
move/from16 v1, v22
move/from16 v2, v23
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;
move-result-object v19

.line 105
.local v19, temp02:Ljava/lang/String;
const/16 v22, 0x0
const/16 v23, 0x6
move-object/from16 v0, v16
move/from16 v1, v22
move/from16 v2, v23
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;
move-result-object v20


//sim seri numarası ve ime numarasının xor işlemine tabi tutulması-Serial’ın ikinci parçasının oluşturulması
.local v20, temp03:Ljava/lang/String;<
invoke-static/range {v19 .. v19}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v22
invoke-static/range {v20 .. v20}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v23
xor-int v22, v22, v23


//Serialin Serial1-Serial2-Serial3 olarak dizi foramatına çevrilmesi
new-instance v22, Ljava/lang/StringBuilder;
invoke-static {v12}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
move-result-object v23
invoke-direct/range {v22 .. v23}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
const-string v23, "-"
invoke-virtual/range {v22 .. v23}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22
invoke-static/range {v17 .. v18}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;
move-result-object v23
invoke-virtual/range {v22 .. v23}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22
const-string v23, "-"
//Serial’ın  üçüncü kısmı oluştuluruyor
invoke-virtual/range {v22 .. v23}, Ljava/lang/StringBuilder;-
>append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22
move-object/from16 v0, v22
move-object/from16 v1, v19
invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v22


//Bu kısımda girilen serial ile programın hesapladığı serial kontrolü sağlanmakta
invoke-virtual {v14, v15}, Ljava/lang/String;->equals(Ljava/lang/Object;)

Serial 1. kısmın oluşturulması:
Enter name kısmına girilen ismin Ascii değeri :btrisk - Ascii-> 98116114105115107
İsmin ilk 5 karakteri ile 0x6B016’nın (438294) xor işleminin sonucu ->511826
Serial 2. kısmın oluşturulması:
İme numarası ve Sim seri numarasının xor işlemi sonucu
HW ID1 (İme): 425204 (ilk 6 karakter)            
HW ID2 (Sim Serial No ): 890126 (ilk 6 karakter)
İme numarası ve Sim seri numarasının xor işlemi sonucu->780794

Serial 3. kısmının oluşturulması:
HW ID1 (İme): 425204 (ilk 6 karakter)


Böylece reverse işlememimiz tamamlanmış oldu. Ayrıca reverse işlemini aşağıdaki gibi de yapabilirdik.

o      Apk dosyamızı herhangi bir arşiv programı (Winrar,Winzip v.b.) ile açalım ve içerisinden classes.dex        uzantılı dosyayı bir klasöre kopyalayalım.
o      Konunun başında verdiğimiz linklerden Dex2jar ve Java Decompiler programlarını indirelim ve arşivden  çıkarılm.
o      Dex2jar klasörünün içerisine classes.dex dosyasını yapıştıralım.
o      Dex2jar klasörü içerisinde komut satırını açıp “ dex2jar.bat classes.dex” yazıp enter diyelim


o      Oluşan classes_dex2jar.jar dosyasını Java Decompiler (jd-gui.exe) ile açalım.




Uygulamamızı daha çok alışık olduğumuz Java dilinde kaynak kodunu görebildik. Yine burada da atanan register değerlerini R.class içerisinde karşılıklarını görebiliriz.



Kaynak içerisinde serialin nasıl oluşturulduğu aşağıdaki kısımında kolayca anlayabiliyoruz.


Neden Smali?


Android .apk ve .jar dosyaları içerisinde belirli işlevleri yerine getirmek üzere Java sınıfları yer alır.  Smali ile Java sınıfları düzenlenebilir ve değiştirebilir formata gelir. Jar formatında ise kaynak kodu rahatlıkla okuyabiliriz ama üzerinde değişikliker yapıp tekrardan kullanılır hale getirilemesi zor bir süreçtir. Bu sebeplerden dolayı değişiklikler için ara kod düzeyi diye tabir etiğimiz Smali kodu üzerinden değişikler yapabilir ve programın işleyişine müdahale edebiliriz.

Dex<  > Smali <  Jar