饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 137 页

作者:Nick Randolph/等 当前章节:15387 字 更新时间:2026-6-18 14:51

Return (age * height) + Today.DayOfWeek

Decompilers .

939

End Function

End Class

End Namespace

Double-clicking the GenerateMagicNumber method in IL Dasm opens up an additional window

that shows the IL for that method. Figure 47-2 shows the IL for the GenerateMagicNumber method,

which represents your super-secret, patent-pending algorithm. In actual fact, anyone who is prepared

to spend a couple of hours learning how to interpret MSIL could quickly work out that the method

simply multiplies the two int32 parameters, age and height, and then adds the current day of the

year to the result.

fiGure 47-2

For those who haven’t spent any time understanding how to read MSIL, a decompiler can convert

this IL back into one or more .NET languages.

decoMPilers

One of the most widely used decompilers is .NET Reflector from Red Gate Software (available for

download at www.red-gate.com/products/reflector/). Reflector can be used to decompile any

.NET assembly into C#, Visual Basic, Managed C11, and even Delphi. In Figure 47-3, the same

assembly you just accessed is opened using IL Dasm, in Reflector.

940 .

chaPter 47 obFuScATion, ApplicATion moniToring, And mAnAgemenT

fiGure 47-3

In the pane on the left of Figure 47 - 3, you can see the namespaces, type, and method information in a

layout similar to IL Dasm. Double - clicking a method should open the Disassembler pane on the right,

which displays the contents of that method in the language specifi ed in the toolbar. In this case, you

can see the C# code that generates the magic number, which is almost identical to the original code.

You may have noticed in Figure 47-3 that some of the .NET Framework base class

library assemblies are listed, including System, System.Data, and System.Web.

Because obfuscation has not been applied to these assemblies, they can be

decompiled just as easily using Reflector. However, Microsoft has made large

portions of the actual .NET Framework source code publicly available, which

means you can browse the original source code of these assemblies including the

inline comments. This is shown in Chapter 43.

If the generation of the magic number were a real secret on which your organization made

money, the ability to decompile this application would pose a significant risk. This is made worse

when you add the Reflector.FileDisassembler add-in, written by Denis Bauer (available at

www.denisbauer.com/NETTools/FileDisassembler.aspx ). With this add - in, an entire assembly

can be decompiled into source fi les, complete with a project fi le.

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 and modifying code paths 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 2010 ships with the Community Edition of Dotfuscator Software

Services from PreEmptive Solutions, 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 diffi cult 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 refl ection or strong - name your application.

dotfuscator software services

Although Dotfuscator can be launched from the Tools menu within Visual Studio 2010, it is a

separate product with its own licensing. The Community Edition (CE) contains only a subset of

the functionality of the commercial edition of the product, the Dotfuscator Suite. If you are serious

about trying to hide the functionality embedded in your application, you should consider upgrading.

You can fi nd more information on the commercial version of Dotfuscator at www.preemptive.

com/products/dotfuscator/compare - editions .

Dotfuscator CE uses its own project format to keep track of which assemblies you are obfuscating

and any options that you specify. After starting Dotfuscator from the Tools menu, it opens with

a new unsaved project. Select the Input Assemblies node in the navigation tree, and then click the

button with an ellipsis (...) under the Assembly Name listing to add the .NET assemblies that you

want to obfuscate. Figure 47 - 4 shows a new Dotfuscator project into which has been added the

assembly for the application from earlier in this chapter.

Unlike other build activities that are typically executed based on source fi les,

obfuscation is a post - build activity that works with an already compiled set

of assemblies. Dotfuscator takes an existing set of assemblies, applies the

obfuscation algorithms to the IL, and generates a set of new assemblies.

obfuscating Your Code . 941

942 .

chaPter 47 obFuScATion, ApplicATion moniToring, And mAnAgemenT

fiGure 47-4

Without needing to adjust any other settings, you can select Build Project from the Build menu, or click

the “play” button (fourth from the left) on the toolbar, to obfuscate this application. If you have saved the

Dotfuscator project, the obfuscated assemblies will be added to a Dotfuscated folder under the folder

where the project was saved. If the project has not been saved, the output is written to c:\Dotfuscated.

If you open the generated assembly using Reflector, as shown in Figure 47-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 similar, non-intuitive names could cause

confusion and make the source code very difficult to understand when decompiled.

fiGure 47-5

obfuscating Your Code .

943

The free version of Dotfuscator only obfuscates assemblies by renaming classes,

variables, and functions. The commercial version employs several additional

methods to obfuscate assemblies, such as modifying the control flow of the

assembly and performing string encryption. In many cases, control flow will

actually trigger an unrecoverable exception inside decompilers, effectively

preventing automated decompilation.

The previous example obfuscated the public method of a class, which is fine if the method will only

be called from assemblies obfuscated along with the one containing the class definition. However,

if this was a class library or API that will be referenced by other, unobfuscated applications, 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 during obfuscation. 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 unchanged.

The refactored code would look like the following:

c#

namespace ObfuscationSample

{

public class MathematicalGenius

{

public static Int32 GenerateMagicNumber(Int32 age, Int32 height)

{

return SecretGenerateMagicNumber(age, height);

}

private static Int32 SecretGenerateMagicNumber(Int32 age, Int32 height)

{

return (age * height) + DateTime.Now.DayOfYear;

}

}

}

