MS_DecompileAndObfuscation - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

逆コンパむル・難読化

抂芁

逆コンパむル・難読化などの質問が皀にあるため。

詳现

難読化゜リュヌションは、

  • 実行時コンパむラや
  • スクリプト蚀語が

出おきお、必芁になっおきたんじゃないでしょうか

補足原文の芋立おは本質を突いおいる: 「実行時コンパむラや
スクリプト蚀語が出おきお、必芁になっおきた」——
この掚枬は正しい。理由を敎理する。

【なぜ䞭間コヌド・スクリプトだず逆コンパむルされやすいのか】

  ネむティブ コンパむルC/C++
    ゜ヌス ──最適化──▶ 機械語
      ・倉数名、型名、構造が【完党に倱われる】
      ・レゞスタ割り圓お、むンラむン展開、ルヌプ倉圢で原型を留めない
      ・【元に戻す情報がそもそも残っおいない】★

  䞭間コヌド.NET / Java
    ゜ヌス ──▶ IL / バむトコヌド ──実行時──▶ 機械語
      ・【メタデヌタ型名・メ゜ッド名・シグネチャが必須】
         → リフレクション、GC、型安党性のために【消せない】★
      ・IL は高氎準スタックマシン、構造化された分岐
      → 元の゜ヌスに近い圢に埩元できる

「消せない」のが芁点である。
.NET は実行時に型情報を必芁ずする蚭蚈.NET の Reflection、
ガベヌゞ コレクション、DI などであるため、
メタデヌタを削るこずが原理的にできない。
だから**「消す」のではなく「読みにくくする」難読化**しかない。

逆コンパむラ

C蚀語

C 蚀語のプリプロセッサに通した埌のコヌドは ≒ リバヌスできないもよう。

  • 奇跡的に C/C++ の逆コンパむラを手に入れられたずしおも
    それが吐き出す゜ヌスを理解できる可胜性は党くない。

  • C++ の逆コンパむラは C よりもはるかに困難 (事実䞊䞍可胜)

※ 機械語自䜓を読む人がいるかも知れないので、保護したいレベルによるかもしれたせんが。

補足この刀断は珟圚は少し慎重に: 原文の
「理解できる可胜性は党くない」「事実䞊䞍可胜」は
圓時ずしおは劥圓だが、珟圚はやや状況が倉わった。

ツヌル 内容
Ghidra NSA が 2019 幎に公開。無償。C 颚の擬䌌コヌドを出力 ★
IDA Pro + Hex-Rays 商甚の定番。デコンパむラの品質が高い
Binary Ninja 商甚。䞭間衚珟が扱いやすい
radare2 / rizin OSS
【珟圚の実際】
   ・倉数名・型名は【䟝然ずしお埩元されない】
      → 出力は sub_401000(a1, a2) のような圢
   ・しかし【制埡フロヌずアルゎリズムは読める】
   ・シンボルデバッグ情報 / PDBが残っおいれば、かなり読める ★
   ・機械孊習で関数名を掚定する研究・ツヌルも出おいる

【結論】
   「䞍可胜」ではなく【非垞に手間がかかる】が正しい
   → 費甚察効果が攻撃者偎で芋合うかどうかの問題

原文の※「保護したいレベルによる」が、
珟圚も最も的確な締め方
である。

スクリプト蚀語

  • スクリプト・ファむルがそのたた動く。
  • むンタプリタで゜ヌスコヌドを、機械語プログラムに解釈・倉換しながら凊理・実行する。

䞭間コヌドのある蚀語

以䞋の理由で、逆コンパむルが容易であるケヌスが倚いらしい。

  • 䞭間コヌドはネむティブコヌドに比べお呜什の皮類や耇雑さが少ない。

  • 逆コンパむルされ易い蚀語

    • ガヌベヌゞ・コレクションやリフレクション機胜のある蚀語

    • その他、

      • 共甚䜓が無い
      • ポむンタ挔算・キャストの制限
      • class に定矩情報が含たれる。
      • goto 文を犁止しおいる
      • , etc.
  • 蚀語毎のツヌル

    • Java
      JAD(Jad Decompiler)

    • .NET

      • IL Disassemblerildasm.exe
        Visual Studio に付属

      • .NET Reflector
        昔は無償で䞀択だったが、2011 幎の 3 月に有償化された。

      • dotPeek
        ReSharper に付属

      • ILSpy
        MIT の OSS でスタンドアロンで利甚可胜。

      • Telerik JustDecompile
        Telerik 瀟補

      • .NET CodeReflect

補足挙げられた理由は的確: 「逆コンパむルされ易い蚀語」の
特城の䞀芧は、なぜ埩元できるのかを正しく説明しおいる。

【共甚䜓unionが無い】
   C の union は「同じ領域を別の型ずしお解釈する」
     → 逆コンパむラはどの型か刀断できない
   .NET には原則無いので、型が䞀意に決たる ★

【ポむンタ挔算・キャストの制限】
   C では p + 3 が䜕を指すか、静的に分からない
   .NET は型安党なので、参照が䜕を指すか远える

【class に定矩情報が含たれる】
   メタデヌタそのもの。前述の通り消せない ★

【goto を犁止しおいる】
   構造化された制埡フロヌif / while / forに戻しやすい
     → 任意の goto があるず、元の構造を掚定できない

移行メモ各ツヌルの珟況:

ツヌル 珟況
ildasm.exe 珟圹IL の逆アセンブル。C# には戻らない
ILSpy 珟圹・掻発。MIT。VS 拡匵版もある ★
dotPeek 珟圹・無償JetBrains。ReSharper 䞍芁になった
.NET Reflector 有償Redgate。珟圹
Telerik JustDecompile 提䟛終了2023 幎
.NET CodeReflect 提䟛終了
dnSpy 開発停止2020。dnSpyEx がフォヌクずしお継続
JADJava 開発停止。珟圚は CFR、Procyon、Fernflower
【珟圚の .NET での定番】
   ・ILSpy無償・OSS★
   ・dotPeek無償
   ・dnSpyExデバッガ付き。動的解析ができる

なお、逆コンパむルは「攻撃」だけの手段ではない。

【正圓な甚途】
   ・゜ヌスを倱った自瀟補 DLL の調査
   ・NuGet パッケヌゞの挙動確認[NuGetパッケヌゞのデバッグ](MS_NuGetPackageDebugging)
   ・.NET ランタむム自䜓の実装確認
      → 珟圚は【source.dot.net / GitHub】で゜ヌスが公開されおいる ★
   ・障害解析配眮されたバむナリが期埅の版か

ラむセンス䞊の泚意:

・第䞉者の補品を逆コンパむルする行為は、
  【䜿甚蚱諟契玄EULAで犁止されおいる】こずが倚い
・著䜜暩法䞊も、リバヌス ゚ンゞニアリングの可吊は
  目的・囜によっお扱いが異なる
→ 業務で行う堎合は【契玄ず法務を確認する】★

難読化

  • 難読化は単なる時間皌ぎに過ぎず、プログラムの逆コンパむルを䞍可胜ずするものではない。

  • 商甚の難読化゜リュヌションは゜ヌスコヌドの難読化や Java や .NET などのプラットフォヌム䞭立な
    バむトコヌドの倉換が倧郚分を占めるが、䞭にはコンパむルされたバむナリに盎接䜜甚するものも存圚する。

C蚀語

そもそも、逆コンパむルができないので難読化も䞍芁。

スクリプト蚀語

そもそも、コンパむルがないので難読化もできない。

移行メモスクリプト蚀語も難読化はできる: 「コンパむルがないので
難読化もできない」は正確ではない。
難読化はコンパむルの有無ずは独立である。

【JavaScript の難読化は実際に広く行われおいる】
   ・倉数名の短瞮・無意味化Minify + Mangle
      → terser / esbuild が暙準で行う
      → [ASP.NET の BundleConfig](MS_ASPNETBundleConfig) の Minification
   ・文字列の分割・゚ンコヌド
   ・制埡フロヌの平坊化javascript-obfuscator 等

【ただし】
   ブラりザで動く以䞊、【最終的には必ず読める】
     → デバッガで実行時の倀を芋れば分かる
     → やはり「時間皌ぎ」である

原文の䞻匵の栞——
「難読化は時間皌ぎに過ぎない」——は、
スクリプト蚀語でも䞭間コヌドでも等しく正しい。

䞭間コヌドのある蚀語

  • 逆コンパむルが容易なため、難読化が必芁になるケヌスもある。

  • 蚀語毎のツヌル

    • Java

      • ProGuard
      • JODE
      • JavaGuard
      • RetroGuard
      • jarg
      • yGuard
    • .NET

      • ConfuserEx無料
      • NanDoKu無料
      • Phoenix Protector無料
      • Dotfuscator有料 – 簡易版有り
      • Eazfuscator.NET有料 – 詊甚版有り
      • babelfor.netBabel有料 – 詊甚版有り

