簡易数値検索(新型32ビット版「UsaMimi32.exe」および64ビット版「UsaMimi64.exe」用)
簡易数値検索 目次
簡易数値検索の使い方・使用例●概要と注意点
■解析初心者の方が検索に失敗する原因
●参考スクリーンショット
●基本的な操作の流れ
●検索に失敗したときの対処方法
●検索のヒント
UsaTest2.EXEでのパラメータ検索・書き換え例
●UsaTest2.EXEでの検索例
■数値が明らかな場合の検索
■数値が不明な場合の検索
●UsaTest2.EXEでの数値・プログラムコード書き換え例
■検索結果リスト右クリックからの操作
■直接書き換え
▲ダンプ画面で書き換え
▲「選択アドレスへの直接書き込み・選択範囲の一括書き換え」ダイアログで書き換え
▲「10/16進数表形式入出力」ダイアログで書き換え
■固定化書き換え
■演算を実行して書き換え
■「構造体編集」ダイアログで書き換え
■改造コードを用いた書き換え
■デバッガ用改造コードで環境依存型変動アドレスを取得して書き換え
■パラサイトルーチンを用いた書き換え
■逆アセンブラを用いた書き換え
※「ダイアログ」はウィンドウの一種であり、この解説では「特定機能用の画面」を指します。
簡易数値検索の使い方・使用例
●概要と注意点■概要 この検索機能は、プロセスメモリ上での数値の検索に特化しており、数値をできるだけ簡単かつ確実に検索できることを目指しています。当ソフトウェア『うさみみハリケーン』のユーザーの方々から頂いた、検索機能に関連する多くのリクエストを実現するために、既存の「メモリ範囲を指定して検索」機能(以下「範囲検索」)とは別の検索機能として実装しました。 なお、「範囲検索」は、数値の検索に加えて、この「簡易数値検索」では対応していない、文字列・バイト列・ビット列および、連続する数値(シーケンス)の検索にも対応しています。そのため、状況に応じてこの「簡易数値検索」と「範囲検索」を使い分けてください。 また、当ソフトウェアには、他にも下記の検索機能を実装していますので、必要に応じて併用されることをお勧めします。 複数の数値・文字列・バイト列・ビット列からなるグループを指定して検索する「グループ検索」 正規表現を用いたバイト列・文字列の柔軟な指定方法に対応する「YARAルールでスキャン」 メモリ領域の属性やサイズおよび、先頭から任意の位置にある数値・文字列・バイト列・ビット列を指定して検索可能な「リージョン検索」 指定したアドレス群の格納値の推移を取得して表示する「特定アドレス格納値の時系列状況推移を表示」 自作プラグインから当検索機能のダイアログを表示する場合は、アクション指定用変数に0x00004000を指定してください。当ソフトウェア用プラグインのサンプルのソースコードは、当ソフトウェア作者Webサイト「Digital Travesia」のTools欄で配布しています。自作プラグインにより、当検索機能を用いた検索処理とプロセスメモリ書き換え処理を半自動化するならば、上記プラグインのサンプルのソースコードが参考になります。 ■注意点 この検索機能は、検索の確実性を高める上で多くのメモリを使用することから、高速に動作し空き物理メモリに十分な余裕がある、高スペックなPCでの使用が大前提になっています。そのため、古いWindows OSおよび低スペックPCでの使用も想定している、既存の32ビット版「UsaMimi.exe」では実装を見送りました。 この検索機能により、システムへの負荷が極端に高まる可能性があるため、当ソフトウェアの他の機能との同時使用はなるべく避けてください。 この検索機能では、検索該当アドレスと格納値の情報を全てメモリ上で処理するため、記録可能な検索該当情報の件数は、空きメモリの状況によって変化します。技術的には、「ファイルマッピング」という方法で、メモリ上で処理するよりもはるかに多くの検索該当情報を記録することも可能です。しかし、うさみみハリケーンはなるべくシステムへの負荷を抑え、またインストールフォルダ以外にはファイルを生成せず、かつUSBメモリにインストールして起動可能なポータブルアプリケーションを基本設計としているため、メモリ上で処理する方法を選択しました。 Windows 10以降での当機能使用時に、文字入力欄に数字等を入力しようとするとフリーズする可能性があります。これはMicrosoft IMEが原因ですので、Windowsの設定にある「Microsoft IME」を開き、「全般」の「互換性」欄にある「以前のバージョンの Microsoft IME を使う」をオンにすることで対処してください。なお、フリーズしたうさみみハリケーンは、UsaMimi64.exeを起動しプロセスリスト上で右クリックから強制終了できます。 ■解析初心者の方が検索に失敗する原因 過去に頂いた解析初心者の方々からのフィードバックによれば、解析初心者の方が検索に失敗する場合は、特に「2進数や16進数」、「数値表現」および「リトルエンディアン」への理解不足が原因となっています。当ヘルプでは、このようなプログラム解析の基礎用語の解説を用意していますので、解析初心者の方は参照されることを強くお勧めします。 |
●参考スクリーンショット
■メイン画面 |
●基本的な操作の流れ(数字は画面上の項目番号)
■1.検索する数値の形式を指定 検索する数値の形式を、整数のByte(1バイト)・Word(2バイト)・DWord(4バイト)・QWord(8バイト)および、浮動小数点数のfloat(4バイト)・double(8バイト)から指定します。例えば検索入力値が「500」ならば、数値500を格納できないByteの指定は、検索の内部処理で外しますので、通常は全部の形式を選択しておくことをお勧めします。また、検索入力値に小数点が用いられた場合は、「42.0」といった整数と同様であっても、あるいは増減比率の入力であっても、Byte・Word・DWord・QWordの指定を検索の内部処理で外します。 floatとdoubleについて、プロセスメモリ上での格納値が「42.51258」だがゲーム上での表示は「42」、「42.5」あるいは「43」といった、数値の格納値と表示値が異なるケースもあります。そのため、たとえばゲーム上での表示値「42」を入力値として指定すると、「41.0」から「43.0」の範囲内の数値を検索対象とするオプション「±1範囲で検索」を用意しました。 ちなみに特殊なケースとしては、一部のゲーム機のエミュレータでは、数値サイズが3バイトのケースや、数値がビッグエンディアンで格納されるケースもあります。 ■2.検索対象領域の属性を指定 この検索機能では、検索の効率化が図れるように、検索対象メモリエリアのアクセス属性を指定して検索対象メモリ領域を絞り込むことが可能です。逆に言えば、適切でないアクセス属性を指定すると、検索しても全くヒットしませんので十分に注意して下さい。一部のPCゲームで、各種データを格納するメモリ領域に実行のアクセス属性を設定するケースもありますので、初期設定では、読み込み・書き込み・実行のアクセス属性を選択しています。アクセス属性に関係なく検索したい場合は、「全アクセス」を指定して下さい。指定するアクセス属性のうち、読み込みのアクセスのみ可能な「読み」は、読み込みと書き込みのアクセスが両方とも可能な「読/書/実行」や「読み/書き」とは重複しません。 プロセスメモリ上のメモリ領域は、そのタイプが「PRIVATE」・「IMAGE」・「MAPPED」に分類されます。「IMAGE」はプロセスメモリに読み込まれたEXE・DLLファイルすなわちモジュールの領域です。「MAPPED」は各種ファイルの読み込み等に使われる領域で、たいていは検索対象から外すことができますが、エミュレータなどの特殊なアプリケーションのプロセスでは検索対象に含めた方が良いといえます。 ■2.検索対象アドレス範囲の指定 この検索機能では、検索対象とするプロセスメモリ上の範囲を指定することも可能です。指定範囲外のアドレスは検索しませんので注意が必要です。初期設定では、対象プロセスが使用可能な有効アドレス範囲の先頭と終端を入力欄に表示します。通常は初期設定のアドレス範囲で問題ありません。検索処理の効率化のため、指定されたアドレスは0x1000単位に修正されます。 保存済み設定の検索範囲終端アドレスが、対象プロセスではありえない明らかに異常なアドレスの場合は、設定読み込み時に自動的に修正されます。「UsaMimi32.exe」の検索対象となる、32ビットプロセスでは、実行ファイルやシステムの設定およびWindowsが64ビット版といった要素により、使用可能な有効アドレスの終端が変化するため、保存済み設定の検索範囲終端アドレスが不適切になるケースが生じます。 もし、「UsaMimi32.exe」で、有効アドレス終端が7FFEFFFFのプロセスを解析時に設定保存を行うと、有効アドレス終端がFFFEFFFFのプロセスの解析時にも、保存された設定が反映され検索範囲終端アドレスが7FFEFFFFに指定されてしまいます。そのため、「UsaMimi32.exe」では検索範囲終端アドレスをFFFEFFFFで保存しておくことをお勧めします。この場合、有効アドレス終端が7FFEFFFFのプロセスでは上記の自動修正が実行されます。また、このような検索範囲終端アドレスの不整合を確認および回避できるように、Shiftキーを押しながら当検索画面を表示すると、保存した設定の読み込みと反映をスキップするようにしています。 検索対象アドレスが、「対象プロセスが特定サイズで確保するメモリ領域」内にあることが分かっているならば、当ソフトウェア付属のプロセスモニター「猫原喜雨」さんでメモリ確保処理をモニタリングすると、そのメモリ領域のアドレスが簡単に判明するケースもあると考えられます。 ■2.検索時の比較方法の指定 数値を検索する際の比較方法を指定します。初回検索時には入力値との比較で一致や大小などを指定します。2回目以降の検索つまり絞り込み検索時には、入力値との比較に加えて値の変動に関する比較方法が追加されますので、改めて比較方法を選択して絞り込んでいきます。 初回検索時に、検索結果記録数が最大記録件数に達していると、検索対象のアドレスが記録外となり、以降の絞り込み検索が無駄になるケースもあります。そのため、初回検索時には、なるべく検索結果記録数が最大記録件数にならないよう、上記のアクセス属性やアドレス範囲の指定に加えて、比較方法の工夫も望ましいといえます。 比較方法の工夫の例として、PCゲームでのパラメータといった、現在値は不明だが数値範囲が推測できる状況ならば、初回検索の比較方法には「2つの入力値の間」を指定します。推測される数値範囲として、たとえば値10と99999を指定します。基本的に、ゲームのパラメータなどで、DWORDやQWORDの最大値まで使用することはありません。このように「2つの入力値の間」を用いれば、比較方法に下記「現在値は不明な値」を指定するよりも、はるかに効率的に検索可能です。 数値の現在値や形式が分からない場合は、比較方法として「現在値は不明な値」を選択します。これにより、初回検索では選択されている全部の数値形式でヒットさせておき、2回目以降の検索で変動関連の比較を行って絞り込んでいきます。この際、整数の符号の有無を選択可能です。現在値は不明だが明らかにゼロではない場合は、比較方法に「入力値とは異なる」を選択し、入力値として「0」を入力すれば、「現在値は不明な値」よりも不要なヒットを低減させることができます。この際、「+0」入力で符号付き整数の指定も可能です。 浮動小数点数の検索について、オプション「±1範囲で検索」指定は、誤認識や誤操作が起きないよう、初回検索と絞り込み検索での「2つの入力値の間」で検索時や、絞り込み検索での変動関連の検索時には無効化されます。ただし、このオプションが有効で、絞り込み検索での「入力値分だけ増加した」と「入力値分だけ減少した」では、浮動小数点数の色々な数値丸めの影響を考慮して、浮動小数点数の実増減幅と指定値で、差の絶対値が1以下ならばヒットとみなすようにしています(計算機イプシロンは使用せず)。また、初回検索と絞り込み検索での「入力値以上」、「入力値以下」および「入力値とは異なる」で検索時では、入力した浮動小数点数の、±1範囲全体が合致するかで判断しますので注意が必要です。 ■3.検索する数値の入力 検索する数値を半角英数字で入力します。数値範囲を入力するときは範囲の先頭と終端になる2つの値を入力します。入力された数値は以下のように認識されます。 ただし整数の16進入力で0x7FFFFFFFFFFFFFFF以上の値は認識できません。 ・整数は先頭が「0x」あるいは、数値が文字「abcdefABCDEF」のいずれかを含めば16進数での入力と判断 ・整数は先頭に「+」あるいは「-」で符号付き整数と判断(浮動小数点数は常に符号付き) ・整数は「符号付き」チェックボックスにチェックで符号付き整数扱い(浮動小数点数は常に符号付き) ・数値に小数点があれば、「42.0」といった小数点以下がゼロの値でも浮動小数点数扱い ■3.検索実行 初回検索および、2回目以降の検索つまり絞り込み検索を行います。絞り込み検索を行えば、現在記録されている検索結果の中からさらに新しい検索条件に該当するアドレスをリストアップします。 検索時に記録可能な該当件数は、この検索機能の画面を表示した時点での、当プロセスのプロセスメモリの状況に依存します。Windows 10のクリーンインストール環境では、約1億件の記録が可能でした(「UsaMimi32.exe」の場合)。しかし、当プロセスに干渉する常駐アプリケーションなど色々な要素により、記録可能な件数が大幅に減少するケースもありえます。記録内容をファイルに出力すればより多くの記録が可能ですが、実行環境や実行状況によってはシステムに悪影響を及ぼすと見られるため、メモリ上での記録処理を選択しました。 検索内容やPCスペック等によっては、1回の検索に数分かかるケースも想定されます。そのため、動作が停止しているように見えてもすぐに強制終了させずに、しばらく様子をみてください。また、処理の安全性のため、検索中に何らかのボタンを押すといった操作は行わないでください。15段階のアンドゥ処理を実現することおよび、処理の安全性と確実性を高めた副作用として、特に絞り込み検索の所要時間が増加しています。 検索結果に矛盾が生じるのを避けるため、初回検索時に指定した整数の符号付き・符号なしは、絞り込み検索時に変更することはできません。絞り込み検索時には、その入力内容にかかわらず初回検索時の符号の設定が適用されます。後述のとおり、整数の符号付き設定時は検索結果リストの数値形式背景色で確認可能です。基本的に、検索する整数の符号付き・符号なしは、まず符号なしで検索を行い、うまくいかなければ符号付きで検索するという順序で行います。もし、検索する整数が明らかに負の数になると分かっていれば、最初から符号付きで検索します。 検索結果は画面右側にリスト表示されます。検索結果リストでは、アドレス表示は書き込みができないメモリ領域内アドレスならば、アドレス表示部分の背景を緑にします。また、数値形式表示部の背景は、整数を符号付きで検索している場合には青色にします(浮動小数点数は常に符号付き)。 検索結果の件数が記録可能な件数を超えた場合は、検索結果件数に、記録された最後のアドレスを追記して表示します。もしも、絞り込み検索の結果として記録したアドレス群に目的のアドレスが含まれていなかった場合は、別途、この最後のアドレス以降を検索してください。 検索結果リストでアドレスを選択すると、ダンプ画面での表示アドレスを選択アドレスに変更します。また、アドレスを選択して右クリックのポップアップメニューから、「選択アドレスをコピー」等の選択アドレスに応じた処理を行ったり、各種書き込み処理やブレークポイント設定処理などを行うための画面を表示します。 ▲検索結果リスト上のアドレスを右クリックから呼び出せる特殊機能 選択アドレスへの直接書き込み・選択範囲の一括書き換え 10/16進数表形式入出力 固定化書き換え 選択範囲への演算実行 構造体編集 改造コード実行 ブレークポイントの挿入/削除 VEH用ブレークポイントの挿入/削除 メモリ領域の確保とアクセス属性変更 ■4.検索結果の操作 検索結果は、「一つ前に戻す」ボタンで、検索該当アドレス群を検索15回前まで戻すことができます。この際、検索時の値としては、各アドレス用に内部で記録している、最後にヒットした検索時の値を表示します。そのため、「一つ前に戻す」実行後には、各アドレスそれぞれで最後の検索該当時の値を元にして絞り込み検索を行うことに注意してください。この際、誤認識や誤操作を避けるため、比較方法に「入力値とは異なる」で入力値は「0」といった、検索内容に影響の少ない方法を指定して絞り込み検索を行い、各アドレス用に内部で記録している値を最新のものに更新することも可能です。 ■4.検索結果の表示の設定 検索結果の表示は、オプションの指定により、数値を16進数で表示したり、「UsaTest2.EXE +2148」といった該当モジュール先頭からの16進数相対値で表示することができます。 「アラインメント」は、簡単に言えば、プロセスメモリ上に配置される数値のアドレスが、アクセスの容易さと数値の形式のサイズに応じて調整されることを意味します。例えばDWordの数値ならばサイズが4バイトなので、配置されるアドレスの末尾は4の倍数である0・4・8・Cとなります。同様にサイズが8バイトのQWordならば、配置されるアドレスの末尾は0・8となります。「アラインメント」の指定は、このようなアドレスの調整を見込んで検索するアドレスを絞り込むことで、検索の効率化を図る仕組みです。このような、末尾がDWordのサイズ(4バイト)の倍数になるアドレスを「DWord境界」と呼び、同様にWordのサイズ(2バイト)の倍数ならば「Word境界」、QWordのサイズ(8バイト)の倍数では「QWord境界」と呼びます。実際には、このようなアドレスの調整が行われないこともあり、その場合はすべてのアドレスを検索する必要があります。 「表示件数」は検索該当アドレスのうち、リスト上で表示する件数の上限を指定します。表示する件数を増やせば、リスト上の表示用データの保持に使用するメモリも増加し、当検索機能への悪影響も生じうるため、表示する件数はなるべく少なく設定してください。 「直近の検索後に変動した数値をリアルタイムで強調表示」は、検索結果のアドレスに格納された値を監視し、もし検索後に変動があれば「今回検索」欄に変動後の数値を表示し、さらに数値の背景色を黄色にするオプションです。変動した数値の強調表示は、リスト内の目視できる項目分だけを行うことで処理の軽量化を図っています。このオプションを有効にして、その後無効にすると、「今回検索」欄には検索時ではなく無効にした時点での数値を表示します。このオプションはあくまで表示だけを変更するものであり、検索該当時の記録値は変更しません。なお、特定アドレスの変動後の数値は、検索結果リスト上で該当アドレス選択後に、ダンプ画面のステータスバーでも確認可能です。 ■5.その他の操作 「対象プロセスの実行を一時停止・再開」チェックボックスにより、検索時など必要なタイミングに合わせた、対象プロセスの実行の一時停止と再開が可能です。 「上の設定を保存」ボタンで、各種設定を保存し、次にこの検索画面を表示した際に設定内容を復元します。比較方法や入力値といった検索ごとに指定内容が変化するものは保存しません。Shiftキーを押しながら当検索画面を表示すると、保存した設定の読み込みと反映をスキップするようにしています。 設定ファイルの「UsaMimi32.ini」や「UsaMimi64.ini」内に、以下の形式で設定項目を追加することにより、当機能のウィンドウタイトルを任意の文字列に変更することができます。INIファイルをテキストエディタで編集する際に、文字コードUTF-8では保存しないでください。 SEN WinTitle=生命、宇宙、そして万物についての究極の疑問の答え 「範囲検索」は範囲検索機能の画面を表示します。 ■その他の操作(画面上部) 「縮小表示」ボタンは、画面の縮小表示と通常表示を切り替えます。「最前面表示」チェックボックスは、画面の最前面表示の切り替えを行います。 |
■設定の変更 検索に関する設定の変更で対処します。再検索にあたり以下の項目をひとつずつ試してみてください。 ・検索対象領域の「領域の属性」を「全アクセス」にする ・検索対象領域の「領域の属性」を「全タイプ」にする ・検索対象となる整数の符号付き・符号なし設定を変えてみる ・検索結果記録数が最大記録件数に達しているならば、アドレス範囲全体を複数に分けて検索する ・検索結果記録数が最大記録件数に達しているならば、検索対象の数値の形式を減らして検索する ・検索結果記録数が最大記録件数に達しているならば、比較方法を「現在値は不明な値」から「2つの入力値の間」(数値範囲を推測)に変更して検索する ・「アラインメント」の設定を「なし」にする ・「UsaMimi32.exe」でShiftキーを押しながら当検索画面を表示する(検索範囲終端アドレス設定を適切な値で表示させる) ■他のアプローチ ・初回検索は「現在値は不明な値(符号なし)」、絞り込み検索では「変動した」と「変動していない」のみで検索する(暗号化対策) ・検索結果記録数が最大記録件数に達しているならば、「グループ検索」を使用してみる |
●検索のヒント
フラグ検索等の効率化や、ポインタの検索などについては、上記の基本操作を踏まえた上で範囲検索用「検索のヒント」も参考にしてください。 ■変動検索を行うタイミング 2回目以降の絞り込み検索では、変動分の検索を効率よく行うために、検索を行うタイミングに注意して下さい。例えば検索目的のフラグが変化する直前に初回検索を行い、同フラグが変化した直後に絞り込み検索を行えば、検索結果として出力される変動該当箇所は最小限に抑えられ、効率的な検索が可能になります。また、対象アプリケーションにおいては変動該当箇所を増加させる不必要な操作を極力避けるようにして下さい。 ■変動検索での最初の絞り込み 2回目以降の絞り込み検索時には、プログラムの実行に伴い常に内容が変化するスタック領域のアドレスが多々ヒットします。そのため、絞り込み検索での最初の絞り込みとして、まず対象アプリケーションのウィンドウをアクティブ(最前面)にして何も操作をせず(スタック内容の変動は生じさせる)、次に当検索ダイアログをアクティブにしてから、「変動していない」で絞り込みを行うと、スタック領域分のヒットを多く取り除くことが可能になります。 ■検索範囲の特定 各種ゲーム機のエミュレータといった、特殊なメモリの使い方をするアプリケーションでは、まず点数等の、簡単に検索可能なアドレスを検索し、リスト上で同アドレスを選択し右クリックから「メモリ領域操作ダイアログを表示」で、そのアドレスが含まれるメモリ領域を特定します。それから、そのメモリ領域先頭アドレスと領域サイズ分を検索対象範囲の開始アドレスと終端アドレスに設定して検索すれば、簡単に目的のアドレスを探し出せることがあります。 ■フルスクリーンのゲームでの検索 フルスクリーン表示しかできないゲームでは、ウィンドウ化ツール「DXWnd」などを使うことで、画面をウィンドウ化してから検索してください。 ■<参考>環境依存型変動アドレス PCゲーム及び各種ゲーム機等のエミュレータでは、アプリケーションが動的に確保したメモリブロックにパラメータ等のデータを格納した場合、そのパラメータのアドレスはOSやメモリ実装容量等に依存する環境依存型変動アドレスとなります。この場合、検索結果のアドレスを直接指定する改造コードを作成して公開しても、解析に用いた環境以外では大抵使用できません。そのため、このような環境依存型変動アドレスに対しては、当ソフトウェア用のポインタ型改造コードやデバッガ用改造コード等で対処してください。なお、このような環境依存型変動アドレスの解析は、基本的にデバッガを用いてパラメータ変動やメモリ領域確保処理を追いかけてポインタを探すことになります。 デバッガ用改造コードでの、使用時に毎回デバッガでアタッチする手間を省ける、パラサイトルーチンを使ったアプローチもあります。この場合は、デバッガで解析した対象アドレスへのアクセス処理に、対象アドレスをメッセージボックスで表示または、対象アドレスの値を任意のアドレスに書き込ませるといったパラサイトルーチンを埋め込みます。これは特に、複数のポインタが連なる「多重ポインタ」が解析困難な際に役立つアプローチです。このアプローチの具体的な手順は、環境依存型変動アドレスの解説にあるアプローチ例を参照してください。ちなみに日本のPCゲームでは、ポインタが13以上連なる多重ポインタでパラメータを管理するケースもあります。 |
UsaTest2.EXEでのパラメータ検索・書き換え例
●UsaTest2.EXEでの検索例
当ソフトウェア「うさみみハリケーン」に付属する「UsaTest2.EXE」は、「うさみみハリケーン」のプロセスメモリ編集機能や検索機能をテストするための、32ビット版のソフトウェアです。まず「UsaTest2.EXE」を起動し、それから「うさみみハリケーン」の新型32ビット版である「UsaMimi32.exe」を起動して、表示されるプロセスリスト上で「UsaTest2.EXE」をダブルクリックにより、「UsaTest2.EXE」のプロセスをオープンします。さらに「うさみみハリケーン」のメニュー「検索」→「簡易数値検索」で検索画面を表示します。 ■数値が明らかな場合の検索 まず、UsaTest2の初期パラメータ値である500を入力して初回検索を行います。数値検索の設定は初期設定のままです。現在の数値が明らかなので、「比較方法」には「入力値と同じ」を使用します。「初回検索」ボタンで検索を実行します。初回検索の結果が画面右側のリストに表示され、自動的に絞り込み検索モードになります。 次に、UsaTest2の初期パラメータ値を600に増加させて、2回目の検索つまり絞り込み検索を行います。「比較方法」は「入力値と同じ」のままで、検索する数値を600に書き換えて、「絞り込み検索」ボタンです。 UsaTest2のパラメータ値500が600に増加したので、「比較方法」としては以下のものでヒットすることになります。 ・「入力値と同じ」で数値の入力は600に書き換え ・「入力値以上」で数値の入力は500のまま ・「入力値とは異なる」で数値の入力は500のまま ・「2つの入力値の間」で数値範囲の入力は「599」と「601」 ・「変動した」で数値の入力は500のまま ・「増加した」で数値の入力は500のまま ・「入力値分だけ増加した」で数値の入力は100に書き換え ・「増加分は2つの入力値の間」で数値範囲の入力は「99」と「101」 ・「増加率(%)は2つの入力値の間」で数値範囲の入力は「19」と「21」(増加分100÷元の値の絶対値500=0.2で20%の増加) この例ではパラメータのアドレスが特定できていますが、本来は、この後さらにUsaTest2のパラメータ値を増加させて、必要に応じて入力値も書き換えてから、上記の比較方法で絞り込み検索を行います。また、UsaTest2のパラメータ値はそのままで、「比較方法」に「入力値と同じ」や「変動していない」を指定する絞り込み検索も使用可能です。この変動したケースと変動していないケースの絞り込み検索を組み合わせると、片方のケースのみ使用するよりも効率的に絞り込むことができます。 ■数値が不明な場合の検索 まず初回検索を行います。数値検索の設定は初期設定のままです。現在の数値は不明なので、「比較方法」には「現在値は不明な値(符号なし)」を使用します。なお、このようなパラメータでは、DWORDやQWORDの最大値まで使用する可能性は低いため、比較方法「2つの入力値の間」で推測される数値範囲として値10と99999を指定するアプローチもあります。数値範囲を指定することにより、「現在値は不明な値」を使用するよりも、はるかに効率的に検索可能です。 初回検索の実行後に、UsaTest2の初期パラメータ値を増加させて、2回目の検索つまり絞り込み検索を行います。「比較方法」は「増加した」を指定して「絞り込み検索」ボタンです。 UsaTest2のパラメータ値が増加したので、「比較方法」としては以下のものでヒットすることになります。 ・「変動した」で数値の入力は行わない ・「増加した」で数値の入力は行わない ・「増加率(%)は2つの入力値の間」で数値範囲の入力は「5」と「30」(増加分の範囲は目視で判断した) この後さらにUsaTest2のパラメータ値を変動させるかあるいはそのままで、「変動した」、「変動していない」、「増加した」、「減少した」などの、変動に関する比較方法による絞り込み検索を行います。絞り込みが進んだら、該当アドレスに数値を書き込んで変化をみる等により、パラメータのアドレスを確定します。ちなみに、この現在値が不明なパラメータは、動的に確保したメモリ領域上に格納しており、基本的に実行ごとにそのアドレスが変化します。そのため、実行環境によってアドレスが異なる「環境依存型変動アドレス」になります。 |
●UsaTest2.EXEでの数値・プログラムコード書き換え例
■検索結果リスト右クリックからの操作 数値が明らかなパラメータのアドレスが402148に絞り込めたら、検索結果リスト上で同アドレスを選択して右クリックから、各種処理を行うことができます。たとえば、「直接書き込みダイアログを表示...」を選択すれば、指定アドレスへの書き込みを行う「選択アドレスへの直接書き込み・選択範囲の一括書き換え」ダイアログを表示し、パラメータの書き換えを行うことができます。数値を指定して書き込む際の、10進数や16進数の進数指定および、複数の数値を1度に指定して書き込むシーケンス書き込みについては、解説「検索・書き込み・置換での特殊なデータ入力」を参照してください。ちなみに、絞り込み結果が少なくなった時点で「直近の検索時の値を書き込む」を使えば、この書き込み後に生じる挙動の変化、つまり検索後に変動した値が検索時の値に戻ることから、目的のアドレスの特定に役立つケースがあります。 ▲各ダイアログの解説 直接書き込みダイアログ 10/16進数表形式入出力ダイアログ 固定化書き換えダイアログ 演算実行ダイアログ 構造体編集ダイアログ 改造コード実行ダイアログ ブレークポイント設定ダイアログ VEH用ブレークポイント設定ダイアログ メモリ領域操作ダイアログ ■直接書き換え パラメータのアドレスに、ダンプ画面、「選択アドレスへの直接書き込み・選択範囲の一括書き換え」ダイアログあるいは、「10進/16進数表形式入出力」ダイアログから任意の数値を書き込みます。これらの書き込みは手動かつ単発の書き込みであり、数値を固定化するものではありません。 ▲ダンプ画面で書き換え ダンプ画面上でキーボード入力により新しい値を書き込みます。パラメータの値はリトルエンディアンで格納されていることに注意が必要です。ダンプ画面のステータスバーには、整数の符号あり・符号なしの値が10進数で表示され、Nキーで浮動小数点数表示への切り替えもできます。ダンプ画面での各種操作については、「ダンプ表示ウィンドウでの基本操作」を参照してください。 ▲「選択アドレスへの直接書き込み・選択範囲の一括書き換え」ダイアログで書き換え 「選択アドレスへの直接書き込み・選択範囲の一括書き換え」ダイアログを表示して書き換えます。 ▲「10/16進数表形式入出力」ダイアログで書き換え 「10/16進数表形式入出力」ダイアログを表示して書き換えます。左クリックで対象の数値を選択後、新しい数値を入力してEnterキーで確定(書き込み)です。 ■固定化書き換え 「固定化書き換え」ダイアログから、パラメータのアドレスに任意の数値を書き込みます。この機能では、任意の数値を一定の間隔ごとに書き込む処理を自動化することで、数値の固定化を行います。 ■演算を実行して書き換え 「選択範囲への演算実行」ダイアログから、パラメータのアドレスの格納値に任意の演算を行った結果を書き込みます。 ■「構造体編集」ダイアログで書き換え 「構造体編集」ダイアログから、パラメータのアドレスや数値表現形式を指定して書き込みます。この機能では、Byte/Word/DWord/QWord/Double/Floatといった各種の数値表現形式の数値や、各種文字コードの文字列および、ビット列といった異なる型のデータ群を、あらかじめ指定していた内容で一括して書き換えることができます。加えて、指定更新周期での自動書き換えにも対応しており、特定アドレス格納値の固定化が可能です。また、モジュール相対アドレスやポインタを使用したアドレス指定にも対応しているため、多重ポインタを展開することもできます。 ■改造コードを用いた書き換え 「改造コード実行」ダイアログから、改造コードを使ってパラメータを書き換えます。改造コードではパラメータのアドレスと書き換えるためのバイナリデータを指定しています。この改造コードを用いた書き換え時には、1秒(1000ミリ秒)毎に繰り返して書き換えたり、特定キー押し下げ状況やジョイパッドの特定ボタン押し下げ状況を1秒ごとにスキャンして書き換えることも可能です。繰り返し書き込む場合は「コード実行」ボタン押し下げ前に、設定項目「自動更新」の有効化(チェック)が必要です。また、特定キーや特定ボタンの押し下げを検知して書き換える場合は、事前に設定項目「コード実行トリガー」を有効化しておきます。 ■デバッガ用改造コードで環境依存型変動アドレスを取得して書き換え 検索により判明したパラメータのアドレスに、「ブレークポイントの挿入/削除」ダイアログでブレークポイントを設定します。このダイアログは、検索結果リスト上での右クリックか、メニューの「デバッグ」→「ブレークポイントの挿入/削除」で表示します。ブレークポイントを設定することで、プログラムコードのどこからこのパラメータの読み書きを行っているかを解析します。まず、デバッガとしてアタッチを行い、そして「書き込みByte」のブレークポイントを設定します。これで、このパラメータに増加など書き込み処理が行われたら、ブレークポイントでブレークし、その時点のプログラムコードの実行情報が表示されます。「EIP=」(64ビットプロセスでは「RIP=」)が、パラメータに書き込んだプログラムコードの直後の位置を意味します。 このケースではパラメータのアドレスは543F60であり、これは環境依存型変動アドレスです。ここではパラメータのアドレスが表示されていますが、一般的な解析においては、このようなアドレスは検索により特定します。 デバッガでアタッチ後、パラメータのアドレスに書き込みのブレークポイントを設定します。これにより、UsaTest2の「パラメータ増加」ボタンを押して、パラメータの格納値が増加すればブレークします。 メニューからこのダイアログを表示するならば、メニューの「デバッグ」→「ブレークポイントの挿入/削除」です。 判明したプログラムコードの位置を、逆アセンブラで確認します。ダイアログの表示はメニューの「デバッグ」→「モジュールを逆アセンブル」です。 表示された逆アセンブルコードリストの読み方については、解説「基礎用語 逆アセンブルコードリスト」を参照願います。 アドレス00401404にある、「ADD DWORD PTR [EAX], 0AH」という処理、すなわち「EAXレジスタの格納値がアドレスとなるDWord(4バイト)の値に10を加算する」という書き込みを行った結果ブレークしたことが分かります。この解析結果により、環境依存型変動アドレスに対処するデバッガ用改造コードとしては、以下のように記述します。 ターゲット:UsaTest2.EXE 対象:パラメータ現在値(環境依存型変動アドレスに格納) ハードウェアブレークポイント(実行)のアドレス:401404 ブレークに必要な動作:パラメータの増加 ブレーク時ニーモニック:ADD DWORD PTR [EAX], 0AH ターゲットアドレス:EAXレジスタに格納 また、ポインタ型の改造コードでの対処も可能です。逆アセンブラ上でパラメータ書き込み処理を観察すると、以下のようになっています。 004013F0 A14C214000 MOV EAX, DWORD PTR [0040214CH] 004013F5 0500100000 ADD EAX, 00001000H 00401404 83000A ADD DWORD PTR [EAX], 0AH これは、ポインタであるアドレス40214Cの格納値に、0x1000を足したものがパラメータのアドレスで、そのアドレスを指定してパラメータ加算処理を行っていることを意味します。また、その処理の近辺で値0x65との比較処理を行っており、これがパラメータ最大値と推測できます。 以上により、このパラメータの値を最大値に書き換える改造コードは以下になります。 *40214C>1000-65 なお、ポインタとオフセット(上の例で0x1000)が指すアドレスが次のポインタとなる、ポインタとオフセットの組み合わせが何重にも連なる「多重ポインタ」の場合は、解説「基礎用語 環境依存型変動アドレス」のアプローチ例を参考に対処してください。 プロセスメモリにロードされたEXEファイルやDLLファイルのことを「モジュール」と呼びます。プロセスメモリにロードされたEXEファイル、すなわちメインモジュールのアドレスは、ASLRというセキュリテイ関連機能により、必ずしも固定とはなりません。ただし、付属のPEエディタ「UMPE」を使ってEXEファイルの設定を書き換えることで、このASLRを無効化することも可能です(リンク先にASLR無効化方法の説明あり)。 ASLRによりメインモジュールのアドレスが起動ごとに変動する場合は、プロセスメモリ上のメインモジュール領域内にあるポインタも変動するため、メインモジュールのアドレス+相対値でポインタを指定する必要があります。上の例でいえば、メインモジュールのアドレス+0x214Cをポインタに指定します。 下の画像はポインタの格納値(パラメータのアドレス-0x1000)を検索した結果です。16進数表示とモジュール相対アドレス表示のオプションを有効にしています。なお、このケースで、パラメータのアドレスを基にポインタを探すならば、パラメータのアドレス±0x2000程度を数値範囲として検索するという方法があります。 ■パラサイトルーチンを用いた書き換え 上記でパラメータの増加処理を行うプログラムコードの位置が判明しているので、「パラサイトルーチン作成」機能を使って、環境依存型変動アドレスであるパラメータのアドレスを、メッセージボックスで表示させることも可能です。この場合はデバッガでのアタッチやブレークポイント設定は不要です。この機能のダイアログはメニューの「デバッグ」→「パラサイトルーチン作成」で表示します。 ダンプ画面上でアドレス401407を選択した状態でパラサイトルーチン作成ダイアログを開き、画面左側上部「ジャンプ元アドレス」が401407となっている状態で、画面右側の「テンプレート出力」から「レジスタ取得・表示」を選択します。このテンプレートは、このケースでターゲットアドレスが格納されるEAXレジスタを表示する設定になっているので、そのまま使用します。まず「プレビュー」ボタンでパラサイトルーチンに問題がないか確認し、「ジャンプ+ルーチン(プレビュー分)書き込み」ボタンを押します。 これで、パラメータが増加したら、メッセージボックスでターゲットアドレスを意味するEAXレジスタの値が表示されます。 メッセージボックスの表示内容は、Ctrl + Cキーでコピー可能です。 ターゲットアドレスが確認できたら、「ジャンプ部分書き戻し」ボタンでパラサイトルーチンを無効化します。 パラサイトルーチンの活用法として、パラメータ減少の処理の直後に「パラメータを100(16進数で0x64)にする」という処理を追加で書き込めば、上記固定化書き換え同様、パラメータの減少を回避することができます。この場合は、デバッガでパラメータ減少時にブレークさせて減少の処理のアドレスを特定し、画面左側上部「ジャンプ元アドレス」の指定が適切か確認後に、パラサイトルーチン作成時のテンプレート出力は「基本パラサイトルーチン」を選択します。 ■逆アセンブラを用いた書き換え これまではパラメータの数値を書き込むアプローチを行ってきました。しかし、デバッガや逆アセンブラでプログラムコード上のパラメータの増減処理が特定できることから、その処理そのものを書き換えるアプローチも可能になります。たとえば、パラメータの減少処理を無効化するアプローチです。 アドレス402148に格納されたパラメータの減少処理を無効化してみましょう。上記のデバッガ用改造コード作成時と同様に、デバッガでアタッチしてから、このアドレスに「書き込みByte」のブレークポイントを設定して、UsaTest2の「パラメータ減少」ボタンを押してブレークさせます。このダイアログは、検索結果リスト上での右クリックか、メニューの「デバッグ」→「ブレークポイントの挿入/削除」で表示します。 判明したプログラムコードの位置を、逆アセンブラで確認します。ダイアログの表示はメニューの「デバッグ」→「モジュールを逆アセンブル」です。ブレークしたアドレスの直前の処理がパラメータを減少させる処理です。 アドレス004013B6にある「SUB DWORD PTR [00402148H], 64H」で、アドレス402148にあるDWord(4バイト)の値から0x64すなわち10進数で100を減算させています。この減算処理を無効化する方法は色々ありますが、アドレス004013B6を選択し右クリックで表示されるメニューから「全選択列をNOPで埋める」でも可能です。これにより、減算処理そのものを、実行しても意味のない命令であるNOPの連続で上書きします。 これで、アドレス402148に格納されたパラメータ用の「パラメータ減少」ボタンを押しても、パラメータが減らなくなりました。 この逆アセンブラでは、指定した逆アセンブルコードを、16進バイト列あるいはアセンブリ言語のニーモニックを使って修正することができます。たとえば、上で解析したパラメータ減算処理の、減算する値を0x64からゼロに修正することで、減算処理を無効化します。 上記で解説した、逆アセンブルコードを書き換えるアプローチは、プロセスメモリ上に読み込まれた実行ファイルであるモジュールを対象としたものです。実行ファイルそのもので、該当する書き換え位置すなわちオフセットを知りたい場合は、逆アセンブルコードリスト上での右クリックで表示されるメニューから、「アドレス-オフセット変換モード」を選択します。これにより、プロセスメモリ上のアドレス表示部に、実行ファイル内の該当オフセットが表示されます。 プログラム解析初心者の方は、各種アプローチの練習として、「UsaTest2.EXE」の64ビット版である「UsaTest2_x64.exe」と64ビット版「UsaMimi64.exe」で、上記の色々なアプローチを自分なりに試されることをお勧めします。 |