Code Snippet MathematicalGenius.cs

Vb

Namespace ObfuscationSample

Public Class MathematicalGenius

Public Shared Function GenerateMagicNumber(ByVal age As Integer, _

ByVal height As Integer) As Integer

Return SecretGenerateMagicNumber(age, height)

End Function

Private Shared Function SecretGenerateMagicNumber(ByVal age As Integer, _

944 .

chaPter 47 obFuScATion, ApplicATion moniToring, And mAnAgemenT

ByVal height As Integer) As Integer

Return (age * height) + Today.DayOfWeek

End Function

End Class

End Namespace

Code Snippet MathematicalGenius.vb

After rebuilding the application, you will need to reopen the Dotfuscator project by selecting it from the

Recent Projects list. You have several different ways of selectively applying obfuscation to an assembly.

First, you can enable Library mode on specific assemblies by selecting the appropriate checkbox on the

Input Assemblies screen (see Figure 47-4). This has the effect of keeping the namespace, class name,

and all public properties and methods intact, while renaming all private methods and variables. Second,

you can manually select which elements should not be renamed from within Dotfuscator. To do this,

open the Renaming item from the navigation tree, shown in Figure 47-6.

fiGure 47-6

The Renaming dialog opens on the Exclusions tab where 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 certain elements from being renamed. In Figure 47-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). In addition to explicitly choosing which elements will be excluded, you can also define custom

rules that can include regular expressions.

After you build the Dotfuscator project, click the Results item in the navigation tree. This screen

shows the actions that Dotfuscator performed during obfuscation. The new name of each class,

property, and method is displayed as a sub-node under each renamed element in the tree. You will see

that the MathematicalGenius class and the GenerateMagicNumber method have not been renamed,

as shown in Figure 47-7.

Prepared for SUSAN ROERS/ email0 Susan_Krentz@aol.com Order number0 64627890 This PDF is for the purchaser’s personal use in accordance with the Wrox Terms of

Service and under US copyright as stated on this book’s copyright page. If you did not purchase this copy/ please visit www.wrox.com to purchase your own copy.

obfuscating Your Code .

945

fiGure 47-7

The SecretGenerateMagicNumber method has been renamed to a, as indicated by the sub-node

with the Dotfuscator icon.

obfuscation attributes

In the previous example you saw how to choose which types and methods to obfuscate within

Dotfuscator. Of course, if you were to start using a different obfuscating product you would have to

configure it to exclude the public members. It would be more convenient to be able to annotate your

code with attributes indicating whether a symbol should be obfuscated. You can do this by using

the Obfuscation and ObfuscationAssemblyAttribute attributes from the System.Reflection

namespace.

The default behavior in Dotfuscator is to override exclusions specified in the project with the

settings specified by any obfuscation attributes. In Figure 47-4 is a series of checkboxes for each

assembly added to the project, of which one is Honor Obfuscation Attributes. You can change the

default behavior so that any exclusions set within the project take precedence by unchecking

the Honor Obfuscation Attributes option on a per-assembly basis.

obfuscationassemblyattribute

The ObfuscationAssemblyAttribute attribute can be applied to an assembly to control whether

it should be treated as a class library or as a private assembly. The distinction is that with a class

library it is expected that other assemblies will be referencing the public types and methods

it exposes. As such, the obfuscation tool needs to ensure that these symbols are not renamed.

946 .

chaPter 47 obFuScATion, ApplicATion moniToring, And mAnAgemenT

Alternatively, as a private assembly, every symbol can be potentially renamed. The following is the

syntax for ObfuscationAssemblyAttribute:

c#

[assembly: ObfuscateAssemblyAttribute(false, StripAfterObfuscation=true)]

Vb

<Assembly: ObfuscateAssemblyAttribute(False, StripAfterObfuscation:=True)>

The two arguments that this attribute takes indicate whether it is a private assembly and whether

to strip the attribute off after obfuscation. The preceding snippet indicates that this is not a private

assembly, and that public symbols should not be renamed. In addition, the snippet indicates that

the obfuscation attribute should be stripped off after obfuscation — after all, the less information

available to anyone wishing to decompile the assembly, the better.

Adding this attribute to the AssemblyInfo.cs or AssemblyInfo.vb file will automatically preserve

the names of all public symbols in the ObfuscationSample application. This means that you can

remove the exclusion you created earlier for the GenerateMagicNumber method.

obfuscationattribute

The downside of the ObfuscationAssemblyAttribute attribute is that it exposes all the public

types and methods regardless of whether they existed for internal use only. On the other hand, the

ObfuscationAttribute attribute can be applied to individual types and methods, so it provides a

much finer level of control over what is obfuscated. To illustrate the use of this attribute, refactor the

example to include an additional public method, EvaluatePerson, and place the logic into another

class, HiddenGenius:

c#

namespace ObfuscationSample

{

[System.Reflection.ObfuscationAttribute(ApplyToMembers=true, Exclude=true)]

public class MathematicalGenius

{

public static Int32 GenerateMagicNumber(Int32 age, Int32 height)

{

return HiddenGenius.GenerateMagicNumber(age, height);

}

public static Boolean EvaluatePerson(Int32 age, Int32 height)

{

return HiddenGenius.EvaluatePerson(age, height);

}

}

[System.Reflection.ObfuscationAttribute(ApplyToMembers=false, Exclude=true)]

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页