パッチ(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 を起動してみましょう。
「Config」ボタンを押して、環境設定のチェックを確認して終了します。
これで、
.pat ファイルが
FireFlower3 に関連付けされました。
ollydbg107j.patをOLLYDBG.EXEのあるフォルダで左クリックすれば、
FireFlower3 が起動してパッチが完了します。
※ OllyDbgのメニューを日本語化するものではありません。
OllyDbg を利用して 練習1 をやってみましょう!
解析の流れとして
- ウイルスチェックをする。
- バックアップをとる。
- 制限を確認する。
- ファイルアナライザーなどで、ファイルの全体像を確認する。
- パスチェック、日数チェックなとの処理場所を探す。
一箇所とは限りません!
- 文字列から探す。
- WinAPI(関数)から探す。
- 逆アセを眺めカンで探す。
- 制限を解除する。
ここでは文字列から処理ルーチンを探してみましょう。
「C:\WINDOWS\SendTo」に「OllyDbgのショートカット」を入れておけば、
「EX1.exe」上で「右クリック」→「送る」→「OllyDbg」で読込んで起動します。
これは、実行ファイルがメモリ内部に展開されて、メモリ全体を一つの町とすると、
各大字(セグメント)のようすを表しています。
左上 : Disassembler window | コードセグメントの内容を表示 |
右上 : Registers window | レジスタの内容を表示 |
左下 : Dump window | データセグメントの内容を表示 |
右下 : Stack window | スタックセグメントの内容を表示 |
各部分で表示形式を変化することができ、コードとレジスタ部が大切です。
まず練習1を起動して、どのような事が起こるか確認します。
メニューの「Debug」→「Run」か「F9」ボタンを押し、
練習1が起動したら、適当なPasswordを入れ「OK」ボタンを押します。
「パスワードが違います!!」とのメッセージが出てしまいました。
今回は、このメッセージから処理ルーチンを探すのが目的です。
リスタートします。「Debug」→「Restart」 か 「Ctrl+F2」
右上の適当な部分で「右クリック」→「Search for」→「All referenxed text strings」
今回は、文字列が二つしかありませんが本来はかなりの文字列があるもので、
通常は「右クリック」→「Search for text」で文字列「パスワードが違います!!」をさらに検索します。
カーソルを文字列「パスワードが違います!!」上で「左ダブルクリック」しましょう。
この文字列を利用してるコードウィンドウが表示されます。
逆アセが読みやすいようにウィンドウを調節します。
004010D6 の GetDlgItemTextA で文字を得
004010F8 MOV EDI,EX1.0040208A | 入力した文字の場所をEDIに入れ |
004010FD CALL EX1.00401138 | 401138番地の処理に移動して |
00401102 TEST EAX,EAX | EAXの値が同じか調べ |
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してジャンプは定番です。
パッチとして考えられるのは
- CALL先に行きEAXの値を変える
- EAXの値が同じか調べない
- 違いますへジャンプしない
ここでは、「違いますへジャンプしない」で、試してみます。
00401104を選択して「右クリック」→「Binary」→「Fill with NOPs」
これは選択行をNOP(なにもしない)命令に換えます
試しに実行してみます。「F9」ボタンを押してみます。
うまくいきました、しかし、これはメモリ上の変化で試したのであって、
実際のファイルは換わってません。換えるためにパッチをつくりましょう。
パッチの為にメモリ上のアドレス(00401104)じゃなく
実アドレス(バイナリエデッタでのアドレス)を知る必要があります。
00401104を選択して「右クリック」→「View」→「Executable file」
「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,EAX | EAXを初期化=0にする |
0040113A SUB DWORD PTR DS:[EDI],58837083 | データから58837083引く |
00401140 JNZ SHORT EX1.00401159 | ゼロフラグが立たないとジャンプ |
00401142 ADD EDI,4 | EDIに4加え読み込むデータの位置を変える |
00401145 SUB DWORD PTR DS:[EDI],5B818F83 | データから5B818F83引く |
0040114B JNZ SHORT EX1.00401159 | ゼロフラグが立たないとジャンプ |
0040114D ADD EDI,4 | EDIに4加え読み込むデータの位置を変える |
00401150 SUB DWORD PTR DS:[EDI],48816883 | データから48816883引く |
00401156 JNZ SHORT EX1.00401159 | ゼロフラグが立たないとジャンプ |
00401158 INC EAX | EAXに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進データ検索してみましょう。これも倍直とよべるかもしれません