本期,我們將繼續Android逆向動態分析之smali篇。內容包括smali語言介紹與動態調試。
0X01 smali語言簡述
smali語言是Dalvik的反彙編語言因Android虛擬機Dalvik不是執行java虛擬機JVM編譯後生成的class文件,而是執行再重新整合打包後生成的dex文件,dex文件反編譯之後就是smali代碼。
接觸過Android逆向的小夥伴都會遇到smali語言,簡單的逆向過程 [apk -> smali -> java]。有的逆向工具無法將smali語言反編譯成java源碼,只逆向到smali語言這層。或者反編譯成java源碼無法運行(smali寬鬆型語言)。
0X02 smali語言語法
原始數據類型:
//smali----java B----byte C----char D----double F----float I----int J----long S----short V----void Z----boolean [XXX-----array Lxxx/yyy----object
基礎語法:
語法: .field 定義變量 .method 方法 .parameter 方法參數 .prologue 方法開始 .line 12 此方法位於第12行 invoke-super 調用父函數 const/high16 v0, 0x7fo3 把0x7fo3賦值給v0 invoke-direct 調用函數 return-void 函數返回void .end method 函數結束 new-instance 創建實例 iput-object 對象賦值 iget-object 調用對象 invoke-static 調用靜態函數
smali跳轉語句:
"if-eq vA, vB, :cond_**" 如果vA等於vB則跳轉到:cond_** "if-ne vA, vB, :cond_**" 如果vA不等於vB則跳轉到:cond_** "if-lt vA, vB, :cond_**" 如果vA小於vB則跳轉到:cond_** "if-ge vA, vB, :cond_**" 如果vA大於等於vB則跳轉到:cond_** "if-gt vA, vB, :cond_**" 如果vA大於vB則跳轉到:cond_** //le 小於等於 //eqz 等於0 //nez 不等於0 //ltz 小於0 //gez 大於等於0 //gtz 大於0 //lez 小於等於0
例子:
//smali .method public onClick(View)V .registers 12 00000000 const/4 v9, 3 00000002 const/4 v8, 2 00000004 const/4 v7, 0 00000006 const/4 v6, 1 00000008 iget v5, p0, MainActivity->flag:I 0000000C if-ne v5, v6, :12 00000032 const v5, 0x7F0C0050 00000050 move-result-object v3 00000052 check-cast v3, TextView 00000056 iput v7, p0, MainActivity->m:I 0000005A new-instance v0, Random 0000005E invoke-direct Random-><init>()V, v0 00000064 invoke-virtual Random->nextInt(I)I, v0, v9 0000006A move-result v5 0000006C iput v5, p0, MainActivity->n:I 00000070 new-array v1, v9, [String 00000074 const-string v5, "CPU: Paper" 00000078 aput-object v5, v1, v7 0000007C const-string v5, "CPU: Rock" 00000080 aput-object v5, v1, v6 00000084 const-string v5, "CPU: Scissors" 00000088 aput-object v5, v1, v8 0000008C iget v5, p0, MainActivity->n:I 00000090 aget-object v5, v1, v5 00000094 invoke-virtual TextView->setText(CharSequence)V, v3, v5 0000009A iget-object v5, p0, MainActivity->P:Button 0000009E if-ne p1, v5, :B0 :A2 000000A2 const-string v5, "YOU: Paper" 000000A6 invoke-virtual TextView->setText(CharSequence)V, v2, v5 000000AC iput v7, p0, MainActivity->m:I :B0 000000B0 iget-object v5, p0, MainActivity->r:Button 000000B4 if-ne p1, v5, :C6 :B8 000000B8 const-string v5, "YOU: Rock" 000000BC invoke-virtual TextView->setText(CharSequence)V, v2, v5 000000C2 iput v6, p0, MainActivity->m:I :C6 000000C6 iget-object v5, p0, MainActivity->S:Button 000000CA if-ne p1, v5, :DC :CE 000000CE const-string v5, "YOU: Scissors" 000000D2 invoke-virtual TextView->setText(CharSequence)V, v2, v5 000000D8 iput v8, p0, MainActivity->m:I :DC 000000DC iget-object v5, p0, MainActivity->handler:Handler 000000E0 iget-object v6, p0, MainActivity->showMessageTask:Runnable 000000E4 const-wide/16 v8, 1000 000000E8 invoke-virtual Handler->postDelayed(Runnable, J)Z, v5, v6, v8, v9 000000EE goto :10 .end method
//java public void onClick(View arg11) { int v9 = 3; int v8 = 2; if(this.flag != 1) { this.flag = 1; this.findViewById(0x7F0C0052).setText(""); View v2 = this.findViewById(0x7F0C0050); View v3 = this.findViewById(0x7F0C0051); this.m = 0; this.n = new Random().nextInt(v9); String[] v1 = new String[v9]; v1[0] = "CPU: Paper"; v1[1] = "CPU: Rock"; v1[v8] = "CPU: Scissors"; ((TextView)v3).setText(v1[this.n]); if(arg11 == this.P) { ((TextView)v2).setText("YOU: Paper"); this.m = 0; } if(arg11 == this.r) { ((TextView)v2).setText("YOU: Rock"); this.m = 1; } if(arg11 == this.S) { ((TextView)v2).setText("YOU: Scissors"); this.m = v8; } this.handler.postDelayed(this.showMessageTask, 1000); } }
0X03 動態調試smali
IntelliJ IDEA/Android Studio 利用smalidea插件可實現動態調試smali代碼 下載smalidea插件(https://bitbucket.org/JesusFreke/smali/downloads/) 添加smalidea插件[File->Settings->Plugins]
點擊Install plugin from disk添加下載好插件。
加載插件後關閉Android Studio再重新打開。 導入源碼(apk逆向的smali)。
選擇要加載smali源碼。
連續next。
加載後就能看到smali。
將存放smali文件的文件夾設置爲項目源碼。
給項目添加相應的SDK[File->Project Structure]。
運行模擬器並啓動要調試的APP。 開啓模擬器端口轉發。
使用adb shell ps命令查看程序APP的運行的端口與名稱。
添加遠程調試環境。
開啓程序端口調試轉發。 tcp後的端口爲上圖添加的端口,jdwp後的端口爲在apk中運行的APP端口。
爲smali打上斷點,運行Debug[Run->Debug],開始調試。
0X04 小小總結
本期的Android逆向之動態分析smali篇就介紹到這裏啦 !如果你有疑問或是更好的思路,歡迎給鬥哥留言哦~!祝各位週末愉快~!