LoginSignup
10
5

More than 1 year has passed since last update.

.Netの単一実行ファイルを難読化する

Posted at

はじめに

やってみたところ思いのほか簡単にはいかなかったためメモ

まず、.Net系のexeやdllは簡単にソースコードを復元することができます
元々ildasmが同梱されていますし、今やVisualStudioでF12で定義に飛ぶときに逆コンパイルしてコードを確認することもできるようになっています
image.png
当然適当なライブラリであっても、あるいは商用のプログラムであってもILSpyやdnSpyで中身を解析したりデバッグしたりができてしまいます
image.png
上の画像の実際のソースコードはこことかここです

まあ別に見られても困らないし・・・とか、IL見れたほうが都合がいいし・・・とか、エラー発生時の解析が困難になるからやらない、とかもありますが、時としてそうはいかない場合もあります

やり方

.NET Frameworkならいける、とか単一実行ファイルではない場合はいける、とかいろいろありましたが最終的にはこちらがうまくいきました

Confuser.MSBuild
ConfuserにはいろいろとForkがあるようで、果たしてこれが信用できるのか? というのはあると思いますが保証はしません

.Net7.0でWPFの新規プロジェクトを作成したら、Nugetを利用してインストールします
image.png

次に設定ファイルを作成します
細かい設定がしたい場合、Confuserの他のForkでGUI付きのものから生成したほうがいいかもしれませんが、ここでは直接ファイルを手書きします

都合がいいのでConfuserをインストールしたプロジェクトと同じ場所に「{プロジェクト名}.crproj」というファイルを作成します
image.png
ファイルの中を開いて、まず以下のように記述します

{プロジェクト名}.crproj
<project outputDir="$(OutDir)confused\" baseDir="$(MSBuildProjectDirectory)" xmlns="http://confuser.codeplex.com">
  <rule pattern="true" preset="minimum" inherit="false">
      <protection id="rename">
        <argument name="renXaml" value="false" />
      </protection>
   </rule>
</project>

2行目から先の内容は要件によって様々です
例えば4行目の内容のリファレンスはこちらです

次にプロジェクトファイルを開いて難読化設定を追加します

{プロジェクト名}.csproj
 <PropertyGroup>
    <Obfuscate>true</Obfuscate>
    <ConfuserReplaceOutput>true</ConfuserReplaceOutput>
    <ConfuserProject>$(MSBuildProjectDirectory)\$(MSBuildProjectName).crproj</ConfuserProject>
  </PropertyGroup>

特に2行目はtrueにしておくとアンチデバッグ機能により、デバッグできなくなってしまうので開発時はfalseにしておくといいです
このあたりの設定についてのリファレンスはこちらです

単一実行ファイルの作成

プロジェクトを右クリックして発行を選びます
image.png
設定がなければダイアログが出てくるので任意の場所を選択します
今回はローカルフォルダに出力します
image.png
image.png
デフォルト設定のまま完了を押します
image.png

細かい設定を詰めます
ターゲットランタイムの鉛筆マークを押して設定を出します
image.png
ターゲットランタイムが、今回はWPFなのでWIndows専用であることから、「win-x64」にしておきます
その後、下に「ファイルの公開オプション」が出現するので「単一ファイルの作成」にチェックを入れます
image.png
設定を保存したら発行を押します
image.png
ビルドが走って指定の場所にファイルが作成されているので内容をILSpyで開いて確認します

例えば、これはまったくコードを変更せずに作成したWPFの逆コンパイルです
何やら謎のboolが作成されたりしていますね
「mainwindow.xaml」という文字は見えていますが、このあたり変に名前を変えられると動かなくなったりするのでこれは置いておきます
image.png

とりあえず基本は以上の内容で終了です

ただし、たまに難読化されていると正しく動かなくなったりする処理があるので、クラス単位での抑制の方法を書いて終わりとします
以下のようにObfuscationAttributeを設定すると、設定した単位で難読化の回避ができます

[ObfuscationAttribute(Exclude = false, Feature = "-rename")]
public partial class MainWindow : Window

おわりに

個人的にはよほど自信がない限り、難読化をかけるのはお勧めしません
例えば、ただViewModelを作るようにして、そのコンストラクタで例外を出すようにしただけの修正を加えたとしましょう

起動すると何も起こらないんですが、仕方がないのでイベントビューワで見るとこうです
image.png
当然ソースコード上の記述しか知らないわけですから、まず逆コンパイルにかけてこれがどこで起こったのかを調べないといけません

実際のプロジェクトで何か問題が起こった時、難読化が牙を向くのは開発者のほうです

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5