java-deobfuscator / deobfuscator

The real deal
https://javadeobfuscator.com
Apache License 2.0
1.54k stars 288 forks source link

Jar instructions break after running no transformers #998

Open Nubebuster opened 2 months ago

Nubebuster commented 2 months ago

I have an obfuscated jar. I've been able to successfully deobfuscate a lot of it but I am running into an issue. When I run the deobfuscator without any transformers the jar still stops working. I've inspected the bytecode and I don't see any meaningful changes.

The only change I've observed for a troublesome class is that some instructions are moved. It not behave as expected anymore but it only has changes where the localvariabletable and linenumbertable are swapped. This shouldn't be an issue - ChatGPT.

I've also tried the LocalVariableRemover and LineNumberRemover but that doesn't affect the outcome of the jar working.

L5:     
        .localvariabletable
            0 is iiiIIiIiiii Lorg/bot/core/inject/hook/HookCollection; from L0 to L5
        .end localvariabletable
        .linenumbertable
            L0 255
        .end linenumbertable
    .end code
.end method

Is changed to

L5:     
        .linenumbertable
            L0 255
        .end linenumbertable
        .localvariabletable
            0 is iiiIIiIiiii Lorg/bot/core/inject/hook/HookCollection; from L0 to L5
        .end localvariabletable
    .end code
.end method
    private void test() throws Throwable {
        Configuration config = new Configuration();

        File workspace = new File("workspace");
        List<File> libs = Arrays.asList(new File(workspace, "lib").listFiles());
        config.setPath(libs);

        File input = new File(workspace, "input.jar");
        File output = new File(workspace, "output.jar");
        config.setInput(input);
        config.setOutput(output);

        List<String> regexPatterns = new ArrayList<>();
        regexPatterns.add("com\\/google\\/");
        regexPatterns.add("module-info");
        config.setIgnoredClasses(regexPatterns);

        new Deobfuscator(config).start();
    }

This means something changes that is not visible in the bytecode, or so I assume. I've tried patchAsm and that doesn't affect the outcome either.

I understand that with parsing into instructions and then back into bytecode there can be some things lost in translation. What could those things be?

The issue in practice is that this function throws an exception and then returns null. This may be because the object passed in in the first place is null, I am not sure.

   public static byte[] iiiIIiIiIii(Object iiiIIiIiiii) {
      try {
         ByteArrayOutputStream var1 = new ByteArrayOutputStream();
         (new ObjectOutputStream(var1)).writeObject(iiiIIiIiiii);
         return var1.toByteArray();
      } catch (Exception var2) {
         return null;
      }
   }

Any help or information would be greatly appreciated!

Nubebuster commented 2 months ago

I think the issue lies in a class that makes api calls which could be failing. In that case the Object passed is indeed null. Eitherway the question remains: how does that break if I don't run any transformers.

Janmm14 commented 2 months ago

I would say that the issue must be at another place. Try to look where the function is called or alter the exception handler to print the stack trace before returning null.

ItzSomebody commented 2 months ago

I have an obfuscated jar. I've been able to successfully deobfuscate a lot of it but I am running into an issue. When I run the deobfuscator without any transformers the jar still stops working. I've inspected the bytecode and I don't see any meaningful changes.

I haven't had a chance to look at this too much (especially with current obfuscation techniques), but have you checked if the program relies on certain parts of zip files and/or the constant pool of a classfile? The process of classfile -> ASM representation -> classfile is a lossy in particular with respect to the constant pool (unused entries are deleted entirely and the used ones can be reordered).

Nubebuster commented 2 months ago

I have an obfuscated jar. I've been able to successfully deobfuscate a lot of it but I am running into an issue. When I run the deobfuscator without any transformers the jar still stops working. I've inspected the bytecode and I don't see any meaningful changes.

I haven't had a chance to look at this too much (especially with current obfuscation techniques), but have you checked if the program relies on certain parts of zip files and/or the constant pool of a classfile? The process of classfile -> ASM representation -> classfile is a lossy in particular with respect to the constant pool (unused entries are deleted entirely and the used ones can be reordered).

Funny you should say that. I already had this suspicion that the problem was with serialization.

What happens in the program is that the api class is serialized and de-serialized in another process. This is what the second function I sent does. It serializes the api instance.

But now the question is, why does it matter that the constant pool is not original if this jar does both the serialization and de-serialization? They should both get to the same metadata right?

Janmm14 commented 2 months ago

@Nubebuster The idea was that the code, somewhere else maybe, is checking integrity somewhere as a protective measure. Reordered class pool entries change the file, bytecode can self-inspect via vsarious measures.

He did not say, that serialization inside the target application is the problem. He was talking about the class file.

It is hard to speculate what is going wrong without the jar file in question tho