1. 程式人生 > >Xposed模組開發

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