1

我正在尝试创建简单的 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);
}

有没有一种更清洁或更快的方法来实现这一点,因为这似乎有点矫枉过正?

4

1 回答 1

0

当 JVM 加载一个类时,它会将这些类的方法组织在一个所谓的方法表中。此方法表通过名称和描述符来标识每个方法。因此,您所做的是确定覆盖方法的唯一方法。(检查Overridden注解不是一个解决方案,因为这个注解没有保存在编译的类中,它只是作为 Java 编译器的指令。)

当您考虑在已编译后更改类的B extends A类时,这一点变得更加明显。如果重写了 的方法,则在重新编译后不一定仍然如此。ABBA

然而有一件事,方法的签名与被覆盖的方法无关。您应该改为检查描述符

于 2014-12-05T16:05:03.427 回答