目錄
-
-
-
- 一、目标app
- 二、使用jadx反編譯app分析關鍵代碼
-
- 1、分析需要hook的頁面
- 2、定位主界面加載類
- 3、使用jadx分析定位到的加載類
- 三、hook校驗函數
-
-
一、目标app
對該app進行hook,實作用任意密碼繞過認證。
二、使用jadx反編譯app分析關鍵代碼
注意:前提是app沒有進行加強,如果有加強需要先進行脫殼
1、分析需要hook的頁面
- app一打開就進入上圖的頁面(主界面)
2、定位主界面加載類
- 使用apktool工具反編譯app
- 檢視AndroidManifest.xml定位主界面類
注意:
android.intent.action.MAIN
标記了啟動Application時先啟動哪個Activity,也就是先加載哪個頁面。若有多個android.intent.action.MAIN,則先啟動mainfest裡面第一個出現的。
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yaotong.crackme">
<application android:allowBackup="true" android:icon="@drawable/creakme2_logo" android:label="@string/app_name">
<activity android:label="@string/app_name" android:name="com.yaotong.crackme.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="com.yaotong.crackme.ResultActivity"/>
</application>
</manifest>·
3、使用jadx分析定位到的加載類
搜尋類名
分析app是如何進行驗證的:在我們輸入密碼後點選button按鈕才進行的密碼校驗(程式擷取我們輸入的密碼和本地的密碼進行比對)
類中的方法拓展:
onCreate()函數是在activity初始化的時候調用的,通常情況下,我們需要在onCreate()中調用setContentView(int)函數填充螢幕的UI,一般通過findViewById(int)傳回xml中定義的視圖或元件的ID。子類在重寫onCreate()方法的時候必須調用父類的onCreate()方法,即super.onCreate(),否則會抛出異常。
一個activity啟動調用的第一個函數就是onCreate,它主要做這個activity啟動時一些必要的初始化工作,這個函數調用完後,這個activity并不是說就已經啟動了,或者是跳到前台了。而是還需要其他的大量工作,我們知道:onCreate之後還有onRestart()和onStart()等,實際上onStart()調用完畢了這個activity還沒有完全啟動,也隻是前台可見,直到
onResume() 調用後這個onCreate才算終于啟動
關鍵代碼:
public void onClick(View v) // onClick翻譯中文是點選
{
if(MainActivity.this.securityCheck(MainActivity.this.inputCode.getText().toString()))
{
MainActivity.this.startActivity(new Intent(MainActivity.this, ResultActivity.class));
return;
}
Toast.makeText(MainActivity.this.getApplicationContext(), "驗證碼校驗失敗", 0).show();
}
代碼解讀1:
if(MainActivity.this.securityCheck(MainActivity.this.inputCode.getText().toString())) // 判斷括号内是否為true
{
MainActivity.this.startActivity(new Intent(MainActivity.this, ResultActivity.class)); // 為true執行該代碼塊的邏輯最後return
return;
}
Toast.makeText(MainActivity.this.getApplicationContext(), "驗證碼校驗失敗", 0).show(); // 否則執行該邏輯,"驗證碼校驗失敗"
也就說明了
MainActivity.this.securityCheck(MainActivity.this.inputCode.getText().toString())
的傳回值決定了密碼驗證成功或失敗。
代碼解讀2:
結合上面代碼來看,我們輸入的密碼最後傳給
securityCheck
方法來進行判斷,最終傳回
true
或
false
。
檢視
securityCheck
方法:
發現該方法被定義在了
libcrackme.so
檔案中然後導入到這個地方的。
securityCheck
方法的具體代碼邏輯在
libcrackme.so
檔案中
結合以上代碼邏輯判斷,我們隻需要在java層hook
securityCheck
方法,讓其傳回值永遠為
true
,就不會執行驗證碼校驗失敗的邏輯代碼。
三、hook校驗函數
hook腳本
import frida #導入frida子產品
import sys #導入sys子產品
jscode = """
Java.perform(function(){
var TestSig = Java.use("com.yaotong.crackme.MainActivity"); // 類的加載路徑
TestSig.securityCheck.implementation = function(str){ // str為securityCheck的參數,原securityCheck需要幾個參數就寫幾個
send("success");
return true;
};
});
"""
def on_message(message,data): #js中執行send函數後要回調的函數
if message["type"] == "send":
print("[*] {0}".format(message["payload"]))
else:
print(message)
process = frida.get_usb_device().attach('com.yaotong.crackme') # app包名
script = process.create_script(jscode) #建立js腳本
script.on('message',on_message) #加載回調函數,也就是js中執行send函數規定要執行的python函數
script.load() #加載腳本
sys.stdin.read()
手機輸入任意密碼
執行結果
成功繞過密碼校驗