📜 ⬆️ ⬇️

Cloud protection for .NET applications

just a little cloud
Perhaps software protection has always been one of my favorite topics. I loved to invent complex, ingenious checks of the licensing of the program, and enthusiastically implemented them. I have always adhered to the principle that a hacker, in order to crack the protection, must learn the maximum of the technologies used in the program. Let him think about the synchronization of threads, if he wanted to bang in the key verification algorithm. Let him study the issues of counting COM links if he wants to interfere with my algorithm. Let him think about how bitmap maps of images are represented in memory, if he decided to figure out how I saved the key data.

Yes, C ++ was an almost perfect language in this regard. But times change, old technologies disappear and new ones become more productive and comfortable. So our team switched to .NET. But in exchange for the simplicity of development and convenience of debugging, we also received additional software and decompilation of our software. Now, a hacker could not just circumvent the licensing restrictions, but also get almost the full source of our program by simply feeding it to the reflector.
Of course, many different obfuscators were presented on the market as a solution to this problem. But, oddly enough, most of them disappointed me from two sides at once: with pricing policies (even the minimal license of some exceeded the cost of our software several times), and the “intelligence” of the algorithm. So, after some obfuscators, even simple WinForms applications managed to fall. As for WPF, without a long, long black shamanism over excludes, it was impossible to launch a medium-sized program in principle.

Thus, an understanding of the problem and a clear desire to create a product that minimized the above problems were formed. And SaaS obfuscator and protector .NET code AppFuscator.com appeared
')
Obfuscator and protector .NET code appfuscator




Protection algorithms


Renaming

Obfuscation of classes and their members, with full support for Generics, inheritance, overloading of virtual methods, standard obfuscation attributes.
Various naming options are available: English letters, English letters with overload by type of parameters, non-printable characters and a number of others.

Assembly merging

Consolidation of several original protected assemblies into one final one, in order to complicate analysis and decompilation.
In the current version, assemblies that do not contain WPF resources should act as embedded assemblies.

Decomposition

The decomposition of the class structure into a procedural view is our own original development, based on the idea of ​​transferring a program from an object-oriented form (simple for reverse engineering) to a procedural style, with maximum destruction of all available information stored in metadata (but maintaining full functionality of the garbage collector) .
I'll tell you a little more. Suppose we have an assembly with the following class structure:

Obfuscator code

After performing the decomposition, we will see the following:
.NET obfuscator

