Site of Product: https://www.bisguard.com/

Java-AntiDecompiler is an anti-reverse-engineering product by BIS Guard & Co. which encrypts Java classes and decrypts them on runtime and loads them into memory. This writeup is intended to show how the weak anti-attachment mechanism protection in Java-AntiDecompiler can be easily disabled in under 2 minutes with Krakatau allowing for easy access to the classes loaded in memory.

First, let’s disassemble the entry point method (main) with Krakatau

L3:     invokestatic Method java/lang/management/ManagementFactory getRuntimeMXBean ()Ljava/lang/management/RuntimeMXBean; 
L6:     astore_1 
L7:     new java/util/ArrayList 
L10:    dup 
L11:    aload_1 
L12:    invokeinterface InterfaceMethod java/lang/management/RuntimeMXBean getInputArguments ()Ljava/util/List; 1 
L17:    invokespecial Method java/util/ArrayList <init> (Ljava/util/Collection;)V 
L20:    astore_2

This gets the arguments used to run the protected jar and stores it in a variable.

L21:    aload_2 
L22:    getstatic Field JavaPreloader nodump Ljava/lang/String; 
L25:    invokeinterface InterfaceMethod java/util/List contains (Ljava/lang/Object;)Z 2 
L30:    ifeq L92 
L33:    aload_2 
L34:    getstatic Field JavaPreloader dump Ljava/lang/String; 
L37:    invokeinterface InterfaceMethod java/util/List lastIndexOf (Ljava/lang/Object;)I 2 
L42:    aload_2 
L43:    getstatic Field JavaPreloader nodump Ljava/lang/String; 
L46:    invokeinterface InterfaceMethod java/util/List lastIndexOf (Ljava/lang/Object;)I 2 
L51:    if_icmpge L92

Now according to this:

L86:    ldc '-XX:+DisableAttachMechanism' 
L88:    putstatic Field JavaPreloader nodump Ljava/lang/String;

The “nodump” field is assigned the value of “-XX:+DisableAttachMechanism”. This attempts to make sure the jar is ran with the JVM attach mechanism disabled. However, we can patch this as so:

L21:    aload_2 
L22:    getstatic Field JavaPreloader nodump Ljava/lang/String; 
L25:    invokeinterface InterfaceMethod java/util/List contains (Ljava/lang/Object;)Z 2 
L30:    ifne L92 
(instructions L33 to L51 are removed entirely from the bytecode)

Doing so forces the jar to run in “protected” mode despite the attach mechanism not being disabled. A java-agent can be attached easily and the classes dumped while the program is running.

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.security.ProtectionDomain;

import java.util.UUID;

public class ClassDump implements ClassFileTransformer {
    @Override
    public byte[] transform(ClassLoader loader,
                            String className,
                            Class<?> classBeingRedefined,
                            ProtectionDomain protectionDomain,
                            byte[] classfileBuffer) throws IllegalClassFormatException {
        try {
            if (className != null) {
                Path path = Paths.get("classes/" + className + ".class");
                if (!Files.exists(path.getParent())) {
                    Files.createDirectories(path.getParent());
                } else if (Files.exists(path.toAbsolutePath())) {
                    path = Paths.get("classes/" + UUID.randomUUID() + "/" + className + ".class");
                    if (!Files.exists(path.getParent())) {
                        Files.createDirectories(path.getParent());
                    }
                }
                System.out.println("[ClassDumper] Dumping " + path.toString().replace("\\", "/"));
                Files.write(path, classfileBuffer);
            }
        } catch (Throwable t) {
            System.out.println("[ClassDumper] There was an error trying to dump " + className);
            t.printStackTrace();
        }

        return classfileBuffer;
    }
}

My original writeup: https://github.com/ItzSomebody/CTF-Writeups/blob/master/misc/JavaAntidecompiler.md