目录
原理
anfix修复(阿里云使用)
1. 服务器生成修复包 dex文件。app客户端架子dex包
3.找到修复好的class,找到方法method(修复好的),找到method(有bug的)
public class DxManager {
private Context context;
public DxManager(Context context){
this.context=context;
}
public void loadDex(File file) {
File optf = new File(context.getCacheDir(), file.getName());//缓存路径
if (optf.exists()) {
optf.delete();
}
try {
//加载dex
DexFile dexFile = DexFile.loadDex(file.getAbsolutePath(), optf.getAbsolutePath(), Context.MODE_PRIVATE);
//遍历dex里的class
Enumeration<String> entry = dexFile.entries();
while (entry.hasMoreElements()) {
String className = entry.nextElement();
//修复好的realClaszz
Class realClazz = dexFile.loadClass(className, context.getClassLoader());
//找出bug class,使用注解反射,修复
fix(realClazz);
}
}catch (Exception e){
}
}
private void fix (Class realClazz) {
Method[] methods = realClazz.getDeclaredMethods();
for (Method method : methods) {
//拿到注解
Replace replace = method.getAnnotation(Replace.class);
if (replace == null) continue;
String wrongClazzName = replace.clazz();
String wrongMethodName = replace.method();
try {
//拿到错误的class和method位置
Class wrongClass = Class.forName(wrongClazzName);
Method wMethod = wrongClass.getMethod(wrongClazzName, method.getParameterTypes());
//修复 C++实现
replace(wMethod, method);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public native void replace(Method wMethod, Method method);
#注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Replace{
String clazz();
String method();
}
#注解使用,已修复文件
public class text{
@Replace(clazz="bug文件路径",method="修复方法")
public int mytest{
return 1;
}
}
4.c++替换
下载系统源码,art 包 runtime 文件夹 art_method.h文件,artMethod方法。自定义art.h和common.h文件(这个文件没有找到)
拉入art.h和common.h
native-lib.cpp
#include <jni.h>
#include "art.h"
#include "common.h"
#include <string>
JNIEXPORT void JNICALL
Java_com_example_administrator_fixdavid_DxManager_replace(JNIEnv *env ,jobject instance, jobject wrongMethod,jobject method){
//拿到错误class 字节码里方法表里ArtMethod
art:: mirror::ArtMethod* smeth=(art::minor::ArtMethod*)env->FromFrflectedMethod(wrongMethod);
//拿到正确class 字节码里方法表里ArtMethod
art:: mirror::ArtMethod* dmeth=(art::minor::ArtMethod*)env->FromFrflectedMethod(method);
//替换
smeth->declaring_class_=dmeth->declaring_class_;
smeth->dex_cache_resolved_types_=dmeth->dex_cache_resolved_types_;
smeth->dex_cache_resolved_methods_=dmeth->dex_cache_resolved_methods_;
//替换art.h里方法
}
使用