benf.org :  other :  cfr :  faq

CFR - FAQ

This FAQ is missing information! Why?

I guess the question hasn't been asked! Mail me...

Is there an API?

As of 0.135, yes.

Where do I get it?

You can download it directly from the home page, or use a maven dependency

What's the license?

Read me

What does CFR mean?

Class File Reader. Nothing more interesting than that. I'm just rubbish with names.

There are so many options! You don't expect me to actually use them, do you?

Not really. CFR has multiple fallback passes where it enables different sets of fallback options, but for full disclosure, I've exposed all of these options on the command line. This means that you should never have to set an option - CFR will do it for you if necessary!

..... with the exception of flags which rename members. If these are neccessary, CFR will emit a comment suggesting you use them. I don't do it automatically, as it breaks reflective use of decompiled code.

Can I have line number matching to use in my debugger?

This is a can of worms. See this

Does it use any reflection etc?

Not for decompilation. I've written everything from scratch - partly because I'm doing this for fun, partly because I'm half tempted to port it to C++ at some point, so I don't want dependencies.

There is a small reflective use of NIO, to allow the code to (still) require only Java6.

Where's the source?

On github, here

Where's the test set?

On github, here

What? Why two repos?

CFR is very (very) deliberately java 6 only. But it can handle every release of java up to 13 (and beyond, hopefully!).
The test suite needs to reflect this. It's easier to do this with two separate repos.

Is there a mailing list? Updates?

I'll try to announce updates on Twitter - @LeeAtBenf

Is there a bugtraq?

Just use the issue tracker on github, here.
But PLEASE do not submit classes to which you don't own the copyright.

Why?

For fun. That's the entire reason. I moved from a C++ job to a Java job, and writing a decompiler seemed like a good way to learn the java ecosystem... - there's a lot of published material out there on coin, etc, but not a vast amount on what's going on with the bytecode...

But... why java 6? This isn't 1996!

Java 6 is still amazingly widely installed. Because CFR has its own implementations of all of the class file features / jls understanding, it doesn't actually need java 8 to understand java 8 features! (Though occasionally I find myself missing syntactic sugar!)

Your decompiler sucks at XYZ...

Yup, probably. There are always going to be edge cases. Feel free to send me examples, IF THE INTELLECTUAL PROPERTY BELONGS TO YOU.

You could get a lot better information if you trusted the LocalVariableTypeTable.

Absolutely. But I'm imagining a world where people lie, when they can. JVMs don't verify signature attributes - they can lie. Local type tables can lie. And I want to see what sort of a decompiler I can get if I don't trust information I can't verify..... (though I do use LocalVariableNameTable for hints. Hey, I'm weak.)

I still see some synthetic methods in the output - why don't you just hide them?!

Paranoia. It's possible (and legal) to mark every method in your codebase synthetic, if you're feeling mean. CFR will only remove synthetic methods when it's validated what they're doing, (i.e. friend accessors)

I see messages like Failed to find class java/util/stream/Stream.class

The JRE used when decompiling doesn't have to support the needs of the class file. If you're decompiling Java 8 files using a Java 6 JRE, then the support classes will be unavailable to CFR. They're not strictly necessary, however they will improve the quality of the decompilation.

Why not just topologically sort basic blocks all the time?

I find if the code hasn't been obfuscated (or more accurately, been madly rebuilt with dex2jar) then the bytecode straight out of javac is in a more sensible ordering than I get after a topsort. As such, I only apply the topsort if CFR can't produce sensible code off the basic ordering. (and ends up creating code that seems to contain Duff's device... :P )

Can it do insert my JVM language here?

Maybe. Probably. Possibly. But you'll end up with Java. Which isn't necessarily a bad thing - I've found it fascinating seeing what Scala/Kotlin/Groovy look like if you push them back into java! If you've got a pet JVM language that CFR particluarly sucks at, please let me know - but please don't expect CFR to generate anything but Java for now!

I can't seem to use the cfr jar (-jar) and specify my own jar (-cp) on the classpath.

java -jar cfr.xxx.jar -cp myPath/myJar.jar myClassName
doesn't work.

Nope - this a java cli behaviour - to work around this, you can specify

--extraclasspath myPath/myJar.jar

Why did you change the naming scheme?

Prior to 0.135, CFR has been entirely self hosted, which means I kept doing the first thing that popped into my head. As of 0.135, I've let the project grow up a bit, and it's hosted on maven central. As such, it's good to play nice!

Other decompilers?

awwww ;)

There are tonnes, but not many which support modern Java features.

The entire CFR website looks like it was put together in vi - why not move into the 90s, at least?

It was. Consider it my backlash against the form over function that seems to exist everywhere! (And hey, at least you don't need javascript enabled.)

.... mail me (lee@benf.org) if I've missed something ;)
Last updated 03/2018