views:

268

answers:

5

I am building a spring mvc web application. I plan on using hibernate.

I don't have much experience with obfuscating etc.

What are the potential downsides to obfuscating an application?

I understand that there might be issues with debugging the app, and recovering lost source code is also an issue.

Are there any known issues with the actually running of the application? Can bugs be introduced?

Since this is an area I am looking for general guidance, please feel free to open up any issues that I should be aware of.

+1  A: 

The biggest problem centers around that fact that obfuscating programs generally make a guarantee of not changing the behavior of their target program. In some cases it proves to be very hard to do this -- for example, imagine a program which checks the value of certain private fields via reflection from a string array. An obfuscator may not be able to tell that this string also needs to be updated correspondingly, and the result will be unexpected access errors that pop up at runtime.

Worse still, it may not be obvious that the behavior of a program has changed subtly -- then you may not know that there's a problem at all, until your customer finds it first and gets upset.

Generally, professional-grade obfuscation products are sophisticated enough to catch some kinds of problems and prevent them, but ultimately it can be challenging to cover all the bases. The best defense is to run unit tests against the obfuscated result and make sure that all your expected behavior continues to hold true.

John Feminella
Are there any free professional grade ones you can recommend?
mrblah
+4  A: 

You may want to look at some of the comments here, to decide if obfuscating makes sense: http://stackoverflow.com/questions/1988451/net-obfuscation

You may want to express why you want to obfuscate. IMO the best reasons are mainly to have a smaller application, as you can get rid of classes that aren't being used in your project, while obfuscating.

I have never seen bugs introduced, as long as you aren't using reflection, assuming you can find something, as private methods for example will have their names changed.

James Black
`InternalsVisibleToAttribute` is also a fertile source of obfuscation bugs. I've also seen aggressive obfuscation render assemblies unusable on Mono.
itowlson
+4  A: 

Surprised no one has mentioned speed - in general, more obfuscated = slower-running code


[Edit] I can't believe this has -2. It is a correct answer.

Shortening identifiers and removing unused methods will decrease the file-size, but have 0 impact on the running speed (other than the few nanoseconds shaved off the loading time). In the meanwhile, most of the obfuscation of the program comes from added code:

  • Breaking 1 method into 5; interleaving methods; merging classes [aggregation transformations]
  • Splitting 1 arithmetic expression into 10; jumbling the control-flow [computation transformations]
  • And adding chunks of code that do nothing [opaque predicates]

are all common obfuscation techniques that cause a program to run slower.

BlueRaja - Danny Pflughoeft
Where did you get that idea? If anything obfuscation shortens identifiers and removes unused classes / methods. It is a kind of optimisation.
rsp
@rsp: see edited post
BlueRaja - Danny Pflughoeft
(@Raja, I didn't downvote when I added the comment.) The few obfuscators I encountered actually optimised. I guess one has to be aware of obfuscators that add junk in the process of obfuscation as you say.
rsp
+6  A: 

There are certainly some potential performance/maintenance issues, but a good obfuscator will let you get round at least some of them. Things to look out for:

  • an obvious one: if your code calls methods by reflection or dynamically loads classes, then this is liable to fail if the class/method names are obfuscated; a good obfuscator will let you select class/method names not to obfuscate to get round this problem;
  • a similar issue can occur if not all of your application is compiled at the same time;
  • if it deals directly at the bytecode level, an obfuscator can create code that in principle a Java compiler cannot create (e.g. it can insert arbitrary GOTO instructions, whereas from Java these can only be created as part of a loop)-- this may be a bit theoretical, but if I were writing a JVM, I'd optimise performance for sequences of bytecodes that a Java compiler can create, not ones that it can't...
  • the obfuscator is liable to make other subtle changes to performance if it significantly alters the number of bytecodes in a method, or in some way changes whether a given method/piece of code hits thresholds for certain JVM optimisations (e.g. "inline methods with fewer than X bytecodes").

But as you can see, some of these effects are a little subtle and theoretical-- so to some extent what you need to do is soak-test your application after obfuscation, just as you would with any other major change.

You should also be careful not to assume that obfuscation hides your code/algorithm (if that is your intention) as much as you want it to-- use a decompiler to have a look at the contents of the resulting obfuscated classes.

Neil Coffey
A: 

1 free one you might want to check out is Babel. It is designed to be used on the command line (like many other obfuscators), there is a Reflector addin that will provide a UI for you.

When it comes to obfuscation, you really need to analyze what your goal is. In your case - if you have a web application (mvc) are you planning on selling it as a canned downloadable application? (if not and you keep the source on your web servers then you don't need it).

You might look at the components and pick only certain parts to obfuscate ... not the whole thing. In general ASP.Net apps break pretty easy when you try to add obfuscation after you developed them due to all the reflection used.

Pretty much everything mentioned above is true ... it all depends on how many features you turn on to make it hard to reverse your code:

  • Renaming of members (fields/methods/events/properties) is most common (comes in different flavors: simple renaming of methods from something like GetId() to a() all the way to unreadable characters and removal of namespaces). BTW: This is where reflection usually breaks. Your assembly file may end up being smaller due to smaller strings being used too.
  • String encryption: this makes it harder to reverse your static strings used in your code. BTW: this paired with renaming makes it difficult for you to debug your renaming problems ... so you might turn it on after you have that working. This also will have to add code to decrypt the string right before it is used in IL
  • Code mangling ... this is what BlueRaja was refering to. It makes your code look like spagetti code - to make it harder for someone to figure out. The CLR does not like this ... it can't optimize things as easy and your final code will mostlikely proccess slower due to the additional branching and something not being inlined due to the IL rewriting used for this option. BTW: this option really does raise the bar on what it takes to reverse you source code, but may come with a performance hit.
  • Removal of unused code. Some obfuscators offer you the option to trim any code that it finds not being used. This may make your assembly a little smaller if you have alot of dead code hanging around ... but it is just a free benefit obfuscators throw in.

My advice is to only use it if you know why you are using it and design with that end in mind ... don't try to add it after you've finished your code (I've done that and it's not fun)

Jason Haley