1. 程式人生 > >反編譯與xposed模組開發

反編譯與xposed模組開發

需求描述:008神器生成的資料中,手機型號資料老舊並且android版本低於4.4無法滿足現有需求,需要更新手機型號資料並且擴充套件到更高的android版本。

思路一:反編譯008神器並重新打包

使用androidKiller反編譯008.apk,點選開啟連結

思路二.實現一個修改手機資訊的xposed模組

#.xposed介紹

    xposed框架的作者是rovo89,Xposed框架的原理是修改系統檔案,替換了/system/bin/app_process可執行檔案,在啟動Zygote時載入額外的jar檔案(/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar),並執行一些初始化操作(執行XposedBridge的main方法)。然後我們就可以在這個Zygote上下文中進行某些hook操作。

  • XposedInstaller,這是Xposed的外掛管理和功能控制APP,也就是說Xposed整體管控功能就是由這個APP來完成的,它包括啟用Xposed外掛功能,下載和啟用指定外掛APP,還可以禁用Xposed外掛功能等。
  • Xposed,這個專案屬於Xposed框架,其實它就是單獨搞了一套xposed版的zygote。這個zygote會替換系統原生的zygote。所以,它需要由XposedInstaller在root之後放到/system/bin下。
  • XposedBridge。這個專案也是Xposed框架,它屬於Xposed框架的Java部分,編譯出來是一個XposedBridge.jar包。
  • XposedTools
    。Xposed和XposedBridge編譯依賴於Android原始碼,而且還有一些定製化的東西。所以XposedTools就是用來幫助我們編譯XposedXposedBridge的。

#.關於xposed的使用

1.新增依賴包:匯入XposedBridge.jar包或使用gradle依賴
provided files('libs/XposedBridgeApi-54.jar')

這裡使用provided而不用compile是因為xposed框架中已經包含該jar包,所以只建立編譯時依賴。

2.宣告xposed模組
<!-- 標記app為xposed模組 -->
<meta-data
android
:name="xposedmodule" android:value="true" /> <!--xposed版本 --> <meta-data android:name="xposedminversion" android:value="54" /> <meta-data android:name="xposeddescription" android:value="測試Xposed" />
3.建立hook類
public class XposedUtil implements IXposedHookLoadPackage {
    @Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam mLoadPackageParam) throws Throwable {


    }
}
4.宣告hook入口

建立完我們hook類之後,我們需要將該類載入到XposedInstaller中,也就是我們必須宣告該類的位置,需要在xposed_init中宣告:建立assets資料夾,然後在裡面新建一個檔案,檔名為xposed_init,沒有後綴,然後在裡面寫入我們剛剛建立的類的完整類名

com.dovar.fakermobile.XposedUtil

XposedHelpers.findAndHookMethod()可在目標方法執行之前或之後進行修改,一般用於執行前修改傳參或執行後修改返回值或者對資料進行抓包。

XposedHelpers.findAndHookMethod("android.view.Display", loadPkgParam.classLoader, "getSize", Point.class, 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);
Point mPoint = (Point) param.args[0];
mPoint.y = SharedPref.getintXValue("height");
mPoint.x = SharedPref.getintXValue("width");
XposedBridge.log("getSize");
}
});

另外也可通過XposedHelpers.findAndHookMethod()直接對目標方法進行替換,以此影響程式的執行

new XC_MethodReplacement(){
    @Override
protected Object replaceHookedMethod(MethodHookParam mMethodHookParam) throws Throwable {
        return null;
}
};
針對多種獲取解析度的方式進行hook:
/**
 * Display.getWidth()  Display.getHeight()
 * 針對這種方式的獲取解析度
 */
XposedHelpers.findAndHookMethod("android.view.Display", loadPkgParam.classLoader, "getWidth", new XC_MethodHook() {

    @Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
param.setResult(SharedPref.getintXValue("width"));
XposedBridge.log("getWidth");
}
});
/**
 *  Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);method.invoke(display, dm);dpi = dm.heightPixels;
 *  針對這種方式的獲取解析度
 */
