为什么不能加载(打开)所有DLL模块?

时间:2014-08-21 05:50:32

标签: c++ c windows dll

我有notepad.exe路径,我需要输出notepad.exe使用的所有DLL模块和函数(导入)。

  int InitWork()
{
    LPCWSTR fileName = L"C:\\Windows\\System32\\notepad.exe";

    PEinfo.handle = CreateFile(fileName, GENERIC_READ, 0, 0, OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL, 0); 

    /*....*/
    PVOID pVirtual = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
    /*...*/
    // Get pointer to headers
    PEinfo. pNTHeader = (PIMAGE_NT_HEADERS)(PCHAR(pVirtual) + PEinfo.pDOSHead->e_lfanew);   
    PEinfo.pSech = IMAGE_FIRST_SECTION(PEinfo.pNTHeader);
    PEinfo.OptHeader32 = (IMAGE_OPTIONAL_HEADER32) PEinfo.pNTHeader->OptionalHeader; 

    WCHAR* funcname = (wchar_t*)malloc(sizeof(wchar_t));

    size_t i=0;
    LPSTR libname = (char*)malloc(sizeof(char));

    if(PEinfo.OptHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size != 0)
    {
        PEinfo.pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)pVirtual +\
            Rva2Offset(PEinfo.OptHeader32.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,PEinfo.pSech,PEinfo.pNTHeader));

        printf("DLLName.FunctionName\n");

        while(PEinfo.pImportDescriptor->Name != NULL)
        {           
            //Get the name of each DLL
            libname = (PCHAR)((DWORD_PTR)pVirtual + Rva2Offset(PEinfo.pImportDescriptor->Name,PEinfo.pSech,PEinfo.pNTHeader));

            funcname = ANSItoUnicode(libname, funcname);

            ImportFuncList(funcname);
            PEinfo.pImportDescriptor++;
            i++;
        }
    }
    return 0;
}

/*Convert Virtual Address to File Offset */
DWORD Rva2Offset(DWORD rva,PIMAGE_SECTION_HEADER psh,PIMAGE_NT_HEADERS pnt)
{
    size_t i = 0;
    PIMAGE_SECTION_HEADER pSeh;
    if(rva == 0)
    {
        return (rva);
    }
    pSeh = psh;
    for(i = 0; i < pnt->FileHeader.NumberOfSections; i++)
    {
        if(rva >= pSeh->VirtualAddress && rva < pSeh->VirtualAddress +
            pSeh->Misc.VirtualSize)
        {
            break;
        }
        pSeh++;
    }
    return (rva - pSeh->VirtualAddress + pSeh->PointerToRawData);
} 

int ImportFuncList(LPWSTR dllName)
{
    PEinfo.DLLModule = NULL;
    PEinfo.DLLModule = GetModuleHandle(dllName);

    if (PEinfo.DLLModule == NULL)
    {
        wprintf(L"Error Load %s\n", dllName);
        return 1;
    }

}

结果: ADVAPI32.dll中。 KERNEL32.dll中。 GDI32.DLL。 USER32.dll中。 MSVCRT.DLL。 错误加载COMDLG32.dll 错误加载SHELL32.dll 加载WINSPOOL.DRV时出错 错误加载ole32.dll 错误加载SHLWAPI.dll 错误加载COMCTL32.dll 错误加载OLEAUT32.dll ntdll.dll中。 错误加载VERSION.dll

什么?

为什么有些DLL加载而有些没有?

1 个答案:

答案 0 :(得分:2)

尚未加载失败的模块。这样做,我预测您的代码将按预期工作:

LoadLibrary(dllName);
PEinfo.DLLModule = GetModuleHandle(dllName);

这不是你应该怎么做的,但是它证明了DLL在程序启动时并没有全部加载,如果尚未加载它们,GetModuleHandle将会失败。