关于Android程序bug在线热修复


http://www.apkplug.com/

DL

android-pluginmgr

dexposed准备资料:

原版:

https://github.com/alibaba/dexposed

介绍

Dexposed 是阿里巴巴无线事业部第一个重量级 Andorid 开源软件,基于 ROOT 社区著名开源项目 Xposed 改造剥离了 ROOT 部分,演化为服务于所在应用自身的 AOP 框架。它支撑了阿里大部分 App 的在线分钟级客户端 bugfix 和线上调试能力。

Dexposed 的 AOP 是实现了纯非侵入式,没有任何注释处理器,weaver 或者字节码重写程序。Dexposed 的集成非常简单,就像加载一个 JNI 库一样,只需要在初始化的时候插入一行代码。
osc更多介绍

修改版本:

https://github.com/overlooping/DexposedDemo

修复示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.taobao.patch;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;

import com.taobao.android.dexposed.XC_MethodReplacement;
import com.taobao.android.dexposed.DexposedBridge;

public class DialogPatch implements IPatch {

@Override
public void handlePatch(final PatchParam arg0) throws Throwable {
Class< ?> cls = null;
try {
cls= arg0.context.getClassLoader()
.loadClass("com.taobao.dexposed.MainActivity");
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
DexposedBridge.findAndHookMethod(cls, "showDialog",
new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
Activity mainActivity = (Activity) param.thisObject;
AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
builder.setTitle("Dexposed sample")
.setMessage("The dialog is shown from patch apk!")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}).create().show();
return null;
}
});
}

}

原理分析:

1.通过反射拿到bug类的字节码文件,cls= arg0.context.getClassLoader() .loadClass("com.taobao.dexposed.MainActivity");

2.通过DexposedBridge.findAndHookMethod(cls, "showDialog",new XC_MethodReplacement() {...}
修改class中指定的方法。

3.修改的内容在protected Object replaceHookedMethod(MethodHookParam param)中实现。

4.稍微研究下findAndHookMethod这个方法的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static Unhook findAndHookMethod(Class< ?> clazz, String methodName, Object... parameterTypesAndCallback) {
if(parameterTypesAndCallback.length != 0 && parameterTypesAndCallback[parameterTypesAndCallback.length - 1] instanceof XC_MethodHook) {
XC_MethodHook callback = (XC_MethodHook)parameterTypesAndCallback[parameterTypesAndCallback.length - 1];
Method m = XposedHelpers.findMethodExact(clazz, methodName, parameterTypesAndCallback);
Unhook unhook = hookMethod(m, callback);
if(!(callback instanceof XC_MethodKeepHook) && !(callback instanceof XC_MethodKeepReplacement)) {
ArrayList var6 = allUnhookCallbacks;
synchronized(allUnhookCallbacks) {
allUnhookCallbacks.add(unhook);
}
}

return unhook;
} else {
throw new IllegalArgumentException("no callback defined");
}
}

前两个参数是:Class< ?> clazz, String methodName,后面的参数是不固定的Object… parameterTypesAndCallback,这样子的话,反射的时候就是要调用方法对应的参数类型顺序传到parameterTypesAndCallback,并且最后一个是XC_MethodHook的hook。

热修复需要注意的问题

咱们的项目基本都是混淆过的,混淆过后方法名就变了,变化的映射在mapping.txt中可以查看到。

下面分别介绍下:dump.txt、mapping.txt、seeds.txt和usage.txt四个文件。

dump.txt
描述.apk文件中所有类文件间的内部结构

mapping.txt
列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。

seeds.txt
列出了未被混淆的类和成员

usage.txt
列出了从.apk中删除的代码

文章目录
  1. 1. dexposed准备资料:
    1. 1.1. 原版:
    2. 1.2. 介绍
    3. 1.3. 修改版本:
    4. 1.4. 原理分析:
    5. 1.5. 热修复需要注意的问题