C ++: get native dll dependencies without loading it

I need to get a list of DLL dependencies programmatically. This is how I try to solve this problem:

BSTR GetDllDependencies(const wchar_t* dllPath)
{
    std::wstring dependencies;

    struct LibDeleter
    {
        typedef HMODULE pointer;
        void operator()(HMODULE hMod) { FreeLibrary(hMod); }
    };

    auto hModRaw = LoadLibraryExW(dllPath, NULL, DONT_RESOLVE_DLL_REFERENCES); //(*)nullptr nere
    auto hMod = std::unique_ptr<HMODULE, LibDeleter>();

    auto imageBase = (DWORD_PTR)hMod.get();

    auto header = ImageNtHeader(hMod.get());
    auto importRVA = header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
    auto importTable = (PIMAGE_IMPORT_DESCRIPTOR)(DWORD_PTR)(importRVA + imageBase);

    while (importRVA && importTable->OriginalFirstThunk)
    {
        auto importedModuleName = (char*)(DWORD_PTR)(importTable->Name + imageBase);
        dependencies
            .append(importedModuleName, importedModuleName + std::strlen(importedModuleName))
            .append(L",");

        importTable++;
    }

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

    return result;
}

It works. But, as you can see, it loads the DLL into the process. And I ran into a problem in this place: LoadLibraryExreturns nullptrif the process has already loaded the DLL with the same name.

nullptr

I'm not sure if it is allowed to load two DLLs with the same name (but in a different place) in the same process? I believe, yes. Then why LoadLibraryExreturns nullptr? Is it possible to somehow get the DLL dependencies without loading the DLL?

+4
source share
2 answers

DLL . RVAtoRAW, RVA RAW ( ).

//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;
}
0

. , IMAGE_IMPORT_DESCRIPTOR " PE".

Peering Inside the PE: Win32

+1

Source: https://habr.com/ru/post/1682683/


All Articles