[UNITY-DEVs?!]: Is Obfuscation of NET assembly sufficient to protect code?

Hi there,

[Just in case: This is NOT a question about Obfuscators, so please don’t try to sell them here xD, I know them all]

I have a question that can probably only be answered by a Unity developer…
When you build a project the NET assemblies seems to be just lying around there in “Xxx_Data/Managed/”, like “Assembly-CSharp.dll” which would be the one containing my code…

If I now use a tool like “eazfuscator” or RedGate to properly protect this DLL, and keeping all names, that are required for Unity to apply behaviours, unchanged; would it be sufficient? Or is the NET code stored somewhere else as well? Is it for example precompiled into some Unity internal file or whatever (so that this plain NET assembly is just used for reflection)?

The reason is, that if I really only need to protect the built NET DLL, then this would simplify obfuscation a lot. Otherwise I would have to create some sort of proxy for each MonoBehaviour and then link it with a preobfuscated DLL containing my original code and then build the project (does not only sound cumbersome; the good thing is that I have not that much behaviours, but still it leaves the irritating process of adding an obfuscated DLL to the assets and the whole thing…)

Thanks a lot :wink:
C.M.Burns

I’d suggest you try it yourself and see how it goes. I don’t know exactly how unity serializes things, but SerializedObject in UnityEditor all settings are stored for something/variables for something like a prefab are saved by name.

I would hope though whatever benefits there are to obfuscation it would leave memberinfo’s alone name wise? Or is that all obfuscation does?

But yea, other than testing it yourself you’ll probably need a developer to give you more info

Redgate for me has worked the best and is the hardest to reverse. Not impossible, but it makes my life a nightmare at times when I am picking apart other people’s code for ideas. :slight_smile: There is also the dedicated Unity3D Obfuscator sold by Tech-Next. I have heard a number of complaints against that one and I have heard the support is not great. It uses, AFAICS, the standard Mono obfuscator wrapped in a simple .NET application.

With Redgate you get the benefit of being able to endlessly tweak what gets obfuscated and what does not, thereby ensuring that your code can still run against the Unity run-time. You can protect parts of the Unity run-time too, but the only part you really need to concentrate on is your own code. Redgate also gives you instrumentation so you can actually track what parts of your code is being called and report it back to a server and database. Nice if you want to track down which features are being used, or highest levels reached in the game.

Is obfuscation worth it? I think it is. It won’t stop people copying your game, and the number of people out there who have ability to reverse your game is very little, but if you don’t want to give away all of your source code, obfuscation will at least stop a larger majority of lazy leechers.

One more thought, if you want to protect everything, not just your code, you may consider something like Molebox or Armadillo to protect assets and code. This of course only works on the PC platform. I think there are similar packages for Mac OS X.

To complete what Justin has already begun and to answer BDevs question:

Obfuscation starts with randomizing or encrypting all eligable symbols in an assembly. Eligable depends on many things. For an exe without serialization you can probably randomize everything, for Unity you will at least have to exclude the MonoBehaviour method names and so on…

That’s already enough to raise the bar of effort for reconstructing your code to a level where it is usually cheaper to copy your product by rewriting it from scratch. Either way its illegal and that’s not what obfuscation is really about. You might want to protect some fancy algorithms you have expensively developed and don’t want someone to steal them. You may want to prevent hackers/cheaters from gaining important insides of your application. Make your license protection more solid… etc…

But obfuscators can do much more. For an extensive explanation you may visit the RedGate site. But there are code flow obfuscation (which simply reorders/replaces instructions on IL level), native compilation (which replaces some of your IL code with real native code), insertion of illegal/non-standard NET code, creating proxies for external dependencies, so that it is almost impossible to see which parts of your code call System.IO.File.Read() for example… All except renaming and code flow obfuscation are potentially incompatible to MONO and thus Unity, but provide among the strongest way to prevent decompilation, which essentially helpful to counter cheaters/hackers…

So in summary… Renaming/Code flow makes decompilation rather useless. All other protections usually make decompilation not possible at all (since the decompiler/disassembler fails during the process, hopefully for as many methods as possible), but do not increase the real obfuscation that much anymore. Proxies are more a runtime protection, so that it is much harder to hook into your running application…