The method that is highlighted in the screenshot is the former MainForm_Load - the form loading handler. Only now it, like the rest of the code, lies outside the class to which it belongs, in the global namespace (unlike C #, where any method must belong to a class, in IL it is admissible to declare normal global functions).

In the form itself (now it's class b), there is only one method left: Dispose. It is an overload of the virtual function, so we can not stand it.

As you can see, the complexity of reading increases significantly, and it will be very difficult for a hacker to figure out which method was related to earlier. At the same time, classes turn into empty wrappers containing only data fields (with lost types) and the remainder of virtual functions.

External Method Call Hiding

Hiding a call to external methods - the substitution of an explicit call to methods from external assemblies (including calls to the Common Language Runtime), to an implicit call by an unmanaged pointer.
A small example. It was:

public void ShowMessage(string text) { MessageBox.Show(text); } 


It became:
 // <Module> public static void a(object obj, string text) { object arg_0C_0 = calli(System.Int32(System.String), text, gb); } 


String encryption

String encryption based on a proprietary algorithm. For the categorical complication of life for potential developers of an automated decoder, dynamic variables are generated in the protected program, depending on the context.

Reflection analyzing

Analysis of calls to the mechanism of reflection - a set of algorithms that track calls to Reflection.
I always categorically did not like that after assembling the next version of the program, the next stage begins - dancing with a tambourine around the obfuscator. Therefore, our product provides an analyzer that is trained to automatically track communications and correct names in the program code. It has a fairly powerful logic for parsing complex structures and choosing the final solution. Of course, he will not be able to close all possible cases automatically, but it will make life easier for the developer.
Suppose we have two classes:

 class ClassA { string GetText() { return "A"; } public int smallField; } class ClassB { string GetText() { return "B"; } } 


Consider the following sample code:

 public void HabraTestFirst(int x) { Type work = null; string method = "gettext"; if (x == 0) work = typeof(ClassA); //  ClassA else { string name = "HabraCode.ClassB, HabraCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"; work = Type.GetType(name, true); //  ClassB } //      GetText HabraReflectionCall(work, method); } public void HabraReflectionCall(Type target, string method) { var call = target.GetMethod(method, BindingFlags.IgnoreCase | BindingFlags.NonPublic | BindingFlags.Instance); var obj = Activator.CreateInstance(target); call.Invoke(obj, null); MessageBox.Show(string.Format("HabraReflection call: {0}.{1}", obj.ToString(), call.Name)); } 


In this example, depending on the numeric parameter passed to the input, the method will be called either in the ClassA class or in ClassB. However, these classes have no connection with inheritance \ interfaces.

Compile a simple program:
 var reflector = new Reflector(); reflector.HabraTestFirst(0); reflector.HabraTestFirst(1); 


We launch and voila:
Obfuscation .NET Reflection

As you can see, both classes and both methods were renamed during obfuscation, but the program was able to identify the dependency between them, and updated the reference to the name in the Reflection call.
An even more interesting example in which we not only access Reflection, but also find the required field through the enumeration:

 public void HabraTestSecond() { FieldInfo result = null; var anyobj = new ClassA().GetType(); foreach (var it in anyobj.GetFields()) { if (it.Name == "smallField") //     smallField     result = it; } if (result == null) throw new InvalidOperationException(); MessageBox.Show("HabraReflection field: " + result.ToString()); } 


When you start the program will honestly tell us:
Reflection Alnalyzing module

How it works? Everything is simple - after seeing the characteristic construction - listing the fields received from Reflection, the analyzer was able to adapt and update the requested name in the IL code.
Of course, such an approach will not always work, if the construction is more multi-step or the name of the desired method is taken, for example, from an external file, then our intelligent analyzer will honestly admit defeat.

Source code can be downloaded here .

WPF Analyzing

Automatic exclusion from obfuscation of types, methods and fields accessed from the Windows Presentation Foundation. The program performs decompilation and analysis of compiled XAML resources in assemblies. Fully supports WPF syntax extensions, including complex constructs (for example, PropertyPath and others).
Because of this, in a program written in WPF, only that which should be renamed will be renamed.

A typical example of a program after obfuscation:
The result of obfuscation .NET applications
(click to enlarge)

Why SaaS?



It's simple - instead of buying a good box obfuscator for a few thousand dollars, and then constantly paying for the purchase of its updates (after all, the .NET platform technologies are developing very quickly), you get access to the online obfuscation service. And after that, pay only for the amount of work that you personally need. Release the version once a month - pay only for it.
Pricing is now at the stage of formation, but I can confidently say that the conditions will be delicious. In addition, a free version will be available, the functionality of which exceeds all free obfuscators presented at the moment.

It's safe?


We take the protection of your data very seriously.

First and foremost: you do not need to send the source code of the programs to the server. You send only compiled assemblies already, in exactly the same way as your users (and perhaps not only users) would see them, if you had not dealt with the issue of protection and did not obfuscate them. No other information is required.
The whole process of obfuscation is performed on dedicated servers, access to which only a few people from our team have access to. Of course, we use the latest software and make regular updates. In addition, the obfuscation module and the web frontend for user interaction are physically placed on separate servers, which increases the security and scalability of the system.

We are a legal entity and are ready to provide all the necessary documents, such as an agreement to use our service and NDA.

Now the service is launched in beta mode, and you can test all the functionality absolutely free.

Source: https://habr.com/ru/post/150127/


All Articles