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