1. 程式人生 > >Android逆向-java程式碼基礎(1)

Android逆向-java程式碼基礎(1)

0x00 簡述

好久沒有動過java程式碼的樣子,都是在Android開發中使用一下,今天假裝自己是一個初學者來溫習一下吧。當然現在的行當是逆向,那麼逆向是不能少的。之前學習都是使用Eclipse的,現在使用javac進行編譯,找點新鮮感,有所進步和學習還是很好的。

連結

0x01 本次內容

1.編寫第一個java程式碼

public class first
{
    public static void main(String[] args)
    {
            System.out.println("I Love Zhuzhu!");

    }
}

程式碼很簡單,就是輸出一串字元,我就不輸出HelloWorld了,想輸出什麼隨你開心。

2.使用javac進行編譯。

普及一下什麼是javac:
簡單的說javac 是java語言程式設計編譯器。如果想要深入瞭解請:自行百度。
編譯

javac first.java

3.使用java命令執行

java first

這裡寫圖片描述
這裡我們成功的輸出了我們想要輸出的元素。

4.結束語

以上就是使用javac進行編譯java程式碼的簡單過程,恩。非常簡單,但是又必須得知道。以為這裡就結束了?恩,就是結束了。

0x02 附加內容(java虛擬機器)

1.java虛擬機器

(1)首先明確

.class並不是直接執行在系統程序上的,而是通過一個java虛擬機器來進行託管。
這裡寫圖片描述

(2)類裝載器

類載入指將類的位元組碼檔案(.class)中的二進位制資料讀入記憶體,將其放在執行時資料區的方法區內,然後在堆上建立java.lang.Class物件,封裝類在方法區內的資料結構。

(3)理解

先把.class檔案給JVM,JVM進行執行,如果當該程式結束的時候,JVM也緊跟著一起結束,

(4)結束語

詳細的以後會講到,現在只是一個簡單的瞭解

0x03 附加內容(class檔案)

1.簡要說明

class檔案是一種8位位元組的二進位制流檔案,相鄰的項之間沒有間隙,class檔案中的資訊是一項一項排列的, 每項資料都有它的固定長度。

2.class檔案的資料項

這裡寫圖片描述

3.class檔案的結構

3.1 魔數【magic】

檔案開頭是4個位元組大小的magic,也就是魔數。
所謂的魔數就是校驗位,JVM通過判斷魔數來判斷是不是.class檔案。一般通過java編譯器編譯過的魔數都是:CA FE BA BE。

這裡寫圖片描述

3.2副版本號【minor_version】

副版本號佔用第5、6兩個位元組,一般都為0。

這裡寫圖片描述

3.3主版本號 【major_version】

主版本號佔用第7,8兩個位元組,1.0的jdk 版本號是45,1.7的就是51,對應的十六進位制就是0x33。
這裡寫圖片描述

3.4 小技巧

有沒有什麼辦法可以直接檢視主版本號和副版本號的嗎,當然有了,我們來使用jdk自帶的javap來進行檢視吧。

javap -v first

這裡寫圖片描述

3.5 常量池計數器(constant_pool_count)

(1)常量池計數器佔兩個位元組,他描述整個class檔案的字面資訊。
(2)常量池是由一組constant_pool結構體陣列組成的,而陣列的大小則由常量池計數器指定。
(3)常量池計數器constant_pool_count 的值 =constant_pool表中的成員數+ 1。constant_pool表的索引值只有在大於 0 且小於constant_pool_count時才會被認為是有效的。

這裡寫圖片描述
這裡我們看出,常量池計數器是00 1D,也就是說常量池的長度就是

3.6 常量池【constant_pool】

常量池,constant_pool是一種表結構,它包含 Class 檔案結構及其子結構中引用的所有字串常量、 類或介面名、欄位名和其它常量、類或介面名、欄位名和其它常量。 常量池中的每一項都具備相同的格式特徵——第一個位元組作為型別標記用於識別該項是哪種型別的常量,稱為 “tag byte” 。

4.結束語

class檔案結構暫時就只介紹到這裡,以後會有章節進行詳細解釋。

0x04 .class 轉換dex

雖說是要複習一下java以及學習java沒有學到的知識點,但是呢,還是要側重一下逆向的嘛。smali是APK逆向之後的常見的東西,程式碼這種東西就是敲的越多,見的越多,它就和你越熟練。所以把java編譯成二進位制位元組碼的class檔案,然後再把class檔案轉化成dex檔案就十分重要了。

1.class轉dex

編譯工具在 Android SDK 的路徑如下./build-tools/19.0.1/dx
這裡我把這個目錄加在了環境變數裡,方便我在任何目錄進行使用。
使用的命令如下:

 dx --dex --output=first.dex first.class

使用後效果:
這裡寫圖片描述

出現了一個錯誤:

PARSE ERROR:
unsupported class file version 52.0
...while parsing first.class
1 error; aborting

這個錯誤的意思就是編譯java的jdk版本過高或者是dx的版本太低。解決方法就是降低jdk版本,或者提高dx的版本。在這裡我採用降低jdk版本的方式。當然我也不會重新去安裝我的jdk。javac自帶功能就好。

使用命令:

javac -source 1.6 -target 1.6 first.java

這裡寫圖片描述
這裡有一個警告,無視他,dex生成成功。

這裡寫圖片描述

2.dex轉smali

這個就非常簡單了,丟在工具裡,一鍵搞定,不得不說圖形化介面真的省事。
這裡寫圖片描述
稍等一下,就拿到了我們想要的smali檔案。
我這裡使用sublime Text檢視。

sublime Text自己是不會帶smali高亮的,需要自己設定關於sublime Text怎樣設定smali語法高亮之前有過總結:https://bbs.ichunqiu.com/thread-31148-1-1.html
關於helloworld程式的smali程式碼分析,之前也有總結,這裡就不再贅述:https://bbs.ichunqiu.com/thread-31104-1-1.html

0x05 結尾