Android Studio調試smali代碼
標籤: APK逆向分析
1. 前言
經過一段時間的學習,現在總結下針對APK逆向的一些基本調試技術,以阿里移動安全比賽題目爲例
2. 使用Android Studio調試smali代碼
步驟一:下載安全Android Stuio,下載地址http://www.android-studio.org/
步驟二:下載插件smalidea
地址: https://bitbucket.org/JesusFreke/smali/downloads
步驟三:下載完成後,打開Android studio的Settings——>Plugins,選擇 Install plugin from disk
步驟四:反編譯apk,修改AndroidManifest.xml文件的屬性android:debuggable=”true”
java -jar apktool.jar d -d ./apk/AliCrackme_1.apk -o out
修改完成之後,回編譯apk
java -jar apktool.jar b -d out -o debug.apk
回編之後,進行簽名
java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 debug.apk debug.sig.apk
步驟五:安裝簽名之後的應用
adb install debug.sig.apk
使用backsmali得到apk的smali代碼
java -jar backsmali.jar debug.sig.apk
將得到的smali代碼導入Android Studio中
步驟六:配置遠程調試的選項,選擇Run–>Edit Configurations:
增加一個Remote調試的調試選項,端口選擇:8700
步驟七:下好斷點,針對本APK我們在button的onclik函數出下斷點(點擊鼠標右鍵)
步驟八:以調試狀態啓動app
adb shell am start -D -n com.example.simpleencryption/.MainActivity
下好斷點之後Run->Debug
執行完
invoke-virtual {v6}, Lcom/example/simpleencryption/MainActivity;->getTableFromPic()Ljava/lang/String;
得到圖6內容
通過分析我們大體知道個整個函數的執行邏輯
- 通過MainActivity中的getTableFromPic方法,獲取一個類似密碼錶的東西
- 通過MainActivity中的getPwdFromPic方法,獲取正確的密碼”義弓麼丸廣之”
- 獲取我們輸入內容的utf-8的字節碼,然後調用MainActivity的access$0方法,獲取加密之後的內容
- 再看MainActivity的access$0方法的實現
裏面又調用了bytesToAliSmsCode,傳了兩個參數,一個是我們輸入的qwer的bytes數組,一個是獲取的密碼錶
具體的邏輯如下
.method private static bytesToAliSmsCode(Ljava/lang/String;[B)Ljava/lang/String;
.registers 5
.param p0, "table" # Ljava/lang/String;
.param p1, "data" # [B
.prologue
.line 144
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
.line 145
.local v1, "sb":Ljava/lang/StringBuilder; //創建一個StringBuilder的變量sb
const/4 v0, 0x0
.local v0, "i":I // 定義一個int變量i = 0
:goto_6
array-length v2, p1
if-lt v0, v2, :cond_e // 比較i和data數組的長度,如果小於,跳到cond_e
.line 148
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v2
return-object v2
.line 146
:cond_e
aget-byte v2, p1, v0 // 取出data[i]
and-int/lit16 v2, v2, 0xff
invoke-virtual {p0, v2}, Ljava/lang/String;->charAt(I)C // 獲取data[i]在table數組的字符
move-result v2
// 調用sb的append函數進行拼接
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(C)Ljava/lang/StringBuilder;
.line 145
add-int/lit8 v0, v0, 0x1
goto :goto_6
.end method
整體邏輯就是一個循環,將輸入字符轉化爲utf-8格式的bye數組,然後取出data[i]table表中所對應的字符,然後拼接返回
5. 返回字符串與正確密碼”義弓麼丸廣之”比較
invoke-virtual {v4, v6}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
此時我們輸入的qwer加密後與”義弓麼丸廣之”
肯定不相等,所以這裏我們可以想辦法是的輸入的字符串加密等於”義弓麼丸廣之”
怎麼辦呢?
我們可以將bytesToAliSmsCode進行反向實現,
public static void main(String args[]){
String table = "一乙二十丁廠七卜人入八九幾兒了力乃刀又三於幹虧士工土才寸下大丈與萬上小口巾山千乞川億個勺久凡及夕丸麼廣亡門義之屍弓己已子衛也女飛刃習叉馬鄉豐王井開夫天無元專雲扎藝木五支廳不太犬區歷尤友匹車巨牙屯比互切瓦止少日中岡貝內水見午牛手毛氣升長仁什片僕化仇幣仍僅斤爪反介父從今兇分乏公倉月氏勿欠風丹勻烏鳳勾文六方火爲鬥憶訂計戶認心尺引醜巴孔隊辦以允予勸雙書幻玉刊示末未擊打巧正撲扒功扔去甘世古節本術可丙左厲右石布龍平滅軋東卡北佔業舊帥歸且旦目葉甲申叮電號田由史只央兄叼叫另叨嘆四生失禾丘付仗代仙們儀白仔他斥瓜乎叢令用甩印樂";
String dataString = "義弓麼丸廣之";
String passwd = "";
for(int i = 0 ; i < dataString.length(); i++){
passwd += (char)table.indexOf(dataString.charAt(i));
}
System.out.println("passwd = " + passwd);
}
運行出的結果爲passwd = 581026就是我們輸入框裏面要輸入的字符串