Assemblies compiled using the .NET framework contain MSIL (Microsoft Intermediate Language) instructions that are executed by the .NET runtime just-in-time compiler when your application is run on the user machine. The just-in-time compiler converts the MSIL instruction to native machine instructions which are then processed by the machine. The MSIL instructions, together with class, methods, fields and other metadata information available inside a compiled assembly makes it possible for tools like .NET reflector, dotPeek and JustDecompile to translate the code back to its source language (C#, VB or any other .NET language).
Symbol renaming doesn't modify the MSIL instructions at all, it only changes the names of classes and methods but leaves the MSIL instructions untouched.
Code Encryption protects the MSIL code, but since the code has to be transformed back to MSIL before the just-in-time compiler can process the method theoretically it should be possible to retrieve the original MSIL code instructions. In practice Agile.net adds additional protection to frustrate hackers attempting to capture the decrypted assembly.
Code virtualization takes a different approach towards MSIL code protection as it never processes the original MSIL code directly. Code virtualization will convert your MSIL code into virtual opcodes that will only be understood by a unique virtual machine. Virtual opcodes are opcodes forming a unique language which Agile.net especially synthesizes for selected methods. Each method selected for virtualization will produce different set of virtual opcodes and a unique virtual machine that can process them. As opposed to protecting MSIL code through encryption where the encrypted code must be decrypted back into MSIL before it can be executed by the CLR, a unique virtual machine directly processes the protected code in the form of a virtual machine language. Code virtualization strength derives from the fact that it applies a one-way transformation on the MSIL code. This important property makes it ideal for protecting your software against unauthorized distribution.
When selecting method to apply code virtualization on, choose those classes and methods that have a high intellectual property component, or that are particularly vulnerable to hacking or reverse-engineering. These include the following:
There are certain scenarios where the performance of a protected application is
slower than the unprotected versions. This is usually the result of applying protection
to methods containing iterations of complex calculations.
For example, executing a math operation on every pixel of a bitmap graphic as part of an image processing application would negatively affect performance. To work around this limitation, we recommend applying protection to methods that are not computationally intensive. In cases where you want to control access to a computationally intensive method, you can protect 'gateway' methods - that is you protect the non-computationally intensive methods that call the computationally intensive methods.
Consider a scenario where you are applying protection to an image processing application. You have implemented an algorithm that sharpens the image to enhance the clarity of captured images. To access this feature, users click Sharpen from a menu. The method that performs the work contains the iterated complex math. However, if you apply protection to the menu item, Sharpen, you can control the use of the feature without having to protect the computationally intense sharpen method.
There are certain code protection scenarios where code virtualization can not be applied: