Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional Visual Studio 2005 (2006) [eng]

.pdf
Скачиваний:
117
Добавлен:
16.08.2013
Размер:
21.9 Mб
Скачать

Chapter 17

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 ObfuscatingSample.exe ObfuscatingKey.pfx

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 ObfuscatingSample application:

sn -Vr ObfuscatingSample.exe

Similarly, the following will reactivate verification for this application:

sn -Vu ObfuscatingSample.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)..\..\SDK\v2.0\Bin\sn.exe” -Vr “$(TargetPath)” “$(DevEnvDir)..\..\SDK\v2.0\Bin\sn.exe” -Vr “$(TargetDir)$(TargetName).vshost$(TargetExt)”

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

Where Did Those Attributes Go?

In the previous version of the .NET Framework, to sign an assembly you had to specify the appropriate attribute within the assemblyinfo file:

<Assembly: AssemblyKeyFile(“MyKey.snk”)>

<Assembly: AssemblyDelaySign(True)>

Because the location of the key was hard-coded into the assembly, it could be a security vulnerability; in addition, it could be difficult to configure, as the name had to match the physical location of the key. In Visual Studio 2005, the signing information specified in Figure 17-8 is included in the project file, as shown in the following code (this makes more sense than using attributes, as the signing process is just another part of the build process):

<?xml version=”1.0” encoding=”utf-8”?> <Project DefaultTargets=”Build”

xmlns=”http://schemas.microsoft.com/developer/msbuild/2003”>

<PropertyGroup>

<AssemblyName>ObfuscationSample</AssemblyName>

...

226

Obfuscation

<SignAssembly>true</SignAssembly>

<AssemblyOriginatorKeyFile>ObfuscatingKey.pfx</AssemblyOriginatorKeyFile>

<DelaySign>true</DelaySign>

</PropertyGroup>

...

</Project>

As you can see from this code snippet, taken from the project file, both the attributes associated with signing the assembly are contained in the initial property group for the assembly being created. MSBuild uses this information to sign the assembly as part of the build process.

Attributes

In the previous example you saw how to choose which types and methods to obfuscate within Dotfuscator. Of course, if you were to move to an alternative 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 ObfuscationAssembly attributes.

The default behavior in Dotfuscator is to ignore the obfuscation attributes in favor of any exclusions specified in the project. In Figure 17-4 there are a series of checkboxes for each assembly added to the project, of which the top checkbox is Honor Obfuscation Attributes. A limitation with the Community edition is that you can’t control this feature for each assembly. You can apply this feature to all assemblies using the second button from the right on the toolbar.

ObfuscationAssembly

The ObfuscationAssembly 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. Alternatively, as a private assembly, every symbol can be potentially renamed.

