[英]Change all class references in a compiled class
我试图修改一个已编译的类(源代码不可用),例如,我想some.packageName.SomeClass
java.lang.Object
所有引用更改为some.packageName.SomeClass
。
引用指的是:
java.lang.Object.class
) 基本上,通过此示例,修改后的类应该不能直接访问java.lang.Object
类,而只能通过some.packageName.SomeClass
进行some.packageName.SomeClass
。 请注意,示例类可以是jre中的任何任意类。 提供的替代品将完全符合预期的性能。
使用BCEL或Javassist是否可以? 如果没有,是否有其他库提供实现此目标的功能?
我没有尝试过,但是javassist和ASM当然可以在类中更改常量池。 这是此类引用存储在类文件中的地方。
我使用ASM,这非常简单。 我有一个org.objectweb.asm.commons.Remapper的实现, 它将类的名称和描述符更改为新的。
例如,一种方法如下所示:
@Override
public String mapDesc(String desc) {
return super.mapDesc(StringUtil.fixDesc(desc, renamed));
}
描述如下: Lcom / example / Class; 。 我输入到fixDesc中的“重命名”字段是我进行的类映射的映射,其中包含旧值到新值。 因此,如果我想将com / example / AAA设置为com / example / BBB,则将之前和之后的值输入到映射中,然后像这样调用重新映射器:
/**
* Given a map of ClassNodes and mappings, returns a map of class names to
* class bytes.
*/
public static Map<String, byte[]> process(Map<String, ClassNode> nodes, Map<String, MappedClass> mappings) {
Map<String, byte[]> out = new HashMap<String, byte[]>();
RemapperImpl mapper = new RemapperImpl(mappings);
for (ClassNode cn : nodes.values()) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor remapper = new ClassRemapper(cw, mapper);
cn.accept(remapper);
out.put(mappings.get(cn.name).getNewName(), cw.toByteArray());
}
return out;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.