Skip to Content
新しいバージョン 12 を公開しました 🎉
Obfuscator制御フロー難読化パフォーマンスとチューニング

パフォーマンスとチューニング

制御フロー難読化は、わずかな実行時間と引き換えに保護を得るものです。軽量なアルゴリズムは、実質的にコストがかかりません。フラット化アルゴリズムは、呼び出しのたびに実行されるディスパッチャーを追加するため、コストが高くなります。このページでは、アルゴリズムを比較し、「反復回数」の設定を説明して、頻繁に呼び出されるメソッドを高速に保つ方法を示します。

アルゴリズムの比較

アルゴリズム系統実行時の相対コスト検証可能な ILエディション
if軽量ごくわずかはいすべて
goto軽量ごくわずかはいすべて
switchフラット化高はいすべて
caseフラット化(switch と併用)高はいすべて
callフラット化(switch と併用)高はいすべて
valueフラット化(switch と併用)高はいすべて
chain(チェーン状態)フラット化高(≈ switch)はいUltimate
token—低いいえすべて
underflow—低いいえすべて

表の読み方

  • if と goto は、分岐と条件を追加しますが、ディスパッチャーは追加しないため、実行時のコストはごくわずかです。広く適用できます。
  • フラット化系(switch、case、call、value)と chain は、ディスパッチャーを中心にメソッドを再構築します。タイトなループで数千万回呼び出される小さなメソッドでは、フラット化を 1 回適用すると、そのメソッド自体の呼び出し 1 回あたりの時間が、およそ 1 桁増えます。難読化解除がはるかに困難であるにもかかわらず、チェーン状態は switch との差が数パーセント以内に収まります。追加の保護は、フラット化そのものと比べれば、実質的にコストがかかりません。
  • token と underflow は、実行時のコストは低いものの、検証不可能な IL を生成するため、Babel は .NET と .NET Core ではこれらを無効にします。

これらは、フラット化された小さなメソッド 1 つをループで呼び出すだけのマイクロベンチマークによる、最悪の場合の数値です。ほとんどのメソッドは、このようなホットループでは呼び出されないため、フラット化の実際の影響は、通常は小さなものです。それでも、フラット化は重要なメソッドに限って使用し、ホットパスには適用しないことをお勧めします。

制御フローの反復回数

制御フローアルゴリズムによる難読化の効果は、主に、メソッドに適用する「反復回数」によって決まります。回数が多いほど、結果は複雑になります。フラット化アルゴリズムの場合は、適用のたびにディスパッチの層が 1 つ増えるため、実行時のコストも高くなります。

Babel では、--iterations <n>(MSBuild では ILIterations)で反復回数を設定できます。0 に設定すると、制御フロー難読化は無効になります。メソッドのフローをそれ以上変更できなくなる上限があり、これはメソッドの構造によって決まります。そのため、回数を増やしても、命令が増えるとは限りません。

制御フロー難読化の限定

フラット化は、対象となるすべてのメソッドに分岐を追加するため、見境なく適用すると、パフォーマンスが重要なコードが遅くなることがあります。XML ルールを使用して、制御フロー難読化を必要なメソッドに限定し、残りを除外してください。たとえば、コンパイラーが生成したメソッドは、保護に値する知的財産を含むことがほとんどないため、除外できます。

<Rules> <Rule name="rule" feature="control flow" exclude="true" applyToMembers="true"> <Target>Classes</Target> <Pattern>*</Pattern> <HasAttribute onEnclosingType="false">System.Runtime.CompilerServices.CompilerGeneratedAttribute</HasAttribute> </Rule> </Rules>

このルールは、exclude="true" で control flow 機能を対象にし、applyToMembers="true" で、一致するクラスのすべてのメンバーに適用範囲を広げます。<Target> 要素は要素の種類(ここでは Classes)を選択し、<Pattern> はその名前に一致させ(* はすべて)、<HasAttribute> は、CompilerGeneratedAttribute を持つクラスだけに一致を絞り込みます。

同じ方法で、パフォーマンスが重要だとわかっているメソッドを除外できるため、保護と速度のバランスを取ることができます。機密性の高いコードはフラット化し、ホットパスには手を加えないでおきます。

Last updated on