Dotfuscator による保護を構成するには、アプリケーションのソース コードに .NET 属性を付けます。 ただし、Dotfuscator では、保護を構成するようにソースを編集する必要はありません。 また、ソースから独立して Dotfuscator による保護を構成するには、Dotfuscator 構成ファイルを使用します。
Dotfuscator は、アセンブリを処理するときに特定の属性を認識します。それらの属性は、それが付けられたコード要素を処理する方法を Dotfuscator に指示します。 既定では、Dotfuscator はアセンブリの処理中にこれらの属性の除去も行い、出荷されるアプリケーションに重要な構成情報が含まれないようにしています。
Dotfuscator の属性のリファレンスについては、難読化属性およびチェック属性を参照してください。
互換性のある属性
Dotfuscator は、特定の属性のみを認識し、他の属性を無視します。 Dotfuscator によって認識される属性は次のとおりです。
各属性のセットの詳細については、リンク先ページを参照してください。 このページの残り部分では、多くの属性に共通する側面について説明します。
属性を使用するタイミング
属性を使用することで、ソース コードを読む際に、Dotfuscator がコード要素にどのように作用するかがわかりやすくなります。 たとえば、次の C# のスニペットは、ObfuscationAttribute
を使用して、クラス(そのメンバーではなく)を名前の変更対象から除外することを示しています。
using System.Reflection;
[Obfuscation(Feature = "renaming", Exclude = true, ApplyToMembers = false)]
private class MyClass { /* ...*/ }
しかし、属性を使用するより、Dotfuscator 構成エディターを使用して Dotfuscator 構成ファイルを変更する方が、より良く実現できる場合もいくつかあります。 次のようなシナリオが挙げられます。
- ソース コードを編集できないアセンブリを使用する場合
- 保護設定を変更するたびにコードを再コンパイルするのが、開発プロセスのオーバーヘッドとしては大きすぎる場合
- 規則を使用してコード項目を特定の保護機能の対象として除外または選択した方が、個々のコード項目に属性でアノテーションを付けるより簡単または効率的な場合
- 複数の場所を対象とするチェックを構成する場合
属性と Dotfuscator 構成ファイルの設定を組み合わせることができます。 たとえば、上記のスニペットは、名前の変更対象から MyClass
を除外することを Dotfuscator に指示していますが、Dotfuscator 構成エディターを使用して他の型を除外し、それらの対象除外を構成ファイルに保存しておくことができます。 Dotfuscator は、構成ファイルを使ってアセンブリを処理する際、属性または構成ファイルによって除外されているコード項目の名前を変更しません。
コードへの属性の追加
コードに属性を追加し、それらの属性を Dotfuscator に認識させるには
-
プロジェクトに適切な参照を追加します。 詳細については、以下を参照してください。
-
コードに互換性のある属性を適用します。適用方法は通常の属性の場合と同様です。
-
名前空間(このため、必要な
using
ステートメント)は、属性によって異なります。 詳細については、各属性のセクションを参照してください。 -
他の属性と同様に、使用する際にはサフィックス
Attribute
を省略できます。 たとえば、次はTamperCheckAttribute
の使用例です。[TamperCheck(Action = CheckAction.Exit)] public void MyMethod() { // メソッド本体 }
-
-
アプリケーションをビルドします。
-
難読化属性を使用する場合は、Dotfuscator 構成エディターを使って以下の設定を構成します。
-
チェック属性を使用する場合は、Dotfuscator 構成エディターを使って以下の設定を構成します。
-
難読化属性が含まれるアセンブリごとに、[チェック属性の使用]オプションと[チェック属性の除去]オプションが有効になっていることを確認します。
-
チェックが有効になっていることを確認します。
-
-
プロジェクトを保存します。それによって、通常どおり Dotfuscator がアプリケーションを保護します。 たとえば、Dotfuscator が Visual Studio プロジェクトに組み込まれた場合、リリース構成のプロジェクトをビルドします。
アプリケーション コードとの対話
Dotfuscator によって差し込まれたコードが既存のアプリケーション コードと対話できるシナリオがいくつかあります。 差し込まれたコードに情報を提供するアプリケーション コードはソースと呼ばれ、差し込まれたコードから情報を受け取るアプリケーション コードはシンクと呼ばれます。
各チェックで、さまざまなコンテキストのために、1 つ以上のシンクと、1 つ以上のソースが定義できます。 チェックのソースとシンクは、次の 3 つのプロパティで定義されます。
-
element プロパティ。フィールドやメソッドなど、ソースまたはシンクとなるコード項目の種類を指定します。 詳細については、ソース要素の種類サブセクションとシンク要素の種類サブセクションを参照してください。
-
name プロパティ。コード項目の名前を指定します(該当する場合)。
-
省略可能な owner プロパティ。コード項目を定義する型を指定します(該当する場合)。 指定されていない場合は、チェックの場所を定義する型が既定値になります。 詳細については、オーナー サブセクションを参照してください。
たとえば、チェックが実行された場合、チェックはアプリケーション通知シンクを介して、結果をアプリケーションに通知できます。 シンクは、チェックの ApplicationNotificationSink プロパティを使って構成できます。
-
ApplicationNotificationSinkElement
-
ApplicationNotificationSinkName
-
ApplicationNotificationSinkOwner
特定のチェックに使用できるソースとシンクの詳細については、チェック属性ページの関連セクションに記載されています。
ソース要素の種類
ソースは、Dotfuscator によって差し込まれたコードに情報を提供するアプリケーション コード要素です。 このセクションでは、差し込まれたコードのソースとして使用できるコード要素の種類を列挙します。
サポートされている要素、要素の署名、ソースから取得される値の意味は、チェックによって異なることに留意してください。 詳細については、チェック属性ページを参照してください。
たとえば、ShelfLifeCheckAttribute
のトークン ソース には、string
型のメソッド引数、フィールド、またはプロパティか、あるいは string()
署名付きのメソッドを指定する必要があります。 文字列の値は、外部に保管された Shelf Life トークンです。
以下に、チェックの element プロパティ(たとえば、ShelfLifeCheckAttribute
の ShelfLifeTokenSourceElement)に使用可能な値を列挙します。 使用可能なソース要素の種類は以下のとおりです。
-
None:ソースは無効であり、アプリケーションは差し込まれたコードに情報を提供しません。
- name プロパティおよび owner プロパティは、この設定では無視されます。
-
MethodArgument:差し込まれたコードは、メソッド引数から情報をコピーします。 メソッド引数は、チェックのすべての場所に対応する引数である必要があります。
-
name プロパティには、メソッド引数の名前を指定します。
-
owner プロパティはこの設定では無視されます。
-
-
Field:差し込まれたコードは、フィールドから情報をコピーします。 このフィールドは、チェックのすべての場所からアクセス可能である必要があります。
-
name プロパティには、このフィールドの単純名を指定します。
-
owner プロパティには、このフィールドを宣言する型を指定します。
-
-
Property:差し込まれたコードは、プロパティから情報をコピーします。 このプロパティとその getter は、チェックのすべての場所からアクセス可能である必要があります。
-
name プロパティには、このプロパティの単純名を指定します。
-
owner プロパティには、このプロパティを宣言する型を指定します。
-
-
Method:差し込まれたコードは、情報を返すメソッドを呼び出します。 このメソッドは、チェックのすべての場所からアクセス可能である必要があります。
-
name プロパティには、このメソッドの単純名(例:
bool MyMethod()
でなくMyMethod
)を指定します。 -
owner プロパティには、このメソッドを宣言する型を指定します。
-
-
DefaultAction:差し込まれたコードは、いくつかの既定の情報を使用します。 正確な動作は、構成する特定のソースによって異なり、この設定を無効な構成としているものもあります。
-
これは、その名前に反して、必ずしも element プロパティの既定値ではありません。
-
name プロパティおよび owner プロパティは、この設定では無視されます。
-
シンク要素の種類
このセクションでは、差し込まれたコードのシンクとして使用できるコード要素の種類を列挙します。
サポートされている要素、要素の署名、シンクに提供される値の意味は、チェックによって異なることに留意してください。 詳細については、チェック属性ページを参照してください。
たとえば、チェックのアプリケーション通知シンクには、bool
型のフィールドまたはプロパティ、あるいは void(bool)
署名付きのメソッド、デリゲート フィールド、またはデリゲート メソッド引数を指定する必要があります。 ブール値は、チェックが不正な状態(デバッガーがアタッチされている、改ざんされている、など)を検出した場合は true
、検出されなかった場合は false
です。
以下に、チェックの element プロパティ(たとえば、改ざんチェックの ApplicationNotificationSinkElement)に使用可能な値を列挙します。 使用可能なシンク要素の種類は以下のとおりです。
-
None:シンクは無効であり、差し込まれたコードはアプリケーションに情報を提供しません。
-
通常、これが element プロパティの既定値です。
-
name プロパティおよび owner プロパティは、この設定では無視されます。
-
-
Method:差し込まれたコードはメソッドを呼び出し、そのメソッドのパラメーターを介して情報を提供します。 このメソッドは、チェックのすべての場所からアクセス可能である必要があります。
-
name プロパティには、このメソッドの単純名(例:
void MyMethod(bool)
でなくMyMethod
)を指定します。 -
owner プロパティには、このメソッドを宣言する型を指定します。
-
-
Field:差し込まれたコードは、フィールドを設定することによって情報を提供します。 このフィールドは、チェックのすべての場所からアクセス可能かつ設定可能である必要があります。
-
name プロパティには、このフィールドの単純名を指定します。
-
owner プロパティには、このフィールドを宣言する型を指定します。
-
-
Property:差し込まれたコードは、プロパティを設定することによって情報を提供します。 このプロパティとその setter は、チェックのすべての場所からアクセス可能である必要があります。
-
name プロパティには、このプロパティの単純名を指定します。
-
owner プロパティには、このプロパティを宣言する型を指定します。
-
-
MethodArgument:差し込まれたコードは、メソッド引数で指定されたデリゲートを呼び出し、そのデリゲートのパラメーターを介して情報を提供します。 メソッド引数は、チェックのすべての場所に対応する引数である必要があります。
-
name プロパティには、メソッド引数の名前を指定します。
-
owner プロパティはこの設定では無視されます。
-
-
Delegate:差し込まれたコードは、フィールドで指定されたデリゲートを呼び出し、そのデリゲートのパラメーターを介して情報を提供します。 このフィールドは、チェックのすべての場所からアクセス可能である必要があります。
-
name プロパティには、このフィールドの単純名を指定します。
-
owner プロパティには、このフィールドを宣言する型を指定します。
-
-
DefaultAction:差し込まれたコードは、情報に基づくいくつかの既定の動作を実行します。 正確な動作は、構成する特定のシンクによって異なり、この設定を無効な構成としているものもあります。
-
これは、その名前に反して、必ずしも element プロパティの既定値ではありません。
-
name プロパティおよび owner プロパティは、この設定では無視されます。
-
オーナー
ソースまたはシンクの owner は、そのソースまたはシンクを宣言する型です。
owner プロパティの値は、アセンブリ名ではなく名前空間を含めて表される型名です。 たとえば、名前空間 Outer.Inner
で宣言されたクラス MyType
のフィールド wasTampered
について考えてみましょう。 このフィールドにシンクを定義するプロパティは、以下のようになります。
-
element プロパティ:Field
-
name プロパティ:
wasTampered
-
owner プロパティ:
Outer.Inner.MyType
ソースまたはシンクには、オーナーのインスタンス メンバーまたは静的メンバーを使用できます。 この違いは、owner プロパティの使用方法に影響します。 また、複数の場所を持つチェックを使用する場合には、各場所に異なるオーナーを参照させることができます。
静的メンバーの場合
ソースまたはシンクが静的メンバーである場合は、ソース/シンクは、チェックのすべての場所からアクセス可能であれば、どのような型で定義されていてもかまいません。 これがどの型であるかを owner プロパティに指定します。 このプロパティの値が空白である場合は、チェックの場所を定義している型と見なされます。
インスタンス メンバーの場合
ソースまたはシンクがインスタンス メンバーである場合は、次の条件を満たしている必要があります。
-
チェックの場所もインスタンス メンバーである。
-
チェックの場所は、ソースまたはシンクを宣言した型と同じ型で定義されている。
-
owner プロパティは、この型の名前であるか、または空白である。
実行時、場所を呼び出す際に使用されたインスタンスが、ソースまたはシンクにも使用されます。
チェックの複数のオーナー
複数の場所を持つチェックを使用する場合、各場所は、ソースおよびシンクに関して個々に評価されます。 つまり、次の条件を満たしていれば、各場所が異なるソースまたはシンクを持つことができます。
-
チェックの場所を定義する各型に、ソースまたはシンクのメンバーが指定されている。
-
特定の場所が静的メンバーである場合は、対応するソースまたはシンクのメンバーも静的メンバーである必要があります。
-
特定の場所がインスタンス メンバーである場合は、対応するソースまたはシンクのメンバーはインスタンス メンバーまたは静的メンバーのどちらでもかまいません。
-
-
owner プロパティが空白である。