構造体のサイズは76バイトです(Windows 7 x64でテスト)。GetOpenFileNameAまたはGetSaveFileNameAが呼び出されているときに、アクセス違反の例外が発生します。実行時にウィンドウが76バイトではなく88バイトを読み取ろうとしていると思います。
あなたが見るならば、OPENFILENAME
struct
あなたは気づくでしょう:
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
32ビットプログラム(VC ++ 4は64ビットターゲットをサポートしていませんでした)では、これは正確に12バイトの違いに変換されます。発信者によって適切に設定されている限りlStructSize
、これはまったく問題にはなりません。procdump
Microsoft / Sysinternalsから使用して、正確な状態のミニダンプを取得する(またはデバッガーを接続して調査する)ことは価値があるかもしれません。発生する例外は、必ずしもstruct
サイズが原因である必要はありません。もしそうなら、この機能の下位互換性に関しては、Microsoftがボールを落とした可能性が高いです。明らかOPENFILENAME::lStructSize
に、のバージョン管理のためにあり、struct
遭遇したことが起こらないようにするためにあります。しかし、それでは、Windows2000より前の時代からコンパイラ/リンカーで構築されたプログラムについて話しています。
sthを書く。Spy++と同じように動作するLoader.exeのように。両方のAPIが呼び出されたときにアクセス違反の例外を飲み込む。それは公正な点です。例外処理をトップレベルに挿入すると、やりたいことができますが、例外の正確な原因(つまり、どの正確なメモリが上書きされたか)によっては、副作用が発生する可能性があります。
DLLインジェクションとAPIフックを使用します。GetOpenFileNameとGetSaveFileNameをカスタムDLLのカスタム実装にフックすることができます。私の実装では、構造体を修正し、修正した構造体を元のAPI呼び出しに渡します。これは最初のものとほとんど関係があります。あまり邪魔をせずに動作を修正できるので、全体として最も簡単で安全だと思います。以下をさらにお読みください。また、NInjectLibもチェックしてください。
SetWindowsHookを使用してウィンドウメッセージをフックしますか?!?!?!DLLの注入を容易にする以外にそれがどのように役立つかわかりません(1.および2の場合)。
バイナリファイルにパッチを適用します。HEXエディターを使用してパッチを適用することで、この構造体サイズの問題を修正することはできますか?これは、OPENFILENAME
がバイナリ内にあるか(初期化されたデータ)、スタックにあるか、またはヒープに割り当てられるか(簡単)によっては、最も難しい場合があります。
1.と2の可能なハイブリッドアプローチの1つは、次のとおりです。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
実行しているプログラムにちなんで名付けられたサブキーを追加します(例foo.exe
)
- その新しく作成されたサブキー内に名前を付けた
REG_SZ
値を作成し、その値を、ここで簡単に説明しようとするプログラムに設定します。Debugger
これにより、この古いアプリケーションのデバッガーが効果的にセットアップされます。これは、これから作成するデバッガーが、アプリケーションのコマンドラインを引数として受け取ることを意味します。エンドユーザーに対して透過的であり、ニーズに合わせて調整できるので便利です。
デバッガーを作成する必要があります。Win32が提供するデバッグヘルパーを使用できるため、このタスクは最初に思われるほど厄介ではありません。要点はデバッガーループにあります。CreateProcess
一般に、デバッグできるように適切なフラグを渡すことを使用して、ターゲットプロセスを自分で作成します。使用WaitForDebugEvent
とContinueDebugEvent
実行の制御。すべての実用的な目的で、デバッガーループはまったく必要ない場合があります。これは、ターゲットアプリケーションのメインスレッドを一時停止して作成し(CREATE_SUSPENDED
に渡すCreateProcess
)、最初にメインスレッドのを独自のコードにポイントしてCONTEXT
から、を呼び出すことができるためです。 ResumeThread(pi.hThread)
。このようにして、メインスレッドが開始する前に完了します。kernel32.dll
ただし、これにより、方法が原因で問題が発生する可能性があります。CreateThread
動作します(これには、新しいスレッドをWin32サブシステム(別名)に登録することが含まれますcsrss.exe
)。そのため、代わりにメモリ内のターゲットのIATなどにパッチを適用することをお勧めします。結局のところ、あなたは単に2つの機能に興味があるだけです。
トピックの詳細については、こことここの2つの記事を確認してください。
PyDbg
私は、PaiMeiに基づいてデバッガーを作成することを好みますが、そのようなPythonベースのデバッガーをで使用しようとしたことはありませんImage File Execution Options
。