我正在尝试创建简单的Java混淆器,以便使用OW2的ASM在运行时修改字节码来创建它。
我的目标是重命名每个类,字段和方法名称,但如果MethodNode很容易存在于超类中,我无法弄清楚如何删除
我目前递归循环遍历当前类中的每个超类,并查看方法是否存在同名和签名
private boolean isSuperMethod(MethodNode method, ClassNode node) {
if(node.superName == null)
return false;
boolean exists = false;
ClassNode cn = null;
try {
ClassReader cr = new ClassReader(node.superName);
cn = new ClassNode();
cr.accept(cn, 0);
} catch (IOException e) {
e.printStackTrace();
}
for(MethodNode superMethod: (List<MethodNode>)cn.methods) {
boolean sameSignature = (superMethod.signature == null && method.signature == null) || superMethod.signature.equals(method.signature);
if(superMethod.name.equals(method.name) && sameSignature) {
System.out.println(superMethod.name + " exists in parent class(" + cn.name + ")");
exists = true;
break;
}
}
return exists || isSuperMethod(method, cn);
}
是否有更清洁或更快的方法来实现这一目标,因为这看起来有点矫枉过正?
答案 0 :(得分:0)
当JVM加载一个类时,它会在所谓的方法表中组织这些类的方法。此方法表按名称和描述符标识每个方法。因此,您所做的是确定重写方法的唯一方法。 (检查Overridden
注释不是解决方案,因为此注释未在编译类中保留,它仅用作Java编译器的指令。)
当您考虑在编译B extends A
之后更改类A
的类B
时,这一点就变得更加明显了。如果B
覆盖了A
的方法,则在重新编译后不一定是这样。
但有一点,方法的签名与被覆盖的方法无关。您应该检查描述符。