Properly embedded useless proxy functions are probably the biggest bane of my life. You can easily spend twenty minutes tracing through code only to find that the proxy function you just reversed is actually just junk code inserted by the obfuscator. Code flow isn’t that difficult to reverse and names are reasonably simple. Usually I am after only a few functions, like in the Unity.exe, to figure out something. The entire program is usually not worth figuring out as 90% of it will be interface code, or housekeeping code, or error handling code. When reversing something, I am after either a few short bytes, or maybe, at most, a hundred lines to a couple of hundred lines of code.

Before you invest in an obfuscator, you might want to look at the de-obfuscators available for the products you’re interested in. Especially if it’s a popular package such as RedGate.

This is also true, but I have yet to find a de-obfuscator that can stand up to what Redgate does. There is a reason it starts at $800. Makes the Mono obfuscator tool look like a toy. De-obfuscation is not entirely automatic, there is still quite a bit of manual labour involved figuring out the code. But yes, do try out some of the commercial de-obfuscators and obfuscators (screw the free ones, they’re pretty much useless for anything but slowing someone down by a few minutes) and see what works for you. All the stuff I care about that I do in .NET gets run through Redgate’s tools first though. :slight_smile:

If obfuscation is done properly, deobfuscators should have a really hard time to output anything useful, regardless how popular the obfuscator is… As a matter of fact, if they could do anything reasonable then the obfuscator wouldn’t be popular at all xD. And they still will never be able to reverse the renaming, not to speak of LINQ expression and all the other fancy compiler generated stuff, code comments, code structure and so on. Its hard enough to keep the code maintainable as it is ;). Deobfuscation and decompiling is not much of use for anything but hackers. You can’t get a working product out of it and probably neither get much useful information for your own products at all; and thats the most important thing to me. Also I would rather use a combination of different obfuscators…

@Justin: But you still have to find it in that hunk of junk that comes out of RedGate. And I wonder how you even know what you are looking for ^^. I mean if you just have about 500KB - 1MB of obfuscated junk in front of you and the running game on the other hand there isn’t much to get you started with. What exactly would you be looking for now ^^?

Some of us can read MSIL easier than we read hex dumps of x86 code. :slight_smile: I grew up reading assembly dumps from various processors. Your fancy new MSIL technology holds no fears for me, old man.

But you are correct, the good obfuscators inject a lot of crap if used properly, but when all is said and done, you start from some suspected values in memory and work back from there.

Right now you are a little bit too presumptuous…

But back to topic:

  1. MSIL is a very clean assembly language, if you can even say it to be one. So the x86 comparison is a little far fetched.
  2. What should one fear about NET? Though you probably can as soon as it gets hardware locked into the processor, then goodbye reverse engineering ;), at least for 99.99999999% of the people… Microsoft and Intel already started something like that but it got killed in the market before it even arrived (because they focused on DRM instead of safety; or let’s say they cared only about the safety of their money)
  3. The working back sounds like fun and that’s also a little gift for all those who worry about their IP being stolen; all the time other people waste from their short span on earth crawling through assembly code ;). Probably one of the main reasons why I would never become hacker. I’d rather think about how they’ve done it and make it even better, instead of stealing their results…

But now it is getting philosophically…

There’s little presumptuous about it. I’ve been writing assembler for various CPUs for 33 years, MSIL, even when obfuscated, is like reading Jack and Jill compared to Tolstoy.

Point two I won’t touch because until I get my hands on it, I don’t know. Extracting firmware isn’t impossible, it can be made difficult, but not impossible.

Reverse engineering, it’s how I got to where I am today. It’s not for everyone. It’s a specialised skill. I get compensated very well for figuring out stuff that isn’t documented, or locked down for whatever reason. Hacking is where a lot of good ideas come from.

Well, I mean you are presumptuous about other people ^^. But let’s cut this right now. We are talking at cross purposes… I have a similar background just not that long.

There is nothing you can do to protect your code once it is in user’s hand. Whatever you do is only delaying the inevitable. The only thing you can do is to pray OnLive become the standard and a resounding success that everyone adopts it as platform. There is nothing to crack if you don’t send anything to user (except video stream).

