Xposed模組開發
剛安卓逆向入門,認識到java hook的實用性後決定動手開發xp模組,不詳細介紹原理,大概百度一下會更有收穫,雖然關於模組開發的文章也不少,但是在自己動手開發時仍遇到一些問題,事無鉅細,決定寫一篇部落格記錄下來。
今天Xposed安卓7版本正式釋出,機友們有福了。
開發環境
1 android studio
2 android 5.0 三星手機 J7
3 Xp框架
開發步驟
1 進行java hook前肯定要清楚目標應用的java層邏輯;這裡我們自己動手開發一個簡單的應用。
2 準備依賴包
3 模組實現
4 設定模組入口點
第一步 理清目標應用的java邏輯(自己動手開發應用替代)
這裡我們簡單開發一個應用,只有一個介面,只有一個Button,點選Button後Toast顯示Hello world 字串
貼上程式碼,大概需要懂一點開發。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnShow = (Button) findViewById(R.id.show); btnShow.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String temp = getTestString(); Toast.makeText(MainActivity.this,temp,Toast.LENGTH_SHORT).show(); } }); }
這裡看到我們的所要顯示的字串從getTestString()中獲得
private String getTestString(){
return "hello world";
}
我們通過hook後希望點選Button後顯示“Hello android”,顯然getTestString()就是我們的目標,我們貼上完整
package com.example.administrator.javahooktest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button btnShow;
private String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnShow = (Button) findViewById(R.id.show);
btnShow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String temp = getTestString();
Toast.makeText(MainActivity.this,temp,Toast.LENGTH_SHORT).show();
}
});
}
private String getTestString(){
return "hello world";
}
}
可得我們的目標是com.example.administrator.javahooktest包下MainActivity來下的getTestString()函式。
第二步 準備xp依賴包
下載api-82.jar api-82-sources.jar
第三步 模組實現
1 講依賴包拷貝到libs目錄下
2 修改 build.gradle
修改 dependencies
dependencies {
provided 'de.robv.android.xposed:api:82'
provided 'de.robv.android.xposed:api:82:sources'
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
}
原為
3 修改manifeses檔案
在application子標籤下新增 meta-data
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="xpose模組測試" />
<meta-data
android:name="xposedminversion"
android:value="54" />
第一條標識是否為xp模組,第二條是說明,第三條設定最低版本
4 進行工具類開發,注意不要在Activity中實現,會出異常,原因暫時不知。
這裡新建XPmodule類實現IXposedHookLoadPackage介面,並實現其handleLoadPackage(...)方法
通過第一步我們已知我們的目標是com.example.administrator.javahooktest包下MainActivity來下的getTestString()函式。
這裡首先匹配我們的目標包名 com.example.administrator.javahooktest 再通過classLoader載入我們的目標類,傳入的引數是我們目標類MainActivity的完整路徑。
最後通過XposedHelpsers 找到並hook我們目標函式,這裡會讓我們實現兩個方法
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
這個函式可在找到目標函式後 執行目標函式前執行
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
param.setResult("Hello Android");
}
這個函式可在正常執行目標函式後在return前執行,我們在這個函式中修改目標函式的返回結果,通過param.setResult(...),當然事前我們已經知道目標函式返回的是一個字串。
貼上完整程式碼
package com.example.administrator.myxposedmodule;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
/**
*
*/
public class XPmodule implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
if(loadPackageParam.packageName.equals("com.example.administrator.javahooktest")){
Class testClass = loadPackageParam.classLoader.loadClass("com.example.administrator.javahooktest.MainActivity");
XposedHelpers.findAndHookMethod(testClass, "getTestString", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
param.setResult("Hello Android");
}
});
}
}
}
到這裡,可能遇到一個問題,我們知道函式是可進行過載的,假如我們的目標函式有引數呢,並且存在不同形式引數的過載函式怎麼辦???
這裡我們看到我們是通過XposedHelpers.findAndHookMethod(...)找到目標函式,跟進
這裡清楚看到第三項是一個可變引數,Object... parameterTypesAndCallback根據名稱以後類內程式碼,我們猜到這個可變引數的最後一項是hook的回撥函式,而這個引數的其他項則應該是我們目標函式所傳入引數決定的。事實上確實如此,在這個可變引數的中我們需要傳入目標函式引數的Class型別。例 假如函式getTestString中有一個String引數,即getTestString(String s),我們就應該在這個可變引數中傳入String.class,以此類推實際上需要傳入所有引數的class。
5 建立xposed_init,寫入我們工具類的入口
首先建立assets資料夾
再建立xposed_init檔案
在xposed_init檔案中新增我們的工具類入口的完整路徑 包名 + 類名
至此,我們的開發完成,最後需要注意的是要通過簽名打包後的apk檔案安裝。
剛android逆向入門,決定每週一更,歡迎關注,同時有什麼問題可加q1254553524