解析講座・初歩のOLLY



 パッチとは

パッチ(Patch)とは、ソフトウェアを修正する差分情報のことです。

実行形式パッチと、各掲示板などでお馴染みのテキスト形式パッチがあります。
海外では実行形式パッチでUPが主流ですが、日本ではテキスト形式パッチを自分で処理するのが 一般的です。

FILENAME aaa.exe
0004123: 74 EB

これは、「aaa.exeファイル」 をバイナリエディタで開き「アドレス 0004123」
番地のデータ「74」「EB」 に書き換えることを表しています。
数箇所なら、かまいませんがパッチャー(Patcher)を使用したほうが効率的です。
「FireFiower by FCJ」、「PatchManager by vernichten」、「NeZuPat by ねずみ」など有名です。
読込みさせるには、上記2行をテキストファイルで拡張子を*** .patと名前をつけ保存します。

パッチャーに読込む形式として

などですがコメント ("*"が先頭につく行) を入れておくと管理しやすいです。
* PATNAME : AAA v1.00 Win98/* パッチ対象ファイル製品名、バージョン、OS
* LastMod. : 2002/01/01/* パッチ対象ファイル作成日
* AUTHOR : MAYI /* パッチ作者名
* URL : http: /* パッチ対象ファイル関連URL
* FileSize : 831bytes /* パッチ対象ファイルサイズ
* CRC : C48D8FF4 /* パッチ対象ファイル整合性チェック
* MESSAGE : 期間解除 /* メッセージ
FILENAME aaa.exe /* パッチ対象ファイル(ターゲットファイル)
0001234: 74 EB /* オフセット: 元のバイト 新しいバイト

※ パッチは生ものですから、製品名、バージョン、OS、作成日は必ず記入しましょう。
今後、Win98では動くのに?WinXPでは出来ないなどが増えるとおもわれます。



 パッチを当てる

FireFlower3 を利用して、DokoDonさん提供の ollydbg107j.pat OllyDbg v1.07 (2002/05/05)に当てて日本語文字列を表示できるようにしてみましょう。

OllyDBG Ver.1.10 JP

まずは、ウイルスチェックをしてください、常識ですね!
次に、パッチ対象ファイル(OLLYDBG.EXE)上で
「右クリック」→「全般」「属性」 の読み取り専用にチェックが無いことを確認します。

起動中のファイルには、パッチ出来ません。再起動してもシステムが 利用してるファイルなども、パッチ出来ません。どうしても、止められないファイルを パッチしたい場合は、名前を換えたり、移動すると出来ます。

ではFireFlower3 を起動してみましょう。

FireFlower設定画面1 矢印画面 FireFlower設定画面2

「Config」ボタンを押して、環境設定のチェックを確認して終了します。
これで、.pat ファイルが FireFlower3 に関連付けされました。
ollydbg107j.patをOLLYDBG.EXEのあるフォルダで左クリックすれば、
FireFlower3 が起動してパッチが完了します。

FireFlower完了画面

※ OllyDbgのメニューを日本語化するものではありません。


 OllyDbgの設定


OllyDbgのフォントの設定をしましょう。

「Options」→「Appearance」→「Fonts」

OllyDbg設定画面1

Terminal 6 を Font 5 に選択を変えて、 「Rename」ボタンを押します。

OllyDbg設定画面2 矢印画面 OllyDbg設定画面3

Font 5 を MS ゴシックに変更します。 ※ 文字化けは気にしないでください。

「Change」ボタンを押し下記のように設定します。
OllyDbg設定画面4

「Options」→「Appearance」→「General」

OllyDbg設定画面5

Use Parent's font in dialogs をチェック。

OllyDbg設定画面5

ツールバーを消したいならShow toolbarのチェックを消します。
Default font を先のFont 5 の位置の文字化けを選択します。


 練習1

OllyDbg を利用して 練習1 をやってみましょう!

解析の流れとして

  1. ウイルスチェックをする。
  2. バックアップをとる。
  3. 制限を確認する。
  4. ファイルアナライザーなどで、ファイルの全体像を確認する。
  5. パスチェック、日数チェックなとの処理場所を探す。 一箇所とは限りません!
    • 文字列から探す。
    • WinAPI(関数)から探す。
    • 逆アセを眺めカンで探す。
  6. 制限を解除する。

ここでは文字列から処理ルーチンを探してみましょう。

「C:\WINDOWS\SendTo」に「OllyDbgのショートカット」を入れておけば、 「EX1.exe」上で「右クリック」→「送る」→「OllyDbg」で読込んで起動します。 OllyDbg画面1

これは、実行ファイルがメモリ内部に展開されて、メモリ全体を一つの町とすると、
各大字(セグメント)のようすを表しています。

左上 : Disassembler windowコードセグメントの内容を表示
右上 : Registers windowレジスタの内容を表示
左下 : Dump windowデータセグメントの内容を表示
右下 : Stack windowスタックセグメントの内容を表示

各部分で表示形式を変化することができ、コードとレジスタ部が大切です。

まず練習1を起動して、どのような事が起こるか確認します。
メニューの「Debug」→「Run」か「F9」ボタンを押し、
練習1が起動したら、適当なPasswordを入れ「OK」ボタンを押します。
OllyDbg画面2

「パスワードが違います!!」とのメッセージが出てしまいました。
今回は、このメッセージから処理ルーチンを探すのが目的です。

リスタートします。「Debug」→「Restart」 か 「Ctrl+F2」
右上の適当な部分で「右クリック」→「Search for」→「All referenxed text strings」
OllyDbg画面3

OllyDbg画面4

今回は、文字列が二つしかありませんが本来はかなりの文字列があるもので、
通常は「右クリック」→「Search for text」で文字列「パスワードが違います!!」をさらに検索します。

カーソルを文字列「パスワードが違います!!」上で「左ダブルクリック」しましょう。
この文字列を利用してるコードウィンドウが表示されます。
逆アセが読みやすいようにウィンドウを調節します。 OllyDbg画面5

004010D6 の GetDlgItemTextA で文字を得

004010F8 MOV EDI,EX1.0040208A入力した文字の場所をEDIに入れ
004010FD CALL EX1.00401138401138番地の処理に移動して
00401102 TEST EAX,EAXEAXの値が同じか調べ
00401104 JE SHORT EX1.0040110D同じなら違いますへジャンプ
00401106 MOV EBX,EX1.00402021正解です!!
0040110B JMP SHORT EX1.00401112メッセージ表示へ
0040110D MOV EBX,EX1.00402008パスワードが違います!!

004010FD の CALL から戻ったときEAXの値が変化すれば正解のようです。
CALL の後 TESTしてジャンプは定番です。

パッチとして考えられるのは ここでは、「違いますへジャンプしない」で、試してみます。
00401104を選択して「右クリック」→「Binary」→「Fill with NOPs」
これは選択行をNOP(なにもしない)命令に換えます
OllyDbg画面6

OllyDbg画面7

試しに実行してみます。「F9」ボタンを押してみます。

OllyDbg画面8

うまくいきました、しかし、これはメモリ上の変化で試したのであって、
実際のファイルは換わってません。換えるためにパッチをつくりましょう。

パッチの為にメモリ上のアドレス(00401104)じゃなく
実アドレス(バイナリエデッタでのアドレス)を知る必要があります。
00401104を選択して「右クリック」→「View」→「Executable file」
OllyDbg画面8

OllyDbg画面8

「00000704 7407 JE SHORT 0000070D」 00000704 がバイナリエデッタでのアドレスです。

パッチはこうなります。

* PATNAME : EX1 Win98
* LastMod. : 2002/05/18
FILENAME EX1.exe
00000704:74 90
00000705:07 90


ところでパスワードは?

パスワードが知りたい場合はCALL EX1.00401138を調べます。
00401138 XOR EAX,EAXEAXを初期化=0にする
0040113A SUB DWORD PTR DS:[EDI],58837083データから58837083引く
00401140 JNZ SHORT EX1.00401159ゼロフラグが立たないとジャンプ
00401142 ADD EDI,4EDIに4加え読み込むデータの位置を変える
00401145 SUB DWORD PTR DS:[EDI],5B818F83データから5B818F83引く
0040114B JNZ SHORT EX1.00401159ゼロフラグが立たないとジャンプ
0040114D ADD EDI,4EDIに4加え読み込むデータの位置を変える
00401150 SUB DWORD PTR DS:[EDI],48816883データから48816883引く
00401156 JNZ SHORT EX1.00401159ゼロフラグが立たないとジャンプ
00401158 INC EAXEAXに1加える
00401159 RETN戻る

SUB DWORD PTR DS:[EDI],58837083
これは、「DS:[EDI]」(データセグメントのEDI番地を先頭にして)
「DWORD」(4バイト)のデータから「58837083」16進を「SUB」(引く)ことを表してます。

つまり、パスワードを4バイト(半角なら4文字、全角なら2文字)だけ比較してることになります。 ここでは、3回処理してますからパスワードは半角なら12文字、全角なら6文字です。

「58837083」は16進の文字コードで、メモリでは1バイトごと逆(リトルエンディアン) に表示されます。「83708358」としてバイナリーエディタで、 EX1.exeを16進データ検索してみましょう。これも倍直とよべるかもしれません