NtQueryObject

NtQueryObject はハンドルと動作モードを与え、構造体ポインタで結果を受け取る典型的なNativeAPI。たとえば NtQuerySystemInformation(SystemHandleInformation, ... で取得したハンドルテーブルを順繰りに喰わせてやることで、システム全体のハンドルに関する情報を列挙することができる。


できるのだが、この NtQueryObject が特定条件下でデッドロックを起こす。検索してみた感じだと次のような条件が関係しているらしい。

  • システムプロセスの保有するハンドルである。たとえば
  • ハンドルにSYNCフラグがたっている
    • たぶん (GrantedAccess & SYNCHRONIZE) == TRUE ということ

これらを事前に回避すること以外に対策はないっぽい。


一方 SysInternals の handle.exe ではこの問題を回避している。どのようにしてか。
答え=>NtQueryObject を使わない。
handle.exe ではドライバを使ってオブジェクトディレクトリを構成するメモリを直接参照している。このこともデッドロックの有効な回避策がないことを感じさせる。undocumentedな世界でもこういった問題のある挙動に出くわすのは珍しい。

参考:CodeProject - Debug Tutorial Part 5: Handle Leaks - Displaying Handle Information In User Mode