I'm evaluating several obfuscators for protecting code in a WPF application.
For checking results of job done by each obfuscator on a given assembly I use Red Gate's .Net Reflector. Just after each obfuscation I open the assembly with .NET Reflector and see what it looks like.
Is it enough? Can .NET Reflector's results be treated as an indicator of quality of obfuscation, or should I try some additional tools? (not any possible instrument of such a kind, but from a point of view of practical common sense).
The results from Reflector should be enough on an indication of how any casual attempt at decompiling would fare. Some obfuscatory will obfuscate code to the extent that the assembly will not even open in Reflector.
Anyone who would try any deeper than that will not be easily deterred by more advanced obfuscation than others.
It would be best, if Reflector and ILSpy would outright refuse to decompile the resulting assembly. I know that there exist obfuscators that are capable of that.
My opinion is: that "is it enough" or not depends on your target app. Obfuscation is never about 100% secure code, it's always to make the code deassembly difficult enough for potential attacker, but it all depends on how much that "potential attacker" will put effort to deassembly your app. And also .NET Reflector is a viewer, like you mantioned, so if it's ecure or not can deduct you, by looking on, for example:
if strings are encrypted
if parameters are encrypted
if class names and fields like (PWD_USER) are encrypted
...
Regards.
Related
I've been using reflector to decompile a couple simple c# apps but I notice that though code is being decompiled, I still can't see things as they were written on VS. I think this is the way it is as the compiler replaces human instructions by machine code. However I thought I would give it a try and ask it on here. Maybe there is a decompiler that can decompile and show the coding almost identically to the original code.
That is impossible, since there are lots of ways to get the same IL from different code. For example, there is no way to know if an extension method was called fluent-style vs explicit on the declaring type. There is no way to know if LINQ vs regular code was used. All manner of implicit operations may or may not be there. Removed code may or may not have been there. Many primitives (including enums) up-to-and-including 4 bytes are indistinguishable once they are IL.
If you want the actual code, legally obtain the original code.
Existing .Net decompilers generally decompile to the best of their ability.
You appear to be asking for variable names and line formatting, which for obvious reasons are not compiled to IL.
There are several. I currently use JustDecompile found here http://www.telerik.com/products/decompiler.aspx?utm_source=twitter&utm_medium=sm&utm_campaign=ad
[Edit]
An alternative is .NET Reflector found here: http://www.reflector.net/
I believe there is a free version of it, but didn't take time to look.
Basically, no. There are often many ways to arrive at the same IL code, and there's no way at all for a decompiler to know which was used.
No, nor should there ever be. Things like comments and unreachable code would just add bloat with absolutely zero benefit. The very best you can ever do is approximate the compiled code.
In one of my .NET apps I must "validate" my program to a library with a license key.
But everyone who peeks into my assemblies can get the key...
This does not affect me but I do care about the creator(s) of the library.
I don't wish to "leak" his/their keys and cause him/them losses like this...
Is there any free tool that I can use to protect my data?
I really do not care about the other code... The key is important.
If you have to pass it into the library and if you don't control the library, then you can't do much anyway. You can obfuscate your code all you like to thwart Reflector users (but not Reflector VSPro, at least not easily) and I'll just use Crack.NET to peek into the memory and grab it from there.
It would have been the job of the library creator to give a secure mechanism, e.g. using public/private keys, SecureString, DPAPI or requiring a web call to store the key on the server.
The only way package I can recall is dotnetfuscator for ubfuscating code but this is not immune to reverse engineering from an expert. The topic is a sore point for C# developers the only real way to do this is not to use .net (which is no answer at all)
There are some others listed in question 211849
Another product doing this and other things: SmartAssembly from RedGate (though not free)...
There is no absolute security - esp. with JITted code (like IL/.NET and Java)...
Although beware of string constants - they need to be replaced by "static readonly" strings... otherwise they can't be "obfuscated/encrytped"...
I have the same situation. The key is present in my code. I do not obfuscate the code. I suppose this is because the bulk of my users are not programmers and would not know how to decompile the code and get at the key. If I was concerned then I thinkl I would obfuscate as suggested above
I would look at this in a different way.
If the library requires a license to validate; then do you have the right license to distribute the library in your application?
If so, then I'd say it's up to the library provider to give you instructions how to properly secure the key.
Otherwise, do the best you can with a code obfuscator.
Dotfuscator can do this for you. I believe it comes packaged with Visual Studio- look it up.
I wouldn't worry about it though; if you're not their only customer then chances are somebody else is leaking the license key through un-obfuscated code, making your efforts a waste of time.
There is a list of code obfuscators at MSDN.
Is obfuscation only about garbling the names of non-public variables/members? If so, would it not be possible to write an application that would at least change these names more readible ones like "variable1", etc, and then extract the whole code that can still be compiled?
No, it is about a lot more, especially with more sophisticated obfuscators. They can produce IL that cannot be expressed in most languages, and where the logic flow is horribly tangled to befuddle the best of tools. With lots of time you can do it (probably lots by hand), and there is certainly an arms race between the obfuscators and deobfuscators - but you vastly underestimate the technology here.
Also, note that many obfuscators look at an entire application (not just one assembly), so they can change the public API too.
That is certainly the start of an obfuscator. Though some obfuscators will also encrypt strings and other such tricks to make it very difficult to reverse engineer the assembly.
Of course, since the runtime needs to run the assembly after all of this, it is possible for a determined hacker to reverse engineer it :)
There are 'deobfuscator' tools to undo several obfuscation techniques like Decrypt strings, Remove proxy methods, Devirtualize virtualized code, Remove anti-debug code, Remove junk classes, Restore the types of method parameters and fields and more...
One very powerful tool is de4dot.
But there are more.
Obfuscation is about changing meaningful names like accountBalance to meaningless ones like a1.
The application will obviously still work, but it will be more difficult to understand the algorithms inside it.
It's depend upon the obfuscation technology used. Obsfucating variable name is only one part of the issue. A lot of obfuscation tools perform some kind of program flow obfuscation at the same time, which will complicate further code comprehension. At the end, the obfuscated IL won't be expressible easily (if at all) in most programming languages.
Renaming the variables and fields won't help you much either, as having a lot of variable1, variable2.. won't help you to understand what you read.
I'm trying to think of a way that prevents others from using your published dlls. For example let's say you create a cool lightweight WinUI photo processing tool that's separated into several assemblies. One of them is your precious filters.dll assembly that basically does all of the core filtering work. Once you publish your application, how can you prevent others from taking this filters.dll and using it in other projects?
I've already tried to look at the StrongNameIdentityPermissionAttribute which has a good example here but it doesn't seem to work for me, the code just works without throwing any security exceptions..
Any ideas?
Strong names have nothing to do with preventing or inhibiting reverse engineering. They only serve to stop people substituting assemblies with hacked versions - and only if people havent turned off strong name verification. There's nothing to stop people taking your code, ILDASMing or Reflectoring and re-ILASMing as they see fit.
InternalsVisibleTo and friends are on an honour system at the compiler level too, so not much use for what you're looking for (although for some obfuscators, internals get more agressively obfuscated than publics by default - though this can generally be overcome). My main concern here is to point out that jsut because something is 'internal' doesnt bestow on it any magic code protection pixie dust that stops reverse engineering.
Most of this stuff re why these sort of approaches arent a solution for code protection is summarised very well in this article
There are also code protection products on the market that go beyond obfuscation which sound like the tool for the job you describe.
One method that may work for you is to declare the the methods and classes in the filter assembly to be internal and explicitly specify the assemblies that can access it as "friends".
You do this with an assembly declaration (ususally in assemblyinfo) like:
[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]
see Friend Assemblies for more info.
Also make sure you obfuscate the assembly or people can dig into the code with reflector.
Don't bother worrying too much about protecting your .NET code. If you deploy it to someone elses computer, and that person wants to use or read your code, they will.
If your code is valuable enough you need to keep it on a computer you control (such as a web server) and guard against unauthorised access.
Obfuscation will only slow determined people down. Strong naming and signing is not used to protect your code, but instead to ensure that the user can confirm the code originates from who they expect it to come from (ie ensure it hasn't been tampered with).
Do class, method and variable names get included in the MSIL after compiling a Windows App project into an EXE?
For obfuscation - less names, harder to reverse engineer.
And for performance - shorter names, faster access.
e.g. So if methods ARE called via name:
Keep names short, better performance for named-lookup.
Keep names cryptic, harder to decompile.
Yes, they're in the IL - fire up Reflector and you'll see them. If they didn't end up in the IL, you couldn't build against them as libraries. (And yes, you can reference .exe files as if they were class libraries.)
However, this is all resolved once in JIT.
Keep names readable so that you'll be able to maintain the code in the future. The performance issue is unlikely to make any measurable difference, and if you want to obfuscate your code, don't do it at the source code level (where you're the one to read the code) - do it with a purpose-built obfuscator.
EDIT: As for what's included - why not just launch Reflector or ildasm and find out? From memory, you lose local variable names (which are in the pdb file if you build it) but that's about it. Private method names and private variable names are still there.
Yes, they do. I do not think that there will be notable performance gain by using shorter names. There is no way that gain overcomes the loss of readability.
Local variables are not included in MSIL. Fields, methods, classes etc are.
Variables are index based.
Member names do get included in the IL whether they are private or public. In fact all of your code gets included too, and if you'd use Reflector, you can practically read all the source code of the application. What's left is debugging the app, and I think there might be tools for that.
You must ABSOLUTELY (and I can't emphasize it more) obfuscate your code if you're making packaged applications that have a number of clients and competition. Luckily there are a number of obfuscators available.
This is a major gripe that I have with .Net. Since MS is doing so much hard work on this, why not develop (or acquire) a professional obfuscator and make that a part of VS. Dotfuscator just doesn't cut it, not the version they've for community.
Keep names short, better
performance for named-lookup.
How could this make any difference? I'm not sure how identifiers are looked up by the VM, but I'm pretty sure it's not doing a straight string comparison lookup. This would be the worst possible way to do it.
Keep names cryptic, harder to decompile.
To be honest, I don't think code obfuscation helps that much. Most competent developers out there have already developed a "sixth sense" to figure out things quickly even if identifiers like method names are totally unhelpful since very often the source code they need to maintain or improve already has these problems (I am talking about method names like "DoAllStuff()").
Anyway, security through obscurity is usually a bad idea.
If you are concerned about obfuscation check out .NET Reactor. I tested 8 different obfuscators and Reactor was not only the cheapest commercial one, it was the second best of the bunch (the best was the most expensive one, Dotfuscator Gold).
[EDIT]
Actually now that I think of it, if all you care about is obfuscating method names then the one that comes with VS.NET, Dotfuscator Community Edition, should work fine.
I think they're added, but the length of the name isn't going to affect anything, because of the way the function names are looked up. As for obfuscation, I think there are tools (Dotfuscator or something like that) that basically do exactly what you're saying.