您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Android中怎么進行靜態分析”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Android中怎么進行靜態分析”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
Android逆向就是反編譯的過程,因為看不懂Android正向編譯后的結果所以CTF中靜態分析的前提是將出現文件反編譯到我們看得懂一層源碼,進行靜態分析。
0X01 基礎說明
Android應用的邏輯代碼是由Java進行開發,所以是第一層就是java代碼
Java虛擬機JVM運行的是java文件編譯過后的class文件
Android虛擬機Dalvik并不是執行Java虛擬機JVM編譯后生成的class文件,而是執行再重新整合打包后生成的dex文件編譯之后的smali文件
APK:是編譯完成后的Android應用程序安裝包
dex文件:是class文件的打包文件
smali文件:是Dalvik字節碼文件
class文件:是JVM字節碼文件
0X02 工具使用
在CTF中Android題目不一定給你完整編譯完成后的APK,可能是編譯過程中任意文件類型,下面斗哥分以下文件類型利用工具來得到斗哥看得懂的java源碼
類型一:class文件
這種情況比較簡單,推薦工具jd-gui
直接將class文件拉進去就可以看到java源碼。
類型二:APK程序
Android工程編譯完成會得到我們想要的APK安裝包,APK文件其實是一個壓縮包。
修改后綴名為zip后解壓,解壓后的文件如下圖所示:
META-INF文件夾:
存放apk簽名信息,用來保證apk包的完整性和系統的安全。
res文件夾:
存放資源文件,包括icon,xml文件。
AndroidManifest.xml文件:
應用程序配置文件,每個應用都必須定義和包含的,它描述了應用的名字、版本、權限、引用的庫文件等信息。
classes.dex文件:
可以直接在Dalvik虛擬機上加載運行的文件,由java文件經過IDE編譯生成。
resources.arsc文件>
二進制資源文件,包括字符串等。
反編譯APK推薦工具ApkIDE、JEB
1. JEB使用:
JEB直接導入APK,反編譯完成看到smali文件。
很多Android逆向工具就反編譯到smali文件這步。
JEB選中smali文件中按Q,就可以看到java文件。
優點:從smali文件反編譯成的java文件代碼結構清晰。
缺點:無法修改。
2. ApkIDE使用:
項目->打開Apk
等待反編譯完成。
看到smali文件。
選擇要java源碼的smali文件,點擊下圖按鈕,打開Java源碼。
ApkIDE關聯了jd-gui,點擊后將跳轉到jd-gui。
ApkIDE是將APK反編譯到class再用jd-gui拿到Java源碼。
在ApkIDE的ApkIDE_v3.3\ApkIDE\Worksrc的項目目錄下可以看到反編譯后的class文件。
優點:功能強大,可以修改反編譯出來的smali文件,重新編譯生成APK。
缺點:編譯成后的java代碼不夠清晰。
3.反編譯區別
Smali文件是由Smali語法編寫,Smali語法寬松式的語法
所以反編譯過程不同,工具不同,java源碼肯定不同
下面是同一個APK用上面兩個工具逆向的結果:
斗哥作為一名Java開發的愛好者喜歡JEB的逆向結果,看著比較舒服。
類型三:dex文件
推薦工具dex2.jar
classes.dex文件,這個是Android源碼編譯過的字節碼包
嘗試使用dex2.jar工具拿到java源碼命令如下
.\d2j-dex2jar.bat C:\Users\lin\Desktop\classes.dex
jar文件可以理解為classes文件的壓縮包,java虛擬機可以直接運行
用Jd-gui打開classes-dex2jar.jar就可以看到java源碼
類型四:smali文件
當只有一個單獨的smali文件時就無法用上述的工具直接進行反編譯
斗哥想到ApkIDE可以對一個APK進行反編譯到smali文件,對smali文件進行增刪改查的操作
于是用ApkIDE打開任意一個完整的APK然后添加smali文件(APK可以用自己開發的)
將smali文件添加ApkIDE項目中。
重新編譯生成APK。
編譯成功后將在原APK目錄生成一個APK。
再用JEB等工具打開就能看到Ezreal.smali文件。
其他工具:
編輯器:notepad++、Sublime等
Android模擬器:夜神模擬器等
0X04 例題分析
將應用安裝到模擬器查看界面是否有提示。
在文本框輸入字符點擊按鈕提示錯誤,猜想是否用來判斷正確的flag。
使用JEB工具編譯成java文件,Android文件下是sdk文件,我們要分析是com包下的源碼文件。
代碼量不多就三個類,先從程序入口MainActivity分析,找到關鍵代碼塊。
這句if就是判斷flag是否正確。
搜索類查看哪里調用了此方法。
分析得到arg12就是界面要輸入的參數,這時我們知道了v5的值就是我們要的flag。
onCreate函數調用了checkSN方法并傳入兩個參數為:
MainActivity.this.edit_userName.trim()
MainActivity.this.edit_sn.getText().toString().trim()
//OnCreate是Android中的一個特別的函數,用來“表示一個窗口正在生成”。
//其不產生窗口,只是在窗口顯示前設置窗口的屬性如風格、位置顏色等。
public void onCreate(Bundle arg3) {
super.onCreate(arg3);
this.setContentView(0x7F040019);
this.setTitle(0x7F06001D);
this.edit_userName = "Tenshine";
this.edit_sn = this.findViewById(0x7F0C0051);
this.btn_register = this.findViewById(0x7F0C0052);
this.btn_register.setOnClickListener(new View$OnClickListener() {
public void onClick(View arg5) {
if(!MainActivity.this.checkSN(MainActivity.this.edit_userName.trim(), MainActivity.this.edit_sn.getText().toString().trim())) {
Toast.makeText(MainActivity.this, 0x7F06001E, 0).show();
}
else {
Toast.makeText(MainActivity.this, 0x7F06001B, 0).show();
MainActivity.this.btn_register.setEnabled(false);
MainActivity.this.setTitle(0x7F060019);
}
}
});
}
分析v5的值,v5是由v3和v4生成的,v4是一個int并直接賦值為0用于循環就可以直接使用
而v3則是toHexString方法的返回值,并要傳入,v1是v1.update(arg11.getBytes());生成
arg11就是傳入的參數"Tenshine"
private boolean checkSN(String arg11, String arg12) {
boolean v7 = false;
if(arg11 != null) {
try {
if(arg11.length() == 0) {
return v7;
}
if(arg12 == null) {
return v7;
}
if(arg12.length() != 22) {
return v7;
}
MessageDigest v1 = MessageDigest.getInstance("MD5");
v1.reset();
v1.update(arg11.getBytes());
String v3 = MainActivity.toHexString(v1.digest(), "");
StringBuilder v5 = new StringBuilder();
int v4;
for(v4 = 0; v4 < v3.length(); v4 += 2) {
v5.append(v3.charAt(v4));
}
if(!"flag{" + v5.toString() + "}".equalsIgnoreCase(arg12)) {
return v7;
}
}
catch(NoSuchAlgorithmException v2) {
goto label_40;
}
v7 = true;
}
return v7;
label_40:
v2.printStackTrace();
return v7;
}
將上面的分析結果,取出生成v5的關系代碼
都是純java代碼,不需要Android的包引入,只需引入java的依賴包。
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Code {
static String toHexString(byte[] arg8, String arg9) {
StringBuilder v3 = new StringBuilder();
byte[] v0 = arg8;
int v5 = v0.length;
int v4;
for(v4 = 0; v4 < v5; ++v4) {
String v2 = Integer.toHexString(v0[v4] & 255);
if(v2.length() == 1) {
v3.append('0');
}
v3.append(v2).append(arg9);
}
return v3.toString();
}
public static void main(String[] args)throws NoSuchAlgorithmException{
MessageDigest v1 = MessageDigest.getInstance("MD5");
v1.reset();
v1.update("Tenshine".getBytes());
String v3 = Code.toHexString(v1.digest(), "");
StringBuilder v5 = new StringBuilder();
int v4;
for(v4 = 0; v4 < v3.length(); v4 += 2) {
v5.append(v3.charAt(v4));
}
System.out.println("flag{" + v5.toString() + "}");
}
}
用IDEA編輯運行,拿到flag。
讀到這里,這篇“Android中怎么進行靜態分析”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。