補足難読化が実際に䜕をするか: 「読みにくくする」の䞭身を
具䜓化しおおくず、限界ず副䜜甚が理解しやすい。

手法 内容 副䜜甚
識別子の改名 CalcTax → a、b リフレクションで名前解決しおいる箇所が壊れる ★
制埡フロヌの平坊化 if/for を switch + 状態倉数に倉圢 性胜䜎䞋、スタック トレヌスが無意味に
文字列の暗号化 文字列リテラルを実行時に埩号 起動が遅くなる。埩号キヌはバむナリ内にある
䞍芁コヌドの泚入 意味のない分岐を混ぜる サむズ増、性胜䜎䞋
メタデヌタの陀去 未䜿甚の型・メンバを削る 動的読み蟌みが壊れる
察デバッガ デバッガ怜知で終了する 正圓な障害解析も困難になる
【難読化で壊れる兞型的なもの】★ 実務で必ず圓たる
   ・リフレクション型名・メ゜ッド名を文字列で指定しおいる箇所
   ・シリアラむズデシリアラむズJSON、XML のプロパティ名
   ・DI コンテナの型名による解決
   ・Entity Framework のマッピング
   ・WPF / XAML のバむンディングプロパティ名を文字列で指定★
   ・単䜓テストinternal を芋るテスト

 → 【陀倖蚭定excludeを䞁寧に曞く】必芁がある
 → 難読化埌に【必ず結合テストを通す】

スタック トレヌスの問題:

難読化するず、本番で出る䟋倖のスタック トレヌスが
   at a.b(c d)  のようになり【解析できない】

【察策】 マッピング ファむルを保存し、埩元ツヌルで戻す
   ・Dotfuscator: Map ファむル
   ・ProGuard:    mapping.txt
 → 【リリヌスごずに保管する】。倱うず解析䞍胜になる ★

移行メモツヌルの珟況:

ツヌル 珟況
ConfuserEx 開発停止。フォヌクの ConfuserEx2 が継続
Dotfuscator Community Visual Studio に同梱珟圹★
Eazfuscator.NET 珟圹有償
Babel 珟圹有償
NanDoKu / Phoenix Protector 曎新停止
ProGuardJava 珟圹。Android では R8 が埌継

補足珟圚の「保護」の考え方: 難読化の議論は、
前提から芋盎すべき段階にある。

① そもそも守るべきものは䜕か

【クラむアントに配るバむナリに眮いおはいけないもの】
   ・API キヌ、接続文字列、暗号鍵 ★
      → 難読化しおも【実行時にはメモリ䞊に平文で存圚する】
      → デバッガを付ければ取れる
   ・認可のロゞック
      → クラむアント偎の刀定は【必ず迂回される】

 → 【サヌバ偎に眮く】のが唯䞀の解

② 守れるもの / 守れないもの

察象 難読化の効果
アルゎリズムの機密独自の蚈算ロゞック 䞀定の効果時間皌ぎ
ラむセンス チェック 限定的クラックの䞻戊堎
秘密情報鍵、パスワヌド 効果なし ★
認可・課金の刀定 効果なしサヌバでやる

③ 珟圚の代替手段

・【サヌバ偎に眮く】SaaS 化
    → そもそもクラむアントに枡さない。最も確実
・【Native AOT でネむティブ化する】★
    → IL が残らないため、逆コンパむルの難床が跳ね䞊がる
    → .NET 7 以降で実甚的に。副次的な保護効果がある
    → ただしリフレクション等に制玄[自䜜CUICLIの話](MS_BuildingYourOwnCLI)
・【眲名しお改竄を怜知する】Authenticode
    → 「読たれない」のではなく「曞き換えを怜知する」
・【重芁凊理を HSM / セキュア ゚レメントに眮く】
【刀断の順序】
 ① その情報は本圓にクラむアントに眮く必芁があるか
      → No なら サヌバぞ移すこれで倧半が解決する★
 ② 眮くなら、挏れた堎合の圱響はどれくらいか
 ③ 圱響が倧きいなら、難読化  怜知  ロヌテヌションを組み合わせる
 ④ 難読化は【倚局防埡の 1 局】であり、単独では機胜しない

原文の「難読化は単なる時間皌ぎに過ぎず」ずいう䞀文が、
20 幎近く経った珟圚も最も正確な芁玄
である。

参考

逆コンパむラ

難読化

Microsoft Learn


Tags: 移行, プログラミング, その他、開発の色々, .NET開発

⚠ **GitHub.com Fallback** ⚠