← Back to context

Comment by leibnitz27

3 days ago

< disclaimer - I wrote CFR, which is one of the original set of 'modern' java decompilers >

Generic erasure is a giant pain in the rear. C# doesn't do this. You don't actually keep any information about generics in the bytecode, however some of the metadata is present. BUT IT COULD BE FULL OF LIES.

There's also a huge amount of syntactic sugar in later java versions - take for example switch expressions.

https://www.benf.org/other/cfr/switch_expressions.html

and OH MY GOD FINALLY

https://www.benf.org/other/cfr/finally.html

>Generic erasure is a giant pain in the rear

Personally, I don't get the sentiment. Yeah, decompiling might not produce the original source code, which is fair. It's possible to generate code using invokeDynamic and what not - still being valid code if a compiler opts to do so.

When decomiling bytecode there has to be a reason for, and a good one. There has to be a goal.

If the code is somewhat humanly understandable that's ok. if it's more readable than just bytecode, that's already an improvement.

Reading bytecode alone is not hard when it comes to reverse engineering. Java already comes with methods and fields available by design. Having local variable names and line numbers preserved is very common, due to exception stack traces being an excellent debugging tool. Hence debugging info gets to be preserved.

try/finally shares the same issues, albeit less pronounced.

C# doesn't erase all generics; but there's also some type erasure happening: nullable reference types, tuple element names, and the object/dynamic distinction are all not present in .NET bytecode; these are only stored in attributes for public signatures, but are erased for local variable types.

C# also has huge amounts of syntactic sugar: `yield return` and `await` compile into huge state machines; `fixed` statements come with similar problems as "finally" in java (including the possibility of exponential code growth during decompilation).

You're awesome! I had really good experiences with CFR in the mid 2010s.

I used it for game modding and documentation (and caught/reported a few game bugs + vulnerabilities along the way). I'd pull game files from Steam depots with steamkit, decompile with CFR, and run the resulting java through doxygen.