-2

I tried to make a program that reverse every string in a jar and then do the same again, to make it be like a string obfuscation. eg.

Normal Code: new String("example");

After running: new String(new StringBuilder().append("elpmaxe").reverse().toString()

My Code:

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;
}

(Using ASM 5.0.4)

Where is my mistake / what did i do wrong with mv.visitMethodInsn()?

EDIT: I noticed, it's working with -noverify (but all strings are reversed). What can I do to get it working without it?

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Aura Lee
  • 416
  • 3
  • 11
  • Which problems are you experiencing? Without an error message, it's very difficult to tell what's wrong. – Antimony Apr 10 '16 at 18:44
  • It gives me a bytecode error. if you decompile it, you'll can see the error – Aura Lee Apr 10 '16 at 19:21
  • Have you manually done this and compared the bytecode? It should be quite apparent what needs changing after you do this. – Display Name Apr 12 '16 at 09:16
  • 2
    You are traversing the nodes of the Tree API, then suddenly in the middle of it starting to use the Visitor API. Also, you are manipulating the source class structure *after* generating the target class. Thankfully, you are overwriting each generated class with an entirely new class using a new `ClassWriter` when encountering the next method in your loop. In other words, you have so many logic errors that they start canceling each other out… – Holger Apr 12 '16 at 11:14

1 Answers1

2

It's hard to tell exactly what's wrong without any information about the errors or problems you are experiencing. However, there is one mistake I noticed:

                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);

In this code, you forgot to actually create the StringBuilder you are using. You'll need to insert a new and invokespecial instruction to create a new StringBuilder.

On a side note, the append call is unnecessary. You can pass a string directly to the ctor of StringBuilder.

Antimony
  • 37,781
  • 10
  • 100
  • 107
  • Edited that, still doesn't work. Same Error, as before. – Aura Lee Apr 10 '16 at 18:56
  • 1
    @GraxCode What is the error? You haven't even provided the error message, let alone a copy of the classfile. Also, please post your updated code. – Antimony Apr 10 '16 at 23:02
  • 1
    Passing `true` as the last parameter argument, claiming that the owner type (`java/lang/StringBuilder`) was an `interface` doesn’t help either… – Holger Apr 12 '16 at 11:00