場合によっては、プログラム(ドライバーを含む)のリバース開発中に、特定のレジストリキーで何らかのアクションを実行する瞬間にその実行を中断することが必要になる場合があります;この状況では、レジストリキーのブレークポイントの文書化されていない機能を使用できます。
初めて、レジストリキーのブレークポイントがWindows XPに登場しました
BREAK_ON_OPEN
フラグ(デバッグフラグ)でレジストリキーを開くとき、またはそのようなキーの一部としてサブキーを作成するときに、カーネルはint 3命令を実行する機能を実現しました。
図 1:CmpDoOpen関数のスニペットこの機能は、サービスパックがリリースされる前からカーネルに登場しており、デバッグ(「チェック済み」)バージョンのカーネルをインストールする必要はありませんでした。 同時に、
BREAK_ON_OPEN
フラグを設定するためのAPI関数がなかったため、HEXエディターでレジストリハイブを使用してファイルを編集することによってのみ、このフラグをキーに設定できました。
Windows Vista以降、使用可能なデバッグフラグのリストが拡張され、NtSetInformationKey API関数を介してこれらのフラグを設定できるようになりましたが、機能自体はカーネルのデバッグバージョン(Windows Driver Kitから取得可能)にのみ残っていました。
タブ。 1:デバッグフラグの可能な値旗 | 価値 | ご注意 |
---|
BREAK_ON_OPEN | 0x01 | キーオープニング |
BREAK_ON_DELETE | 0x02 | キーの削除 |
BREAK_ON_SECURITY_CHANGE | 0x04 | セキュリティ記述子の変更 |
BREAK_ON_CREATE_SUBKEY | 0x08 | サブキーを作成する |
BREAK_ON_DELETE_SUBKEY | 0x10 | サブキーを削除 |
BREAK_ON_SET_VALUE | 0x20 | 設定値 |
BREAK_ON_DELETE_VALUE | 0x40 | 値を削除 |
BREAK_ON_KEY_VIRTUALIZE | 0x80 | キー仮想化 |
デバッグフラグを設定するには、NtSetInformationKey関数を呼び出して、デバッグフラグを設定する最初の引数としてレジストリキーのハンドルを渡す必要があります。 2番目の引数はKeySetDebugInformationで、最後の2つの引数は、デバッグフラグ(または2つ以上のフラグの組み合わせ)の値を含むダブルワード(DWORD)を含むバッファーを記述する必要があります。
説明したブレークポイントをアクティブにするには、CmpRegDebugBreakEnabledカーネル変数の値を1に設定する必要があります。
例
例として、マウントされたボリュームに関する情報が保存されているレジストリキー「
HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices
」に値を書き込む瞬間をキャッチして、そこにデータを書き込むWindowsコンポーネントを決定してみましょう。 これを行うには、
BREAK_ON_SET_VALUE
デバッグフラグで指定されたキーをマークし、CmpRegDebugBreakEnabled変数の値を1に変更して
BREAK_ON_SET_VALUE
、テストディスクをフォーマットしてからマウントします。
その結果、ブレークポイントがトリガーされ、次のコールスタックが表示されます。
コールスタックは、レコードがmountmgrコンポーネントを開始することを明確に示しており、そのコードで必要なnt!RtlWriteRegistryValueコールを見つけることができます。
fffff801`46d6fca4 ff15fe44ffff call qword ptr [mountmgr+0x31a8 (fffff801`46d641a8)] // nt!RtlWriteRegistryValue fffff801`46d6fcaa 488d55b7 lea rdx,[rbp-49h]
結論
説明した機能は、カーネルとドライバーのデバッグに直接関連する問題を解決するため、および指定されたレジストリキーを使用する調査中のシステムイメージ内のプログラムを検索するなど、サードパーティのタスクを解決するために使用できます。