読者です 読者をやめる 読者になる 読者になる

VB.NETは解析されやすいのか?(その2)

VB.NET

はじめに

好きな戦車はルノー FT-17。どうも弊社です。 今からBF1が楽しみですね。

jyuch.hatenablog.com

前回はildasmを用いた逆アセンブルとプログラムに出現する文字列から当該処理を行う箇所を特定し、特定の処理の迂回をやってみました。 今回はデバッガを用いて実際の動作を覗いてみましょう。

動的解析

ところで、前回アセンブラを用いてILコードから実行ファイルを生成したときのコマンドをもう一度確認してみましょう。

>ilasm SuperUsefulApplication.il /exe /debug=impl /resource=SuperUsefulApplication.res /output=SuperUsefulApplication2.exe

ここで重要なのが/debug=implの部分です。 このオプションでデバッグシンボルを一緒に生成しています。

プログラムを起動し、デバッガをアタッチしてみましょう。 なお、ここではVisual Studio 2015 community update 3を使用しています。

デバッグ->プロセスにアタッチで一覧から目的のプロセスを見つけ、アタッチします。

f:id:jyuch:20160709233050p:plain

ところで、このアプリケーションの処理内容について説明していませんでしたね。 文字列を入力するとその文字が格納され、なにも入力しないと入力した逆順に文字列が返されるようです。

なにそれただのスタックじゃん。なんだろな~。どうやって実装しているんだろうな~。気になるなぁ~。

前回の逆アセンブルコードから、SuperUsefulApplication.SuperUsefulClass`1<string>::Pop()SuperUsefulApplication.SuperUsefulClass`1<string>::Push()が中核的な処理をつかさどっているようです。 ですので、この二つのメソッドにブレークポイントを設定してみましょう。

デバッグ->ブレークポイントの作成->関数のブレークポイントからPopPushブレークポイントを設定します。

f:id:jyuch:20160709233059p:plain

文字列を4つ程突っ込んでデバッガで内部状態を確認してみましょう。

f:id:jyuch:20160709233045p:plain

f:id:jyuch:20160709233054p:plain

ローカル変数を確認すると、線形リストでスタックを実装しているようです。

このアプリケーションは単純なのでここで終わりですが、もっと複雑なアプリケーション/ライブラリの場合でも普段と同じようにデバッグができるでしょう。

おわりに

このように、マネージドアプリケーションはリバースエンジニアリングに対して非常に脆弱であることが分かります。

リバースエンジニアリングに対する防御策としては、

  • 一部もしくはすべてをアンマネージで実装する
  • サードパーティー製品を使用して難読化を施す
  • 重要なロジックはネットワーク越しにAPIを通じて利用するようなサービスとして展開する

などが挙げられます。

ロジックの重要度と実施するコストとを勘案していい感じにアレすればいいと思います。

おわり