C#でもILGeneratorでダイナミックにToStringしたい

はじめに

動的にToStringするのに定評がある[要出典]弊社ですが、ライブラリを追加するレベルでもないけど手軽に1ソースコードを追加するだけでパパッと使えるものが欲しいな~と考えておりました。

と、いうわけで作りました。

縛り内容

ゲーム実況等では縛りとしていくつかルールを決めてプレイすることがありますよね。

今回は弊社もいくつか縛りを設けて実装してみようと思います。

2番目についてはまぁ涙を拭けよといった感じですが、まぁアレがアレですよね。

コード

github.com

おわりに

まぁやっていることはSigilを使ったアレと全く一緒なんで特に解説もいらないかな。

jyuch.hatenablog.com

おわり

VB.NETでもWinDbgしたい

はじめに

この記事はWinDbg.NET Frameworkデバッグをするときのコマンドの備忘録です。

解説はありません。希望もありません。

ダンプの取得

ダンプは別途ソフトウェアをインストールする必要なく、タスクマネージャから取得することが可能。

しかし、ダンプを取得するプロセスのビット数に応じてタスクマネージャのビット数を選択する必要がある。

  • 32bit Windows
    • 常に32bitタスクマネージャ(通常起動したタスクマネージャ)
  • 64bit Windows
    • 64bitプロセス
      • 64bitタスクマネージャ(通常起動したタスクマネージャ)
    • 32bitプロセス
      • 32bitタスクマネージャ %windir%\SysWOW64\taskmgr.exe

当該プロセスがどのビット数で動作しているかはタスクマネージャの詳細タブ→プラットフォーム(Windows 10)から確認が可能。

SOSのロード
  • ~.NET 3.5
    • .loadby sos mscorwks
  • .NET 4 ~
    • .loadby sos clr
メソッドにブレークポイントを貼る

!bpmdsos.dllのロードが必要。

Setting .NET breakpoints in Windbg for applications that crash on startup – If broken it is, fix it you should

How to add a breakpoint in a managed generic method in windbg (sos) – I know the answer (it's 42)

JITコンパイル済みネイティブアドレスからMethodDescを検索
0:000> !clrstack
OS Thread Id: 0x2ec0 (0)
Child SP       IP Call Site
012ff14c 0192056e ConsoleApplication2.Module1.Hoge[[System.Double, mscorlib]](Double) [C:\Users\jyuch\Documents\Visual Studio 2015\Projects\ConsoleApplication2\ConsoleApplication2\Module1.vb @ 19]
012ff164 019204c2 ConsoleApplication2.Module1.Main() [C:\Users\jyuch\Documents\Visual Studio 2015\Projects\ConsoleApplication2\ConsoleApplication2\Module1.vb @ 10]
012ff2e8 73e81376 [GCFrame: 012ff2e8] 


0:000> !ip2md 0192056e
MethodDesc:   01444dcc
Method Name:  ConsoleApplication2.Module1.Hoge[[System.Double, mscorlib]](Double)
Class:        0144159c
MethodTable:  01444d70
mdToken:      06000011
Module:       01443fbc
IsJitted:     yes
CodeAddr:     01920550
Transparency: Critical
Source file:  C:\Users\jyuch\Documents\Visual Studio 2015\Projects\ConsoleApplication2\ConsoleApplication2\Module1.vb @ 19
MethodDescからILをダン
0:000> !dumpil 01444dcc
ilAddr = 00e72214
IL_0000: nop 
IL_0001: ldarga.s VAR OR ARG 0
IL_0003: constrained. <unknown token type 1b000000>
IL_0009: callvirt System.Object::ToString 
IL_000e: stloc.0 
IL_000f: br.s IL_0011
IL_0011: ldloc.0 
IL_0012: ret 

おわりに

わあい

おまけ

reflexil.net

よさげ

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

はじめに

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を通じて利用するようなサービスとして展開する

などが挙げられます。

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

おわり