概要
Dotfuscator にはすべてのクラス、メソッド、およびフィールドを短い名前に変更する機能があります。 この機能により、逆コンパイルの出力を非常に理解しづらくするだけでなく、生成される実行可能ファイルのサイズを小さくすることができます。
大部分の商用難読化プログラムは、1 文字程に短い意味のない識別子を適用する名前変更技法を採用しています。 難読化プログラムはコードを処理する際、次に利用可能な意味のない識別子を置き換え用として選択します。 この表面上単純な名前変更方式は、キー属性を持っています。それは元に戻すことはできません。 プログラム ロジックを保持しますが、名前の意味はわからなくなり、コードを解釈するすべての試みを防げます。
オーバーロード誘導
Dotfuscator は、オーバーロード誘導™ と呼ばれる特許取得済みの技術を採用しています。オーバーロード誘導は、1 つの古い名前を 1 つの新しい名前に置き換えていくのではなく、できる限り多くのメソッドの名前を同じ名前に変更します。このような強度な難読化により、そのロジックは人間には理解不能になります。
実際の例を見てみましょう。次の例で、オーバーロード誘導技術の威力が理解できます。
- 難読化前のソース コード:
private void CalcPayroll(SpecialList employeeGroup) {
while (employeeGroup.HasMore()) {
employee = employeeGroup.GetNext(true);
employee.UpdateSalary();
DistributeCheck(employee);
}
}
- オーバーロード誘導難読化を行った後のリバース エンジニアリングされたソース コード:
private void a(a b) {
while (b.a()) {
a = b.a(true);
a.a();
a(a);
}
}
名前の変更により、アプリケーションがコンパクトになります。20 文字の長さの名前の場合、名前を a() に変更するとサイズは 95% 縮小されます。また、名前の変更は文字列ヒープ エントリを節約することでも領域を節約します。複数の項目の名前を a に変更すると、Dotfuscator は識別子を 1 回だけ格納します。
この方法には明確な利点がいくつかあります。
- 名前の変更は、逆コンパイルした出力を理解しづらくします。 しかしながら、逆コンパイラは印字不能文字あるいは、対象ソース言語では無効な名前を再度変更する機能を備えているため、識別子をそのような名前に変更することは無意味です。 一方、オーバーロード誘導でメソッドの 1/3 の名前が "
a()" になることを考慮すると、逆コンパイルした出力を理解することは間違いなく困難になります。 - オーバーロード誘導は、あらゆる名前変更システムに共通する制限以外の制限は受けません。
- オーバーロード誘導は同じ文字を頻繁に使用する傾向があるので、文字数の多い名前(
aa、aaaなど)になるまでには時間がかかります。 この点でも領域を節約します。
米国で特許を取得したオーバーロード誘導のアルゴリズムは、発生する可能性のあるすべての名前変更の衝突を判断し、安全な場合にのみメソッドのオーバーロードを誘導します。 この処理が不可逆であることは実証可能です。 つまり、(再度オーバーロード誘導を実行しても)元のメソッド名の関係を再構築するのは不可能です。
拡張オーバーロード誘導
Dotfuscator は、メソッドの戻り値の型またはフィールドの型を、メソッドまたはフィールドの一意性を判断するときの条件として使用できるようにすることによって、拡張オーバーロード誘導(Overload-Induction™)を提供します。 この機能により、名前変更されたメソッド名およびフィールド名の重複性を最大 15% まで高めることができます。 さらに、戻り値の型やフィールドの型によるオーバーロードは(C#、Visual Basic などの)ソース言語では通常は許可されていないので、逆コンパイルをいっそう困難なものにします。
制限事項
名前の変更を有効にする前に、次の制限事項を確認してください。
- XAML アセンブリ:Dotfuscator は、実行時リンク要件のため、XAML コードを含んでいるアセンブリに対してはオーバーロード誘導を実行しません。[拡張オーバーロード誘導を使用する]オプションによって、このようなアセンブリが変更されることはありません。
- リフレクションと構成:アプリケーションが何らかの種類のリフレクション、エントリ ポイントを含む構成ファイル、外部アプリケーションからアクセスされるライブラリを使用している場合は、名前の変更によって問題が発生する可能性があります。
- Xamarin.Android:Xamarin.Android ビルドでは、Lower Alpha または Upper Alpha 名前変更規則のみを使用する必要があります。
- テスト:名前の変更を有効にした後、すべての参照が正しく更新されていることを確認するために、アプリケーションを十分にテストする必要があります。
詳細については、名前の変更規則を参照してください。
特定の対象除外
Dotfuscator は、ライブラリ モードがオフになっているものと仮定して、できる限りすべての名前を変更しようとします。 リフレクションの特定の使用法が原因で、Dotfuscator は名前の変更時に、特定のエンティティへのすべての参照を更新できないことがあります。 次の例では、4 つのクラスとそのフィールドを対象から除外しています。
この例のアプリケーションは、これらの型やメンバーを参照する場合、リフレクションを使用してそれらの名前を検索しています。 名前が変更されると、アプリケーションは実行時にそれらを見つけられなくなる可能性があります。 そのため、対応するチェック ボックスを使用して、名前の変更処理の対象からこれらを除外しています。
カスタム対象除外規則
特定のコーディング規約のために、多数の特定の対象除外を作成しなければならない状況がある可能性があります。作成した後も、開発者はその規約に従うコードを追加した場合には、その新しいコードのために、さらにもう 1 つ特定の対象除外を作成することを覚えておかなければなりません。
これの解決策が、カスタム対象除外規則です。前の例から、型名が "Dungeon" で終わるすべての型と、それらの型内の特定の型のフィールドは、何らかの理由で名前の変更対象から除外される必要があることがわかったとします。多数の特定の対象除外を作成するかわりに、[名前の変更]エディターで次のように 1 つのカスタム規則を作成することができます。
- [型の追加]ボタンをクリックして、規則のルート ノードを追加します。
- [名前]フィールドに
.*Dungeonと入力します。 - [正規表現](regex)オプションをオンにして、この名前を正規表現として扱う必要があることを示します。これにより、ノードは、型名が "Dungeon" で終わる型と一致します。
- [型を除外する](excludetype)オプションをオンにして、一致する型を除外します。このオプションをオフにした場合には、一致する型は名前の変更対象から除外されません。それらの子ノードによって指定されるメンバーのみが除外されます。
- ルート ノードを右クリックし、[フィールドの追加]を選択して子ノードを追加します。
- このノードの名前を
.*とし、この名前を正規表現として扱う必要があることを示します。 - パブリック アクセス修飾子を持ち(
+publicを設定する)、署名がstring[]であるフィールドのみを対象とするように規則を制限します。このシナリオには両方が必要です。
規則を構成したら、ノードを選択して[プレビュー]ボタンをクリックすることができます。左側のツリー ビューで、カスタム規則に一致するエントリが強調表示されます。規則は右ペインに表示されます。
この例では、子ノードをプレビューすると、条件に一致するフィールドが強調表示されます。AdventureGame.Validation の Keys フィールドは除外されていないことに注目してください。これは、フィールドはこの子ノードに一致していますが、その親の型は親ノードに一致していない(クラス名 "Validation" は "Dungeon" で終わっていない)からです。
この結果として生じるカスタム規則の構成は、XML として構成ファイルに格納されます。この例では、次のような設定の XML が生成されます。
<type name=".*Dungeon" regex="true">
<field name=".*" speclist="+public" signature="string[]" regex="true" />
</type>
組み込み規則
組み込み規則は、普遍的にかなり役立つカスタム対象除外規則です。既定で組み込まれているため、ユーザーはそれらを再実装する必要はありません。
それぞれの規則の正確な定義は、インストール先の Common サブディレクトリに記載されています。 この場所の典型的な例は、C:\Program Files (x86)\PreEmptive Protection Dotfuscator Professional A.B.C\Common です。 この規則定義については、dotfuscatorReferenceRule で始まる XML ファイルを参照してください。
たとえば、System.Web.Services 属性を持つメソッドは、次のカスタム規則に変換されます。
<excludelist>
<type name=".*" regex="true" excludetype="false">
<comment>System.Web.services 名前空間の属性で修飾されたすべてのメソッドを除外します。</comment>
<method name=".*" regex="true">
<customattribute name="System.Web.Services.*" regex="true" />
</method>
</type>
</excludelist>
オプション
名前の変更規則など、多くの名前変更オプションについては[名前の変更]エディター セクションで記載しています。
