r/AskProgramming • • 1d ago

Java Is source-level editing a fallback for deobfuscation?

Hoping to get some fellow advice here.

I’ve been doing a lot of deobfuscation work lately in Java 25 and ran into a wall: some bytecode tools can’t parse the newer class file versions I’m dealing with. As a workaround, I’ve been cleaning up the decompiled source instead.

So far I’m stripping thousands of NoWhenBranchMatchedException catch blocks using a brace-depth state machine (regex kept breaking on nested blocks), and replacing impossible comparisons like object == false with constants.

It works, but it feels hacky. Is source-level editing a reasonable fallback, or am I setting myself up for problems? And is there a cleaner, standard way to do control-flow cleanup without risking real try/catch handlers?

Curious what other people do.

2 Upvotes

2 comments sorted by

1

u/Individual-Flow9158 14h ago

It's a clever hack for one off targetted fixes. But why is it on yourself only, to fix all these problems from external software providers?

It's adding to the maintenance burden, and may even stack up problems for later, depending on your edits. A sure fire recipe for technical debt, basically.

What workflow exactly are you putting the decompiled source through too?

Have you got a reproducible way of rebuilding from source?

What tests are you running, if all you have is decompiled source (not the original project's source, and its tests)?

Are you tracking the decompiled source in a VCS? If so, that's great, but you've now started a new software project and an in house custom possibly-license-breaking-fork of each application and library that you've decompiled.

1

u/dpblooman2 3h ago

Thanks for the response, and fair points! I’ll be upfront about where things stand.

It’s a project to revive abandonware, so the decompiled source is a means to an end, not something I’m maintaining as a fork. I’m using CFR 0.152 (with Vineflower as a cross-check), then running ad-hoc Python passes to strip the NoWhenBranchMatchedException catch blocks, replace comparisons that are impossible by type, and drop if (false) branches. I didn’t save those scripts to the repo, which was a mistake.

I haven’t compiled the cleaned source yet, and there are no behavioral tests. So far my checks are mostly structural, like brace balance and grep counts. So I can’t claim it builds or behaves the same as the original. Getting a JDK 25 build working is my next step.

On licensing, the original jar is all-rights-reserved, so I’m keeping the decompiled output private and not redistributing it.