4

DLLの依存関係リストをプログラムで取得する必要があります。ここで私はこの仕事を解決しようとしています:C++:処理中にDLLを読み込まずにネイティブDLLの依存関係を取得する

それは動作します。しかし、あなたが見ることができるように、プロセスにDLLをロードします。そして、私はこの場所で問題に遭遇しました:LoadLibraryExは、プロセスがすでに同じ名前のDLLをロードしていた場合にnullptrを返します。私はよく分からない

nullptr

は、同じプロセスに同じ名前(位置が異なる)との2つのDLLをロードすることができますか?私はそう信じる。なぜLoadLibraryExnullptrを返すのですか?どういうわけかDLLをロードせずにDLLの依存関係を取得することは可能ですか?

+0

PE(Portable Executable)ファイル(.dllまたは.exe)のインポートセクションを解析する必要があります。 – VTT

+0

ドキュメントで言及されているように['DONT_RESOLVE_DLL_REFERENCES'は廃止され、すべてのバージョンのウィンドウでサポートされていない可能性があります](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684179(v = vs。 85).aspx)では、代わりにデータファイルとしてロードする必要があります。 – Mgetz

+0

'LoadLibraryExは、プロセスが既に同じ名前のDLLをロードしている場合にnullptrを返します.'これは真ではありません。 – RbMm

答えて

0

このソリューションは、DLLファイル内で手動ナビゲーションを使用しています。解の根拠は、RVAアドレスをRAWアドレス(ファイル内のアドレス)に変換するRVAtoRAW関数です。

//Defining in which section particular RVA address actually located (section number) 
DWORD RVAtoRAW(DWORD rva, PIMAGE_SECTION_HEADER sectionHeaderRAW, WORD sectionsCount) 
{ 
    int sectionNo; 
    for (sectionNo = 0; sectionNo < sectionsCount; ++sectionNo) 
    { 
     auto sectionBeginRVA = sectionHeaderRAW[sectionNo].VirtualAddress; 
     auto sectionEndRVA = sectionBeginRVA + sectionHeaderRAW[sectionNo].Misc.VirtualSize; 
     if (sectionBeginRVA <= rva && rva <= sectionEndRVA) 
      break; 
    } 
    //Evaluating RAW address from section & RVA 
    auto sectionRAW = sectionHeaderRAW[sectionNo].PointerToRawData; 
    auto sectionRVA = sectionHeaderRAW[sectionNo].VirtualAddress; 
    auto raw = sectionRAW + rva - sectionRVA; 

    return raw; 
} 

BSTR GetDllDependencies(const wchar_t* dllPath) 
{ 
    auto buffer = ReadFile(dllPath); 
    if (buffer.empty()) 
     return SysAllocString(L""); 

    //RAW - offset from beginnig of the file (absolute "address" within file) 
    auto baseRAW = buffer.data(); 
    auto dosHeaderRAW = (PIMAGE_DOS_HEADER)baseRAW; 
    auto peHeaderRAW = (PIMAGE_NT_HEADERS)(baseRAW + dosHeaderRAW->e_lfanew); 
    auto sectionHeaderRAW = (PIMAGE_SECTION_HEADER)(baseRAW + dosHeaderRAW->e_lfanew + sizeof(IMAGE_NT_HEADERS)); 

    auto sectionsCount = peHeaderRAW->FileHeader.NumberOfSections; 

    //RVA - Relative Virtual Address - relative (to ImageBase) address within virtual address space of the process which loads this DLL 
    auto importTableRVA = peHeaderRAW->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 
    auto importTableRAW = RVAtoRAW(importTableRVA, sectionHeaderRAW, sectionsCount); 
    auto importTable = (PIMAGE_IMPORT_DESCRIPTOR)(baseRAW + importTableRAW); 

    std::wstring dependencies; 
    while (importTableRVA && importTable->OriginalFirstThunk) 
    { 
     auto nameRAW = RVAtoRAW(importTable->Name, sectionHeaderRAW, sectionsCount); 

     auto importedModuleName = (char*)(DWORD_PTR)(nameRAW + baseRAW); 
     dependencies 
      .append(importedModuleName, importedModuleName + std::strlen(importedModuleName)) 
      .append(L","); 

     importTable++; 
    } 

    auto result = SysAllocString(dependencies.c_str()); 

    return result; 
} 
関連する問題