サラマンダーがどのように機能するかを順を追って説明したいと思いますか? 特に気になった点をいくつか紹介します
-
リンクオンデマンド
リンカはエントリ メソッド (構成可能) から開始し、コール グラフを再帰的にウォークして、MSIL コードの必要なビットのみをリンクします。未使用のコードは、最終的なアセンブリにリンクされません。したがって、コードがより効率的になり、ファイル サイズが小さくなります。
-
フレームワーク API へのリンク
リンカーは非常に強力であるため、System.Windows.Forms.dll などの Microsoft .NET Framework アセンブリでさえ、独自の .NET アセンブリにリンクできます。オンデマンドでリンクするので、必要な部分だけがリンクされます。これは、コードの保護、簡単なアプリケーションの展開、およびフレームワーク コード自体へのデバッグによるトラブルシューティングに非常に役立ちます。
-
ネイティブ コンパイル
ネイティブ コンパイラは、システム アセンブリを含むすべてのマネージ アセンブリを x86 ネイティブ コードに変換します。MSIL 命令は配布されず、実行時に JIT コンパイルは行われません。これにより、逆アセンブルと逆コンパイルに対する最高の保護が提供され、パフォーマンスと起動時間も改善されます。
-
Microsoft .NET Framework を完全にインストールしなくても簡単かつ迅速に展開
ミニ デプロイ ツールは、CLR ランタイム ファイルと依存アセンブリの最小限のセットをまとめて、ターゲット コンピューター上の 1 つのフォルダーに簡単にコピーできるようにします。アプリケーションは、フレームワーク全体がインストールされているかのように実行されます。インストールは 1 つのフォルダーに分離されるため、将来の .NET インストールと競合することはありません。依存アセンブリにリンクを使用すると、ファイル サイズがさらに小さくなります。
-
コード保護 現在の難読化ツールでは解決できない問題が 1 つあります。それは、難読化がどれほど優れていても、システム ライブラリの呼び出しやその他の外部参照がコード内に散らばっているということです (下図の赤を参照)。これらの呼び出しは外部参照であるため、難読化ツールはそれらを変更せずに残す必要があります。ただし、これらの参照は、十分に文書化されたパブリック API であるため、逆コンパイルされたコードを理解するのに大いに役立ちます。リンカーは、フレームワーク API を独自のコードにリンクすることで、このようなパブリック API を削除または削減します。したがって、難読化後のコードの逆コンパイルがはるかに困難になります。以下に、リンカーを使用する前後のサンプル MSIL コードを示します。
before: (以下のコードは外部のパブリック API であるため、難読化ツールは名前を変更できません)
IL_0000: ldarg.0
IL_0001: call instance void [System.Windows.Forms]System.Windows.Forms.Form::.ctor()
IL_0006: ldarg.0
IL_0007: newobj instance void [System.Windows.Forms]System.Windows.Forms.TextBox::.ctor()
IL_000c: stfld class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::A
IL_0011: ldarg.0
IL_0012: ldfld class [System.Windows.Forms]System.Windows.Forms.TextBox A.A::A
IL_0017: call valuetype [System.Drawing]System.Drawing.Color [System.Drawing]System.Drawing.Color::get_Cyan()
IL_001c: callvirt instance void [System.Windows.Forms]System.Windows.Forms.TextBoxBase::set_BackColor(valuetype [System.Drawing]System.Drawing.Color)
IL_0021: ldarg.0
後: (Windows.Forms API が使用されているという手がかりはまったくありません。ハッカーがこのがらくたを理解するのは非常に困難です)
IL_0000: ldarg.0
IL_0001: call instance void a.A::.ctor()
IL_0006: ldarg.0
IL_0007: newobj instance void D.c::.ctor()
IL_000c: stfld class D.c A.A::A
IL_0011: ldarg.0
IL_0012: ldfld class f.aA.A::A
IL_0017: call valuetype a.B()
IL_001c: callvirt instance void D.c(valuetype g.e)
IL_0021: ldarg.0
これらのことのいくつかは私を困惑させ、他の誰かがそれがどのように機能するか知っているかどうか疑問に思っていました.