2016-06-22 7 views
3

Microsoft Wordのロードされたモジュールを調べているうちに、非常に奇妙なことが起こりました。ロードされたすべてのDLLの場所を出力するための小さなプログラムを書きました。ここで出力されます:私は私のPC上でこれらのモジュールを見つけるためにしようとすると実際には存在しないプロセスのロードされたモジュールの取得

Loaded modules using snapshot's WinApi

が、私は与えられた場所でそれらを見つけることができませんでしたが、しかし、別の場所で:

The DLL's actual location

なぜDLLのパスが違うのかわからなかったし、VFSと何か関係があるとは思うが、Googleでもそれに関連するものは見つけられなかった。

つまり、何らかの形でProcess ExplorerがDLLの元の場所を表示するように管理しています。

Process Explorerがどのようにそれを行うのか、私のコードでどのように同じ結果を達成できるのか教えていただけますか?

--------------- EDIT ----------------

  1. 私も持っていますDLLを挿入しようとすると、WINWORDのLDRを歩いても、元のDLLの場所が表示されません。

  2. SysinternalのListDllsユーティリティは、元のDLLの場所も表示しません。 今のところ、Process Explorerだけが正しい場所を示しています。

+0

リンクおそらく?? – alk

+0

@alk:それらがソフト/ハードリンクであった場合、それらはユーザーに表示されます。 – IInspectable

+0

@alkこれらはリンクではありません。 – Aviv

答えて

3

Office 2016は、一部のパスをリダイレクトして仮想化するためにApp-Vを使用しています。これはDLLを少し見つけるのを複雑にします。プロセスエクスプローラは、DLLを見つけるために若干複雑なメソッドを使用しています。一般に、プロセスは、次のとおりです。

  1. TH32CS_SNAPMODULETH32CS_SNAPMODULE32フラグと、ツールのヘルプ32スナップショットを作成します。
  2. Module32FirstおよびModule32Nextを使用して、プロセスのモジュールに関する情報を入手してください。
  3. 私のOffice 2016でApp-V dllファイルが存在するシンボリックリンクを解決するには、ファイルを開き、解決されたパスを取得するためにGetFinalPathNameByHandleを使用します。

実装例(これは主要\\?\含むパスであろうが、それは除去するのに十分に簡単です注意してください。):プロセスエクスプローラは、Sysinternalsのによって書かれたことを

// Obtain the Process ID however you like. I used GetWindowThreadProcessId. 
if (processId != 0) 
{ 
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId); 
    if (snapshot != INVALID_HANDLE_VALUE) 
    { 
     MODULEENTRY32W moduleInfo = { 0 }; 
     moduleInfo.dwSize = sizeof(MODULEENTRY32W); 

     BOOL ok = Module32FirstW(snapshot, &moduleInfo); 
     if (!ok) 
     { 
      // The read failed, handle the error here. 
     } 
     do 
     { 
      HANDLE hFile = CreateFileW(moduleInfo.szExePath, 
             0, 
             FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
             NULL, 
             OPEN_EXISTING, 
             FILE_ATTRIBUTE_NORMAL, 
             NULL); 
      if (hFile) 
      { 
       WCHAR realPath[MAX_PATH]; 
       DWORD result = GetFinalPathNameByHandleW(hFile, 
                 realPath, 
                 MAX_PATH, 
                 FILE_NAME_NORMALIZED); 
       if (result > 0) 
       { 
        wcout << L"Module: " << realPath << endl; 
       } 

       CloseHandle(hFile); 
      } 
      else 
      { 
       wcout << L"Module Name: " << moduleInfo.szExePath << endl; 
      } 
     } while (Module32NextW(snapshot, &moduleInfo)); 

     CloseHandle(snapshot); 
    } 
} 

注意、および低レベルの情報を使用している可能性があります。このメソッドは、2016年のインストール時にDLLを解決します。

+0

可視化されたプロセス内でのみ利用可能になるか、他のプロセスも同様に呼び出すことができますか? – Aviv

+1

プロセスにスレッドを挿入することなく、独立したスクラッチC++ conoleアプリケーションでそのコードのテストを実行しました。私のインストールはあなたのものとは少し異なりますので、エッジケースの問題があるかもしれませんが、Process Explorerがこのメソッドを使用していて、取得したすべてのDLLが報告された場所に物理的に存在します。 – theB

+0

ありがとう。あなたは本当に私を助けました – Aviv

関連する問題