プログラムの動きを解析してみよう!|セキュリティ|ブログ|Computerworld

header_cwr_head_mid_fl_logo

CW_ウルトラバナー_Topics04

CW_ウルトラバナー_Topics05

CW_ウルトラバナー_Topics06

CW_ウルトラバナー_Topics07

CW_ウルトラバナー_Topics08

セキュリティ

プログラムの動きを解析してみよう!

Posted by 蔵本雄一 ( 2010年06月27日 )

読者の皆様

お待たせしました。

神戸元町の「赤萬」さんで餃子4人前を一人で平らげてしまった蔵本です。

いやー、おいしかったです。脂っぽくないので、ついつい食べ過ぎてしまいますね。(完全に食べ過ぎですがw)

元町へお立ち寄りの際には是非!

さてさて、前回逆アセンブルして改ざんしたコードがありましたが、今回は何故動きを変える事ができたのか?を考えていくのですが、核心に迫る前に、前準備の解説が必要です。逆アセンブルしたコードを読んでこのプログラムの動きを解析しましょう。自身で作成したプログラムなので、イメージもつきやすいかと思います。

逆アセンブルしたコードを上からみていくと、下記のコードが記述されている部分があります。ここが今回のツボです。

01291025 66:394C24 04 CMP WORD PTR SS:[ESP+4],CX

0129102A |. 76 18 JBE SHORT Sample1.01291044

ここで「CMP」と「JBE」について簡単に解説しますと、

「CMP A,B」

「JBE」

とあると、B=>Aの場合に、JBEのオペランドで指定されているアドレスへジャンプするという動きになります。

今回の実際の使用を見てみると、下記のようになっています。

【CMP WORD PTR SS:[ESP+4],CX】

「ESP+4のアドレスにある値」と、「ECX」レジスタを比較しています。

【JBE SHORT Sample1.01291044】

「ECX」=>「ESP+4のアドレスにある値」 である場合、「01291044」へジャンプしています。

ここで、「CMP」「JBE」で使用されている、「ECX」、「ESP+4のアドレスにある値」「ジャンプ先である01291044」が気になりますね!それぞれ調べていきましょう。

———————ECXレジスタの値を調べてみよう———————

ではまず、ECXレジスタに格納されている値を調べてみましょう!

「CMP」の部分にブレイクポイントを設定します。

下記のコード部分を選択し、右クリックして、表示されるポップアップメニューから「BreakPoint」→「Toggle」を選択します。

01291025 66:394C24 04 CMP WORD PTR SS:[ESP+4],CX

すると、アドレス列が赤く表示されるはずです。これで、実行時に、「CMP」が実行されようとする時に一時停止し、その時のレジスタの値等を見る事ができます。

それでは、メインメニューから「Debug」→「Run」を選択してみましょう。

今、皆さんのデバッガでは、「CMP」部分で止まった状態かと思います。

ここで、右のレジスタペインで「ECX」レジスタを見てみましょう。

すると、「000007D0」とありますね。これを10進数に直すと、「2000」ですね。

これで、今、ECXレジスタには「2000」が格納されている事がわかりました。

———————ESP+4の中身を調べてみよう———————

では、次に「ESP+4」のアドレスに格納されている値を調べてみましょう!

今、皆さんのデバッガは先ほどのECXレジスタの調査でCMP部分のブレイクポイントで止まったままになっていると思います。この調査は、そのままで行います。

レジスタペインを見てみると、ESPレジスタの値は、「0016F99C」となっています。これに4を足すと、「0016F9A0」ですね。逆アセンブルペインの下を見てみると、おっと、なんと親切な設計なのでしょうか。「0016F9A0」の値を表示してくれています。「07DA」です。

これを10進数に変換すると、2010ですね。

ちなみにこのペインでは、先ほどのECXレジスタの値も表示してくれていますね。うーん、なんて親切な。

つまりこの「CMP」では、2010と2000を比較し、2000>=2010だった場合に、「01291044」へジャンプしているようです。

———————01291044には何がある?———————

JBEでの飛び先となる「0129104」には何があるのか気になります。

逆アセンブルペインで見てみますと、下記部分が該当します。

つまり、2000>=2010の場合、下記のメッセージボックスが表示される訳ですね。



01291044 |> 68 38212901 PUSH OFFSET Sample1.??_C@_0P@CMKHHPEP@?$”>Sample1.??_C@_0P@CMKHHPEP@?$>; |Title = “起動できました”

01291049 |. 68 48212901 PUSH OFFSET Sample1.??_C@_0DP@GLPHILAL@2″>Sample1.??_C@_0DP@GLPHILAL@2>; |Text = “2000年よりも前だったら、このメッセージボックスが表示されます。”

0129104E |. 6A 00 PUSH 0 ; |hOwner = NULL

01291050 |. FF15 A8202901 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; |MessageBoxA

01291056 |. 33C0 XOR EAX,EAX

01291058 |. 83C4 10 ADD ESP,10

0129105B |. C3 RETN



自分で書いたプログラムとは言え、こうやって動作解析しながら見るとまた新鮮に見えるので不思議ですよね。

では次回いよいよ核心に迫ります!

ページの先頭へ戻る