<Assembly: Reflection.ObfuscateAssembly(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.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.

Within Dotfuscator you can specify that you want to run all assemblies in library mode. Enabling this option has the same effect as applying this attribute to the assembly.

227

Chapter 17

Obfuscation

The downside of the ObfuscationAssembly attribute is that it will expose all the public types and methods regardless of whether they existed for internal use only. The Obfuscation 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, extend the example to include an additional public method, EvaluatePerson, and place the logic into another class, HiddenGenius:

Namespace SourceLibrary

<Reflection.Obfuscation(applytomembers:=True, exclude:=True)> _

Public Class MathematicalGenius

Public Shared Function GenerateMagicNumber _

(ByVal age As Integer, ByVal height As Integer) As Integer

Return HiddenGenius.MultiplyAgeAndHeight(age, height)

End Function

Public Shared Function EvaluatePerson _

(ByVal age As Integer, ByVal height As Integer) As Boolean

Return HiddenGenius.QualifyPerson(age, height)

End Function

End Class

<Reflection.Obfuscation(applytomembers:=False, exclude:=True)> _ Public Class HiddenGenius

Public Shared Function MultiplyAgeAndHeight _

(ByVal age As Integer, ByVal height As Integer) As Integer Return age * height

End Function

<Reflection.Obfuscation(Exclude:=True)> _ Public Shared Function QualifyPerson _

(ByVal age As Integer, ByVal height As Integer) As Boolean Return (age / height) > 3

End Function End Class

End Namespace

In this example, the MathematicalGenius class is the class that you want to expose outside of this library. As such, you want to exclude this class and all its methods from being obfuscated. This is done by applying the Obfuscation attribute with both the Exclude and ApplyToMembers parameters set to

True.

The second class, HiddenGenius, is a hybrid class. As a result of some squabbling among the developers who wrote this class, the QualifyPerson method needs to be exposed, but all other methods in this class should be obfuscated. Again, the Obfuscation attribute is applied to the class so that the class does not get obfuscated. However, this time you want the default behavior to be such that symbols contained in the class are obfuscated, so the ApplyToMembers parameter is set to False. In addition, the Obfuscation attribute is applied to the QualityPerson method so that it will still be accessible.

228

Obfuscation

Summar y

In addition to learning about how to use obfuscation to protect your embedded application logic, this chapter reviewed two tools, IL Dasm and Reflector, which enable you to analyze and learn from what other developers have written. Although reusing code written by others without licensing their work is not condoned behavior, these tools can be used to learn techniques from other developers.

229

Part V

Coding

Chapter 18: IntelliSense

Chapter 19: Code Snippets

Chapter 20: Regions and Bookmarks

Chapter 21: Refactoring

Chapter 22: Generics, Nullable Types, and Partial Types

Chapter 23: Language-Specific Features

Chapter 24: The My Namespace

IntelliSense

One thing that Microsoft has long been good at is providing automated help as you write your code. Older versions of Visual Basic had a limited subset of this automated intelligence known as IntelliSense, but with the introduction of Visual Studio .NET, Microsoft firmly pushed the technology throughout the whole application development environment. With Visual Studio 2005, IntelliSense is even more pervasive than ever before, but you can also control it more than you could previously.

This chapter illustrates the many ways in which IntelliSense helps you write your code. Code snippets, using XML commenting in your own projects to create more IntelliSense information, and other features as simple as variable name completion are all covered.

IntelliSense Explained

IntelliSense is the general term for automated help and actions when you’re using an application. The most commonly encountered IntelliSense is those wavy lines you see under words that are not spelled correctly in Microsoft Word, or small visual indicators in a Microsoft Excel spreadsheet to inform you that the contents of the particular cell do not conform to what was expected.

Even these basic visual feedback indicators provide you with a quick way of performing related actions. Right-clicking a word with red wavy underlining in Word will display a list of suggested words that you may have intended, and other applications work the same way.

This is just the tip of the IntelliSense iceberg. In more recent versions of Microsoft Office, advanced IntelliSense features include smart tag technology, which marks up recognized words and terms with additional indicators that you can then use to access appropriate actions, such as automatically adding an address into your Outlook Contacts folder from a recognized phrase in Word.

The good news is that Visual Studio has had similar functionality for a long time. In fact, the simplest IntelliSense features go back to tools such as Visual Basic 6. The even better news is that

Chapter 18

Visual Studio 2005 has IntelliSense on overdrive, with many different features grouped under the IntelliSense banner. From visual feedback for bad code, smart tags while designing forms, to shortcuts that insert whole slabs of code, IntelliSense in Visual Studio 2005 provides greatly enhanced opportunities to improve your efficiency while creating applications.

General IntelliSense

The simplest feature of IntelliSense gives you immediate feedback about bad code in your module listings. Figure 18-1 shows one such example whereby an unknown data type is used to instantiate an object and then a second line of code tries to set a property. Because the data type is unknown in the context in which this code appears, Visual Studio draws a blue wavy line underneath it to indicate a problem.

The formatting of this color feedback can be adjusted in the Fonts and Colors group of Options.

Hovering the mouse pointer over the offending piece of code displays a tooltip to explain the problem. In this example, the cursor was placed over the data type with the resulting tooltip “Type ‘PedoBear’ is not defined.” The second line of code also has an error because the enumeration is not present in this code context.

Figure 18-1

Visual Studio is able to look for this kind of error by continually precompiling the code you write in the background, looking for anything that will produce a compilation error. If you were to add a reference to the class containing the PedoBear definition, Visual Studio would automatically process this and remove the IntelliSense marker.

Figure 18-1 also displays a smart tag associated with the first error. This is a new feature for Visual Studio 2005 and applies only to errors for which the IDE can easily give you corrective actions. At the end of the problem code, a small yellow marker is displayed. Placing the mouse pointer over this marker will display the smart tag action menu associated with the type of error — in this case, it’s an Error Correction Options list, which when activated will provide a list of possible data types that you meant to use instead of what’s present.

The smart tag technology found in Visual Studio is not solely reserved for the code window. In fact, Visual Studio 2005 is the first Microsoft development tool to also include smart tags on visual components when you’re editing a form or user control in Design view (see Figure 18-2).

When you select a control that has a smart tag, a small triangle will appear at the top-right corner of the control itself. Click this button to open the smart tag Tasks list — Figure 18-2 shows the Tasks list for a standard TextBox control.

234

IntelliSense

Figure 18-2

Completing Words and Phrases

The power of the IntelliSense in Visual Studio 2005 becomes apparent as you start creating your code. As you type, various drop-down lists are displayed to help you choose valid members, functions, and parameter types, thus reducing the number of potential compilation errors before you even finish writing your code.

List Members

The most common version of this feature is the member list. When you type the name of an object and then immediately follow it by a period (.) to indicate that you are going to refer to one of its members, Visual Studio will automatically display a list of members available to you for that object (see Figure 18-3). If this is the first time you’ve accessed the member list for a particular object, Visual Studio will highlight a default property or function, but if you’ve used it before, it will highlight the last member you accessed to shortcut the process for repetitive coding tasks.

Figure 18-3 also shows another helpful aspect of the member list for Visual Basic programmers. The Common and All tabs (at the bottom of the member list) enable you to view either just the commonly used members or a comprehensive list.

Figure 18-3

235