Java 使用 ASM 反转 Jar 中的所有字符串

Java reverse all Strings in a Jar with ASM

我试图制作一个程序来反转 jar 中的每个字符串,然后再次执行相同的操作,使其类似于字符串混淆。 例如

普通代码:new String("example");

在 运行 之后:new String(new StringBuilder().append("elpmaxe").reverse().toString()

我的代码:

public class Main {
static String obfuscationFile;

public static void main(String[] args) throws IOException {
    obfuscationFile = "C:\Users\Leonhard\Desktop\CrackingTools-v1.0.jar"; // TODO:
                                                                                // args[0]
    File jar = new File(obfuscationFile);
    Map<String, byte[]> out = JarUtil.loadNonClassEntries(jar);
    Map<String, ClassNode> nodes = JarUtil.loadClasses(jar);
    for (ClassNode cn : nodes.values()) {
        for (Object mn : cn.methods) {
            MethodNode mnode = (MethodNode) mn;
            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            cn.accept(cw);
            if (mnode.name.startsWith("")) {
                for (Integer i : reverse(mnode, cw)) {
                    // TODO: Not needed..
                }
            }
            out.put(cn.name, cw.toByteArray());
        }
    }
    JarUtil.saveAsJarAndClasses(out, nodes, jar.getAbsolutePath().replace(".jar", "") + "_Reverse" + ".jar");
}

private static ArrayList<Integer> reverse(MethodNode method, ClassWriter cw) {
    ArrayList<Integer> i = new ArrayList<Integer>();
    int e = 0;
    for (AbstractInsnNode ain : method.instructions.toArray()) {
        e++;
        if (ain.getOpcode() == Opcodes.LDC) {
            if (ain instanceof LdcInsnNode) {
                LdcInsnNode ldc = (LdcInsnNode) ain;
                if (ldc.cst instanceof String) {
                    i.add(e);
                    ldc.cst = new StringBuilder().append(ldc.cst).reverse().toString();
                    MethodVisitor mv = null;
                    mv = cw.visitMethod(method.access, method.name, method.desc, method.signature,
                            (String[]) method.exceptions.toArray(new String[method.exceptions.size()]));
                    if (mv != null) {
                        // mv.visitLineNumber(e, new Label());
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                                "(Ljava/lang/String;)Ljava/lang/StringBuilder;", true);
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "reverse",
                                "()Ljava/lang/StringBuilder;", true);
                        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                                "()Ljava/lang/String;", true);
                        mv.visitMaxs(0, 0);
                        mv.visitEnd();
                        // System.out.println(method.name + " " +
                        // method.desc);
                    }
                }
            }
        }
    }
    return i;
}

(使用 ASM 5.0.4)

我的错误在哪里/我对 mv.visitMethodInsn() 做错了什么?

编辑:我注意到,它正在与 -noverify 一起使用(但所有字符串都被反转)。没有它我该怎么做才能让它工作?

如果没有关于您遇到的错误或问题的任何信息,很难准确判断出问题所在。但是,我注意到一个错误:

                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                        "(Ljava/lang/String;)Ljava/lang/StringBuilder;", true);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "reverse",
                        "()Ljava/lang/StringBuilder;", true);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                        "()Ljava/lang/String;", true);

在此代码中,您忘记实际创建您正在使用的 StringBuilder。您需要插入 newinvokespecial 指令来创建新的 StringBuilder。

附带说明一下,append 调用是不必要的。您可以将字符串直接传递给 StringBuilder 的构造函数。