0

i am trying to modify a jar that is partly obfuscated (and what i want to modify is in this part). I can use Recaf, it will decompile it well and I can save modifications and export program without issues, but doing that it recompiles the whole jar and not only the modified file, and that causes issues. If I open the jar with WinRar, those class appears as empty folders due to obfuscation.

So is there a way to modify only a single .class file without needing to recompile everything ? Even by editing bytecode, it's not an issue

2
  • Have you tried to copy the modified class from the Recaf modified jar into the original jar?
    – Robert
    Sep 4, 2023 at 17:44
  • He can't do that because of the ZIP obfuscation trick which makes class files appear as directories. It prevents extraction and replacement in almost all common ZIP tools.
    – Col-E
    Sep 15, 2023 at 3:01

1 Answer 1

1

I made Recaf.

I can use Recaf, it will decompile it well and I can save modifications and export program without issues.

The title and later description seems to imply the code is obfuscated. Please do not rely on recompilation features when dealing with obfuscated code. It rarely ever works and often has unintended side-effects.

Use the assembler for situations like this.

Even by editing bytecode, it's not an issue

Recaf self-advertises itself as a bytecode editor, and using it is explained in the documentation. Did you read the documentation? It prompts you to do so when first running the application.

but doing that it recompiles the whole jar

No it does not. When you make changes to a class, only that class gets updated within the in-memory model. When you export your changes Recaf will repackage the contents of the model into a JAR file again.

If you are using the current main releases 2.X, the JAR will be written with compression enabled for all entries.

If you are using the preview 3.X releases then you can toggle the use of compression in the config window. Upcoming work supports matching the compression settings per-entry of what they originally were marked as.

If I open the jar with WinRar, those class appears as empty folders due to obfuscation.

Assuming you mean the original input JAR here, this is because the JVM allows class files in zip files to end with a / character. Most tools will thus interpret it as a directory.

Using a standard ZIP archive tool to work around this is going to be tricky unless you normalize all the paths first. If this is the only ZIP file trick in the sample you can use the following to patch the JAR file:

File output = new File("output.jar");
File input = new File("input.jar");
try(ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(output))) {
    try (ZipFile zipIn = new ZipFile(input)) {
        // Copy zip entries of input to output
        Enumeration<? extends ZipEntry> entries = zipIn.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            String entryName = entry.getName();
            if (entryName.endsWith(".class/")) {
                // Fix the zip entry names of classes ending with slashes
                ByteArrayOutputStream tmp = new ByteArrayOutputStream();
                zipIn.getInputStream(entry).transferTo(tmp);
                
                // New blank entry with the fixed name, then write the original class data
                ZipEntry normalizedClassEntry = new ZipEntry(entryName.substring(0, entryName.length() - 1));
                zos.putNextEntry(normalizedClassEntry);
                zos.write(tmp.toByteArray());
                zos.closeEntry();
            } else if (!entry.isDirectory()) {
                // Copy any non-directory content as-is
                ByteArrayOutputStream tmp = new ByteArrayOutputStream();
                zipIn.getInputStream(entry).transferTo(tmp);
                zos.putNextEntry(entry);
                zos.write(tmp.toByteArray());
                zos.closeEntry();
            }
        }
    } finally {
        zos.finish();
        zos.close();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.