仅使用 dexlib2 重写特定包中的 Methodreference
Rewrite Methodreference in particular package only using dexlib2
我正在使用 dexlib2 重写 dex 文件。我需要用我将包含在 aar 中的库 class 名称替换特定的 class 名称。我为此使用以下代码:
DexFile dexFile = DexFileFactory.loadDexFile(filePath, Opcodes.forApi(apiLevel));
DexRewriter dexRewriter = new DexRewriter(new RewriterModule() {
@Override
public Rewriter<MethodReference> getMethodReferenceRewriter(Rewriters rewriters) {
return new Rewriter<MethodReference>() {
@Override
public MethodReference rewrite(MethodReference value) {
if (value.getDefiningClass().equals("Ljava/util/Calendar;")
&& value.getName().equals("getInstance")) {
System.out.println("method Ref class:" + value.getDefiningClass());
ImmutableMethodReference methodRef = new ImmutableMethodReference(
"Lcom/mylib/ICalendar;", value.getName(),
value.getParameterTypes(), value.getReturnType());
return methodRef;
}
return value;
}
};
}
});
DexFile rewrittenDexFile = dexRewriter.rewriteDexFile(dexFile);
DexFileFactory.writeDexFile(filePath, rewrittenDexFile);
但是有了这个,它会在所有其他库中替换这个 class,这也会导致问题。我希望它只有在 classes 中包含某些软件包时才被替换。我可以在上面添加那种过滤器吗?
是的。您可以覆盖 getClassDefRewriter 并在那里添加您的过滤器。
DexRewriter dexRewriter = new DexRewriter(new RewriterModule() {
@Nonnull @Override public Rewriter<ClassDef> getClassDefRewriter(@Nonnull Rewriters rewriters) {
return new ClassDefRewriter(rewriters) {
@Nonnull @Override public ClassDef rewrite(@Nonnull ClassDef classDef) {
if (classDef.getType().startsWith("Lcom/my/package/")) {
return super.rewrite(classDef);
}
return classDef;
}
};
}
@Override
public Rewriter<MethodReference> getMethodReferenceRewriter(Rewriters rewriters) {
return new Rewriter<MethodReference>() {
@Override
public MethodReference rewrite(MethodReference value) {
if (value.getDefiningClass().equals("Ljava/util/Calendar;")
&& value.getName().equals("getInstance")) {
System.out.println("method Ref class:" + value.getDefiningClass());
ImmutableMethodReference methodRef = new ImmutableMethodReference(
"Lcom/mylib/ICalendar;", value.getName(),
value.getParameterTypes(), value.getReturnType());
return methodRef;
}
return value;
}
};
}
});
我正在使用 dexlib2 重写 dex 文件。我需要用我将包含在 aar 中的库 class 名称替换特定的 class 名称。我为此使用以下代码:
DexFile dexFile = DexFileFactory.loadDexFile(filePath, Opcodes.forApi(apiLevel));
DexRewriter dexRewriter = new DexRewriter(new RewriterModule() {
@Override
public Rewriter<MethodReference> getMethodReferenceRewriter(Rewriters rewriters) {
return new Rewriter<MethodReference>() {
@Override
public MethodReference rewrite(MethodReference value) {
if (value.getDefiningClass().equals("Ljava/util/Calendar;")
&& value.getName().equals("getInstance")) {
System.out.println("method Ref class:" + value.getDefiningClass());
ImmutableMethodReference methodRef = new ImmutableMethodReference(
"Lcom/mylib/ICalendar;", value.getName(),
value.getParameterTypes(), value.getReturnType());
return methodRef;
}
return value;
}
};
}
});
DexFile rewrittenDexFile = dexRewriter.rewriteDexFile(dexFile);
DexFileFactory.writeDexFile(filePath, rewrittenDexFile);
但是有了这个,它会在所有其他库中替换这个 class,这也会导致问题。我希望它只有在 classes 中包含某些软件包时才被替换。我可以在上面添加那种过滤器吗?
是的。您可以覆盖 getClassDefRewriter 并在那里添加您的过滤器。
DexRewriter dexRewriter = new DexRewriter(new RewriterModule() {
@Nonnull @Override public Rewriter<ClassDef> getClassDefRewriter(@Nonnull Rewriters rewriters) {
return new ClassDefRewriter(rewriters) {
@Nonnull @Override public ClassDef rewrite(@Nonnull ClassDef classDef) {
if (classDef.getType().startsWith("Lcom/my/package/")) {
return super.rewrite(classDef);
}
return classDef;
}
};
}
@Override
public Rewriter<MethodReference> getMethodReferenceRewriter(Rewriters rewriters) {
return new Rewriter<MethodReference>() {
@Override
public MethodReference rewrite(MethodReference value) {
if (value.getDefiningClass().equals("Ljava/util/Calendar;")
&& value.getName().equals("getInstance")) {
System.out.println("method Ref class:" + value.getDefiningClass());
ImmutableMethodReference methodRef = new ImmutableMethodReference(
"Lcom/mylib/ICalendar;", value.getName(),
value.getParameterTypes(), value.getReturnType());
return methodRef;
}
return value;
}
};
}
});