{smartassembly} & Optimization
Although we came across {smartassembly} while searching for the best obfuscation tool, we’re most impressed in some of the amazing improvements to .NET assemblies in terms of optimization and performance in our test runs. Throughout this review, we’ve focused on getting a real-world look at things, and for this section, we just put our EasyBCD through the motions, and were duly impressed.
Memory Usage Enhancements
{smartassembly} has a couple of excellent features aimed at improving the memory usage of your .NET assemblies. There are a couple of options that can be enabled, but first, here’s a before-and-after:
{smartassembly} uses several different techniques to bring down the memory usage.
We asked the developers of {smartassembly} for some of the specifics, and they told us that by default the CLR reserves a ton of memory for .NET assemblies – whether or not they request it. So {smartassembly} intelligently detects when the CPU is idle (or thereabout) and increases or decreases the amount of reserved memory for your assembly according to its requirements – “automated” GC in a sense, except that memory may or may not have ever been in use.
In that same vein, {smartassembly} (with the benefit of literally having access to your source code thanks to the way .NET is designed) marks any and all classes that don’t have any detectable “child” classes inheriting from them as “sealed” thereby reducing the amount of memory and CPU used by the CLR during run-time to determine what functions should be made available to other classes and libraries.
Improved Size and CPU Requirements
One of the unique techniques used by {smartassembly} to improve the performance of .NET assemblies involves not loading all of the required dependencies
of the main application at once. This is similar to inline vs. external functions in C++, except the dependencies – once requested – are expanded into the memory-space and then have the same performance as the main application itself. Effectively, this is an intelligent compromise between performance and bloat, especially in large applications that rarely have all options activated at once. In our tests, it depends on the size (and quantity) of the external libraries and dependencies being used by the application in question, but by only loading the main assembly into the memory then dynamically decompressing the dependencies (packed with a mild compression algorithm) as one-time occurrence can end up with a huge performance benefit.
{smartassembly} also takes a heuristics approach with regards to detecting unused code and dependencies, then simply cutting them out of the compiled software. Depending on the exact make-up of your program, this has several improvements including securing as-of-yet unimplemented code from prying eyes (think of all those Easter Eggs!), decreasing the executable assembly’s file size, and improving memory usage.
General Improvements
{smartassembly} has one more feature that can make a real difference: it can merge all dependencies and libraries that your application relies on directly into your own code. Then when the time comes to apply the above-mentioned improvements, all those bulky libraries that you only use a function or two from are suddenly subjected to intense filtering and pruning. If you’re using some heavy UI libraries (like DevEx), this can be a real God-send. Besides the drastic improvements to the size of your application, this leads to snappier code and easier deployment – no need to muck around with dependencies in your package manager.
My main complaint with obfuscators is that they kill working things. We have a large client/server architecture with .NET remoting in place to communicate between the 2. Obfuscators cannot change any of the contract calls between client/server, yet all of them crap out on this and force you do do “only metadata” obfuscation.
Additionally, we have run into bad IL issues with Spices, DotFuscator, Salamander, and XenoCode. With Xenocode, the developers gave us some hotfixes that eventually solved the problem.
But I wonder…is all this really worth it? What are we trying to protect? It seems to me the only thing we should be worried about protecting is connection strings, passwords, encryption keys, or activation/time bomb related code.
Yes, it’s true that someone could reflect on the IL, generate functionally equivalent, although comment-less code, and build their own product from that. But honestly, who’s going to do that? The software would be unmaintainable — machine generated, no comments. Businesses would never in their right mind risk a lawsuit by stealing an entire codebase and calling it their own.
Hi Judah,
Unfortunately, your perceptions of people are rather kind! We’ve had this done to us with our programs by other “companies” who don’t mind the extra drudge work so long as there is no thinking and innovating involved.
I know exactly the problems you are talking about – the obfuscators just break the application. Unhandled exceptions, no sync, etc. That’s exactly what we experienced with both Spices and XenoCode. {smartassembly} worked for us though.
I know how you feel. We shouldn’t have to protect our source code. It’s ours, the program and the source alike. No one should try to steal it, it’s too obvious. But unfortunately, the world isn’t filled with only good people. Give {smartassembly} a try, it’s a free trial download – I believe it may work well for you.
Hm, seems SA is only for single assemblies. How about several assemblies, cross-obfuscation, tamper-proofing solutions (very urgent feature for us)? I love Spices.Obfuscator with Anonymizer and antiTampering (these thhigs really work for us), cross-obfuscation (I’ve 15 assemblies in project), that tool is really smarter than smart-assembly and offer real solution to protect big things.
2 Judah: don’t afraid to contact to vendors to solve your problem. I had runned into some problems with spices obfuscator and received some useful recommendations relating to my assemblies protection that solved all my problems.
SA does have an option to obfuscate additional assemblies, at least in the version we tested.
Spices ruined our app as well, it would hang before the Window was even created. I don’t have time to contact commercial vendors whose apps don’t work as advertised, that’s why I’m happy we chose {smartassembly} where we didn’t need to: it just worked.
Hm, but I’ve briefly compared SA with Spices.Obfuscator – assembly after SA is still easy to decompile (ILDASM, Spices.Decompiler, Reflector), many of members iare leaved from obfuscation (some internal and private members not obfuscated, these are usual classes don’t excluded from obfuscation in single exe). Anyone can disassemble this app, make changes and assemble with ILASM with my own code – in other words, make workable copy of protected program, program is still has roundtrip vulnerabilty. You can be happy with SA, you can have no time to contact commercial vendors to take recommendations from experts/professional to REALLY protect your code, until hackers start to distribute your code. In other words – you happy because SA doesn’t ruined your app, isn’t it?
I’ve tried a lot of obfuscators – dotfuscator, xenocode, SA, salamander, Spices.Obfuscator, native protection – Codeveil. They have their own advantages and disadvantages. It’s need to understand results of obfuscation, reasons of incorrect work of program after obfuscation (the main problem – serialization/reflection), what members should be obfuscated and excluded from obfuscaton, analyze results of obfuscation to understand real protection.
BTW, I’ve tried EasyBCD – on startup this program shows AV exception, but continue to work, and after some clicks – View Settings (shows AV), Configure Boot – shows SA exception and crashes. Are you sure that SA doesn’t ruined your app?
Unfortunately, all obfuscation companies are loosing some serious customers, simply because they do not release a simple document of guidelines for writing code that works with obfuscation. I had to go through all the pain of changing my code to make it obfuscatable. I wish i could have some time to write these guidelines myself one day. I know people who already shifted from .NET to other technologies like delphi and c++ just because of the missing the right connection between .NET and obfuscation.
Well, in my experience most of the small obfuscation companies (basically all but Preemptive and Salamander) will gladly allow you to send a program that won’t obfuscate, and send you a patched version of their product that works with it.
As a sidenote: in {smartassembly} 2.2, the problem we experienced with 30-minute obfuscation times was fixed.
I’m a customer of SA….and i think that SA is a good solution…in terms of moneyprotection…
ok someone may say not the most unexploitable….
but i think that his protection is enough for many software companies that don’t have a world-wide distribution, but a simple and more realistic pool of customers.
many of us don’t have hackes that try to steal our super-formulas, in the worst case we can have people that try to duplicate the installation on another machine…without even know what they are doing…and for the “little-selfmade-pro-hacker-wannabe” that our software may ancounter SA seems really enough…(considering his price remember)
The thing that SA REALLY NEED is cross-obfuscation!!!!! all the other things can go fine…
Projects are very large and it is impossible to embed all in a single exe….what about upgrades???? what about maintenance in general??? if i want to change a single function in a library i need to REBUILD all the solution ?????
SA is a good choice but REALLY cross-obfuscation is a thing that we can no longer ignore when writing reviews on obfuscators!!!!! reviews are for all not only for personal-use, single-little-exe’s programmers….the most part of customers of an obfuscator are software companies not peoples in their house!!!
I fully agree with you. At the time when this article was written, we neglected to try {smartassembly} on anything larger than a single exe with multiple library dependencies.
However, we’ve recently tried to obfuscate/optimize a much larger project with multiple executable files and share libraries between them all, and it was not a fun experience.
If you obfuscate a library, it breaks the dependencies in the exe files. For each file you need optimized, you need a seperate project (one file is obfuscated per project).
Hopefully future versions of {smartassembly} will feature improvements in the cross-obfuscation realm……..
I had many issues implementing obfuscation. The main problem was that obfuscation breaks your code. As a result I’ve tried .NET code protection tools, CliSecure in particular worked very well for me. It’s very easy to use, just feed it with your assemblies and run it, and it doesn’t require any modifications or adjustements to your code like most obfuscation tool required.
Does it support cross-compilation? Because that’s the big thing that {smartassembly} is missing and no one else seems to do right.
The main issue with obfuscation tools is that they often break your code. I had many issues with obfuscation and therefore decided to evaluate some .NET code protection tools. CliSecure, in particulr, worked very well for me. It’s very easy to use, just feed it with assemblies and let it secure your code. It doesn’t require any modification or adjustements like most obfuscation tools require.
Dan.
CliSecure is not an obfuscator, it’s a code protection tool. It leaves class & method names intact but at the same time secures your .NET code not allowing it to be reflected by standard .NET tools such as reflector.
I just took a look at it, and, sorry, it’s terrible.
Can you be more specific?
We actually make programs for a hacking community, and while I must say we’re always fighting to keep on top of others, people are always trying to decompile our stuff. Previously, we have used Xenocode, Xheo and a few others. They all failed us. Not only faliled bad, but really faild. Xenocode could hardly produce an assembly that works, Xheo was easily decompiled.
Smartassembly was a god send. This peice of software is the absoulte best obfuscuator out there. We do have issues with MAX protection, so we tone it down slightly, and everything is amazingly perfect. The best feature alone is us not having to tweek the obfuscuation every build. The first time we set it up and got it working has been the only time we’ve touched it.
Moreover, once you setup one project, you learn everything really fast and setting up others is easy as pie. Also, since this review, they added alot of features. You can also tell SA to use max protection on this class but not that class. It is overall, the best working product out there.
No decompilers have been able to crack it. We’ve yet to see “Cracked” versions of our applications out there since SA, which cause revenue to triple.
Only downside is they charge quite a bit for smalltime developers to be able to keep using their webservice for error tracking, however this code isn’t that hard to replicate, so it’s not that bad.
5/5 stars.
Dave, do you use any other tools to protect your software except SA?
I am planing to launch a marketing related software product in C#. I know that there is a small cracking community and I want to add some protection to it. They failed to crack Themida but I had a look at it and it seems too troublesome for the end user. Many AV programs recognize it as a virus.
Mark, what’s your program look like? A single executable? Many DLL files? Some of them not yours?
As a user of SmartAssembly for the last year and a half, I have to agree with your article… It’s a really great product, and it works as advertised. The only thing I take exception to is this statement:
> It doesn’t offer much control to the end user with regards exactly what gets obfuscated and what doesn’t, which obfuscation techniques are used and where they’re employed, but the end result is just great.
Actually, you can drill into the advanced dialogs for code pruning, obfuscation, etc and specifically tag classes or exclude your classes within an assembly. I rarely do this however, and choose instead to use the SmartAssembly.Attributes to decorate my classes/methods when special treatment is required.
For example, I’ve noticed that if you are a fan of Reflection in your code, and you obfuscate the code, you can kiss your reflective invoke’s goodbye. I usually decorate any methods called via reflection as [DoNotPrune, DoNotObfuscate], which works perfectly. Also, you may need to do some custom decoration if you are using the Windows Presentation Foundation (WPF) and XAML. Another interesting note is that BAML (the compiled version of XAML) is not obfuscated…
Anyway, great article, and it’s a great product…
š Geo…
Well said, finally a good report on this stuff
That’s strange, but I’ll agree with Harley, mentioned 3 years ago – SA is not so good for 9 of 10. I moved from SA to Spices.Net Obfuscator just because my app was hacked. BTW – SA is also hacked and available on the Internet, instead of Spices.Net (let’s say that shows how is program protects itself). I’m very satisfied with their product, especially with really working TamperProof technology that makes assemblies tamper resistant. I think that is a “must have” thing of good protection.
Take a look at Crypto Obfuscator – http://www.ssware.com/cryptoobfuscator/obfuscator-net.htm
A unique feature of Crypto Obfuscator is the Warnings tab shown after obfuscation. This lists all lines of code in your assemblies which can potentially cause the obfuscated assembly to fail. With other obfuscators, its like shooting in the dark trying to figure out why obfuscated assemblies are not working.
It also has a lot of intelligent auto-exclusion rules which exclude classes/members from renaming if it determines that renaming will cause the obfuscated assembly to fail.