29.3. Obfuscating Your Code

So far, this chapter has highlighted the need for better protection for the logic that is embedded in your applications. Obfuscation is the art of renaming symbols in an assembly so that the logic is unintelligible and can't be easily understood if decompiled. Numerous products can obfuscate your code, each using its own tricks to make the output less likely to be understood. Visual Studio 2008 ships with the Community edition of Dotfuscator, which this chapter uses as an example of how you can apply obfuscation to your code.

Obfuscation does not prevent your code from being decompiled; it simply makes it more difficult for a programmer to understand the source code if it is decompiled. Using obfuscation also has some consequences that need to be considered if you need to use reflection or strong-name your application.

29.3.1. Dotfuscator

Although Dotfuscator can be launched from the Tools menu within Visual Studio 2008, it is a separate product with its own licensing. The Community edition contains only a subset of the functionality of the Standard and Professional versions of the product. If you are serious about trying to hide the functionality embedded in your application, you should consider upgrading.

After starting Dotfuscator from the Tools menu, it prompts you to either create a new project or use an existing one. Because Dotfuscator uses its own project format, create a new project that will be used to track which assemblies you are obfuscating and any options that you specify. Into the blank project, add the .NET assemblies that you want to obfuscate. Unlike other build activities that are typically executed based on source files, obfuscating takes existing assemblies, applies the obfuscation algorithms, and generates a set of new assemblies. Figure 29-4 shows a new Dotfuscator project into which has been added the assembly for the ObfuscationSample application.

Figure 29.4. Figure 29-4

Without needing to adjust any other settings, you can select Build from the File menu, or click the "play" Button (fourth from the left) on the Toolbar, to obfuscate this application. The obfuscated assemblies will typically be added to a Dotfuscated folder. If you open this assembly using Reflector, as shown in Figure 29-5, you will notice that the GenerateMagicNumber method has been renamed, along with the input parameters. In addition, the namespace hierarchy has been removed and classes have been renamed. Although this is a rather simple example, you can see how numerous methods with the same, or similar, non-intuitive names could cause confusion and make the source code very difficult to understand when decompiled.

Figure 29.5. Figure 29-5

Unfortunately, this example obfuscated a public method. If you were to reference this assembly in another application, you would see a list of classes that have no apparent structure, relationship, or even naming convention. This would make working with this assembly very difficult. Luckily, Dotfuscator enables you to control what is renamed. Before going ahead, you will need to refactor the code slightly to pull the functionality out of the public method. If you didn't do this and you excluded this method from being renamed, your secret algorithm would not be obfuscated. By separating the logic into another method, you can obfuscate that while keeping the public interface. The refactored code would look like the following:

namespace ObfuscationSample
{
    public class MathematicalGenius
    {
        public static Int32 GenerateMagicNumber(Int32 age, Int32 height)
        {
            return CalculateMagicNumber(age, height);
        }

        private static int32 CalculateMagicNumber(Int32 age, Int32 height)
        {
            return age * height;
        }
    }
}

After rebuilding the application and refreshing the Dotfuscator project (because there is no Refresh button, you need to reopen the project by selecting it from the Recent Projects list), the Rename tab will look like the one shown in Figure 29-6.

Figure 29.6. Figure 29-6

In the left pane you can see the familiar tree view of your assembly, with the attributes, namespaces, types, and methods listed. As the name of the tab suggests, this tree enables you to exclude symbols from being renamed. In Figure 29-6, the GenerateMagicNumber method, as well as the class that it is contained in, is excluded (otherwise, you would have ended up with something like b. GenerateMagicNumber, where b is the renamed class). As you can see in Figure 29-6, within the Rename tab there are two sub-tabs; Exclude and Options. On the Options sub-tab you will need to check the Keep Namespace checkbox. When you build the Dotfuscator project and look in the Output tab, you will see that the MathematicalGenius class and the GenerateMagicNumber method have not been renamed, as shown in Figure 29-7.

Figure 29.7. Figure 29-7

The CalculateMagicNumber method has been renamed to a, as indicated by the sub-node with the Dotfuscator icon.

29.3.2. Words of Caution

There are a couple of places where it is worth considering what will happen when obfuscation occurs, and how it will affect the workings of the application.

29.3.2.1. Reflection

The .NET Framework provides a rich reflection model through which types can be queried and instantiated dynamically. Unfortunately, some of the reflection methods use string lookups for type and method names. Clearly, the use of obfuscation will prevent these methods from working, and the only solution is not to mangle any symbols that may be invoked using reflection. Dotfuscator will attempt to determine a limited set of symbols to exclude based on how the reflection objects are used. For example, let's say that you dynamically create an object based on the name of the class, and you then cast that object to a variable that matches an interface the class implements. In that case, Dotfuscator would be able to limit the excluded symbols to include only types that implemented that interface.

29.3.2.2. Strongly Named Assemblies

One of the purposes behind giving an assembly a strong name is that it prevents the assembly from being tampered with. Unfortunately, obfuscating relies on being able to take an existing assembly and mangle the names and code flow, before generating a new assembly. This would mean that the assembly is no longer strongly named. To allow obfuscation to occur you need to delay signing of your assembly by checking the "Delay sign only" checkbox on the Signing tab of the Project Properties window, as shown in Figure 29-8.

Figure 29.8. Figure 29-8

After building the assembly, you can then obfuscate it in the normal way. The only difference is that after obfuscating you need to sign the obfuscated assembly, which can be done manually using the Strong Name utility, as shown in this example:

sn -R ObfuscationSample.dll ObfuscationKey.snk

The Strong Name utility is not included in the default path, so you will either need to run this from a Visual Studio 2008 Command Prompt (Start All Programs Microsoft Visual Studio 2008 Visual Studio Tools), or enter the full path to sn.exe.

29.3.2.3. Debugging with Delayed Signing

According to the Project Properties window, checking the "Delay sign only" box will prevent the application from being able to be run or debugged. This is because the assembly will fail the strong-name verification process. To enable debugging for an application with delayed signing, you can register the appropriate assemblies for verification skipping. This is also done using the Strong Name utility. For example, the following code will skip verification for the MyApplication.exe application:

sn -Vr MyApplication.exe

Similarly, the following will reactivate verification for this application:

sn -Vu MyApplication.exe

This is a pain for you to have to do every time you build an application, so you can add the following lines to the post-build events for the application:

"$(DevEnvDir)....SDKv2.0Binsn.exe" -Vr "$(TargetPath)"
"$(DevEnvDir)....SDKv2.0Binsn.exe" -Vr
   "$(TargetDir)$(TargetName).vshost$(TargetExt)"

The first line skips verification for the compiled application. However, Visual Studio 2008 uses an additional vshost file to bootstrap the application when it executes. This also needs to be registered to skip verification.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.198.59