EDIT: Actually this gave me an idea. I wonder how feasible it is to just stream encrypted scripts
(let’s say NPC behaviors) to user’s memory remotely. Occasional server connection would be required, but nothing is saved on the machine (let’s say iPhone/iPad/iPod) only in memory so there is nothing left for the cracker to get their hands on once they quit out of the game.

Actually this whole thread explains how this protection works… Of course some people, like Justin ;), might actually extract a few things but who cares about? The final product is unrecoverably protected in well obfuscated assemblies…

Helps you almost nothing. In memory is just as good as in file, sometimes even better, since the program is loaded and functional while on disk it might actually be further protected…

It is impossible to completely protect anything ever. However, obfuscating it will help quite a bit.

You didn’t look too hard, as the tools exist. Just found one in 30 seconds that works with up to Smart Assembly 6, and was last updated in July.

There’s an entire sub-culture on the internet with dedicated forums who’s main purpose is to prove the marketing pronouncements of obfuscators to be hollow. It’s a constant cat and mouse game, the problem being there’s far more cats than there are mice.

I dont think your going to get a straight answer MrBurns off the forums. If you’ve got unity pro you could see about using a support ticket.

I am not really sure what you are up to ^^. No one talks about total protection… The reason for obfuscation is to make it impossible (in the means of economics) that someone steals your code and thus your project. And additionally it should make it much harder for hackers/cheaters to crack your app. Both things are well accomplished by obfuscation and once again, you can’t revert the obfuscation done by RedGate, that’s a mathematical thesis (to be more precise, Obfuscators cause a massive loss of information; this is not recoverable by any tool). The only thing you can do is to “try” to judge by some internal way RedGate or any other tool like this is doing proxies, code flow obfuscation and the like to somehow restore the approximate original “intention” of the programmer and C# compiler. So it is gonna be some sort of heuristic reconstruction. But then still you have a lot of crap and noise in there, not to speak of the god damn name obfuscation. Assemblies do not decompile into “good” code when not obfuscated at all and if all the names are screwed up and most of the already non really existing structure is totally ruined your gonna get a hell of a mess. And if you decompile a 500KB-1MB assembly like this, you will end up in a nightmare. And even if someone gets something out of it, the overall value of your product is well protected since it would take considerably longer to restore working code out of this hell hole, than rewriting the product from scratch, and what more do you want?! Its the most important thing that’s desirable and the only thing that can safely be archived by now…

In summary obfuscation is desirable because:

Developing the product from scratch costs X dollars

Reconstructing the product out of the obfuscated costs Y dollars

As soon as Y >= X, obfuscation is a good thing and as a matter of fact Y is usually way greater than X with any good obfuscation tool. And you can stop nobody from just rewriting your app from scratch anyway… And that’s what defines the “level of protection” obfuscators need to archive.

I hope we can close the discussion about whether obfuscation is necessary or useless by now…

Personally, at least when going with standalone, I would care less about Obfuscation and more about using something like SoftwarePassport by http://www.siliconrealms.com/ or a similar system that has the code encrypted and realtime decrypts it in memory or runs it directly in a pseudo VM with the code being stored in this fictive VM systems code.
Its a hell harder to get anything from that, from fictive non existant cpu instructions, then it is to get something “stupid marker renaming” wanna be protections, cause people who can read deassembled code have no problem with trash variable names at all to decypher meaning of code.

Since we are in a graphic forum, maybe the following comparison helps more. Obfuscation is like:

  1. Blurring your image (renaming)
  2. Randomly merge larger chunks of the blurred one (according to internal rules)
  3. blending them with a lot of artifacts (most likely randomly)
  4. Randomly merge smaller chunks in each little chunks (according to internal rules)
  5. adding a lot of crap chunks and thereby making the image larger

No while you can revert (with huge effort and only with a lot of noise and cracks) the steps 2-5, maybe… You will never be able to to revert the blurring, since blurring causes a loss of information, an unrecoverable loss of information… And most importantly, the blurred information somewhat IS your code. You shouldn’t underestimate the value of names ^^. Code without names is pretty much useless. And the only thing, as I mentioned before, that actually might cause lesser costs by “deobfuscation” than by rewriting are complex, secret algorithms. But that’s hopefully not your entire product… And you can’t prevent anyone from stealing algorithms…