XposedHelpers.findAndHookMethod("android.view.Display", loadPkgParam.classLoader, "getRealMetrics", DisplayMetrics.class, new XC_MethodHook(XCallback.PRIORITY_LOWEST) {

    @Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);DisplayMetrics metrics = (DisplayMetrics) param.args[0];metrics.widthPixels = SharedPref.getintXValue("width");
metrics.heightPixels = SharedPref.getintXValue("height");
XposedBridge.log("getRealMetrics_dpi");
}

});
/**
 *  Display display = wm.getDefaultDisplay();Point size = new Point();display.getSize(size);
 *  針對這種方式的獲取解析度
 */
XposedHelpers.findAndHookMethod("android.view.Display", loadPkgParam.classLoader, "getSize", Point.class, new XC_MethodHook() {

    @Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
Point mPoint = (Point) param.args[0];
mPoint.y = SharedPref.getintXValue("height");
mPoint.x = SharedPref.getintXValue("width");
XposedBridge.log("getSize");
}
});
/**
 * DisplayMetrics dm = new DisplayMetrics(); display.getMetrics(dm); height = dm.heightPixels;
 * 針對這種方式的獲取解析度
 */
XposedHelpers.findAndHookMethod("android.view.Display", loadPkgParam.classLoader, "getMetrics", DisplayMetrics.class, new XC_MethodHook() {

    @Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        super.afterHookedMethod(param);
DisplayMetrics metrics = (DisplayMetrics) param.args[0];
metrics.widthPixels = SharedPref.getintXValue("width");
metrics.heightPixels = SharedPref.getintXValue("height");
XposedBridge.log("getMetrics");
}
});

修改buildProp檔案中的系統值

public void BuildProp(XC_LoadPackage.LoadPackageParam loadPkgParam) {
    //systemProperties hook
XposedHelpers.findAndHookMethod("android.os.SystemProperties", loadPkgParam.classLoader, "get", String.class, String.class, new XC_MethodHook() {
        @Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            super.beforeHookedMethod(param);
String methodName = param.method.getName();
            if (methodName.startsWith("get")) {
                XposedHelpers.findField(Build.class, "BOARD").set(null, SharedPref.getXValue("board"));
XposedHelpers.setStaticObjectField(Build.class, "BRAND", SharedPref.getXValue("brand"));
XposedHelpers.findField(Build.class, "CPU_ABI").set(null, SharedPref.getXValue("ABI"));
XposedHelpers.findField(Build.class, "CPU_ABI2").set(null, SharedPref.getXValue("ABI2"));
XposedHelpers.findField(Build.class, "DEVICE").set(null, SharedPref.getXValue("device"));
XposedHelpers.findField(Build.class, "DISPLAY").set(null, SharedPref.getXValue("display"));
XposedHelpers.findField(Build.class, "FINGERPRINT").set(null, SharedPref.getXValue("fingerprint"));
XposedHelpers.findField(Build.class, "HARDWARE").set(null, SharedPref.getXValue("NAME"));
XposedHelpers.findField(Build.class, "ID").set(null, SharedPref.getXValue("ID"));
XposedHelpers.findField(Build.class, "MANUFACTURER").set(null, SharedPref.getXValue("Manufacture"));
XposedHelpers.setStaticObjectField(Build.class, "MODEL", SharedPref.getXValue("model"));
XposedHelpers.findField(Build.class, "PRODUCT").set(null, SharedPref.getXValue("product"));
XposedHelpers.findField(Build.class, "BOOTLOADER").set(null, SharedPref.getXValue("booltloader")); //主機板載入程式
XposedHelpers.findField(Build.class, "HOST").set(null, SharedPref.getXValue("host"));  // 裝置主機地址
XposedHelpers.findField(Build.class, "TAGS").set(null, SharedPref.getXValue("build_tags"));  //描述build的標籤
XposedHelpers.findField(Build.class, "TYPE").set(null, SharedPref.getXValue("shenbei_type")); //裝置版本型別
XposedHelpers.findField(Build.VERSION.class, "INCREMENTAL").set(null, SharedPref.getXValue("incrementalincremental")); //原始碼控制版本號
XposedHelpers.findField(android.os.Build.VERSION.class, "RELEASE").set(null, SharedPref.getXValue("AndroidVer"));
XposedHelpers.findField(android.os.Build.VERSION.class, "SDK").set(null, SharedPref.getXValue("API"));
XposedHelpers.findField(android.os.Build.VERSION.class, "CODENAME").set(null, "REL"); //寫死就行 這個值為固定
}
        }
    });

#.在非root環境下執行xposed模組點選開啟連結

#.github上的一個有趣的xposed模組點選開啟連結