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

C++ 为什么我不能加载(打开)所有DLL模块?,c++,c,windows,dll,C++,C,Windows,Dll,我有notepad.exe路径,需要输出notepad.exe使用的所有DLL模块和函数(导入) int InitWork() { LPCWSTR fileName=L“C:\\Windows\\System32\\notepad.exe”; PEinfo.handle=CreateFile(文件名,通用读取,0,0,打开现有,文件属性,0); /*....*/ PVOID pVirtual=VirtualAlloc(NULL、size、MEM\u COMMIT、PAGE\u READWRITE

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

int InitWork()
{
LPCWSTR fileName=L“C:\\Windows\\System32\\notepad.exe”;
PEinfo.handle=CreateFile(文件名,通用读取,0,0,打开现有,文件属性,0);
/*....*/
PVOID pVirtual=VirtualAlloc(NULL、size、MEM\u COMMIT、PAGE\u READWRITE);
/*...*/
//获取指向标题的指针
PEinfo.pNTHeader=(PIMAGE\u NT_HEADERS)(PCHAR(pVirtual)+PEinfo.pDOSHead->e_lfanew);
PEinfo.pSech=图像第一节(PEinfo.pNTHeader);
PEinfo.OptHeader32=(IMAGE\u OPTIONAL\u HEADER32)PEinfo.pNTHeader->OptionalHeader;
WCHAR*funcname=(WCHAR_t*)malloc(sizeof(WCHAR_t));
尺寸i=0;
LPSTR libname=(char*)malloc(sizeof(char));
if(PEinfo.OptHeader32.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u IMPORT].Size!=0)
{
PEinfo.pImportDescriptor=(PIMAGE\u IMPORT\u DESCRIPTOR)((DWORD\u PTR)pVirtual+\
Rva2Offset(PEinfo.OptHeader32.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u IMPORT].VirtualAddress、PEinfo.pSech、PEinfo.pNTHeader));
printf(“DLLName.FunctionName\n”);
while(PEinfo.pImportDescriptor->Name!=NULL)
{           
//获取每个DLL的名称
libname=(PCHAR)((DWORD_PTR)pVirtual+Rva2Offset(PEinfo.pImportDescriptor->Name,PEinfo.pSech,PEinfo.pNTHeader));
funcname=ANSItoUnicode(libname,funcname);
导入目录(名称);
pImportDescriptor++;
i++;
}
}
返回0;
}
/*将虚拟地址转换为文件偏移量*/
DWORD RVA2偏移(DWORD rva、PIMAGE\U SECTION\U HEADER psh、PIMAGE\U NT\U HEADER pnt)
{
尺寸i=0;
PIMAGE_段头pSeh;
如果(rva==0)
{
返回(rva);
}
pSeh=psh;
对于(i=0;iFileHeader.NumberOfSections;i++)
{
如果(rva>=pSeh->VirtualAddress&&rvaVirtualAddress+
pSeh->杂项虚拟化)
{
打破
}
pSeh++;
}
返回(rva-pSeh->VirtualAddress+pSeh->PointerToRawData);
} 
int ImportFuncList(LPWSTR dllName)
{
PEinfo.DLLModule=NULL;
PEinfo.DLLModule=GetModuleHandle(dllName);
if(PEinfo.DLLModule==NULL)
{
wprintf(L“错误加载%s\n”,dllName);
返回1;
}
}
结果: ADVAPI32.dll。 内核32.dll。 GDI32.dll。 USER32.dll。 msvcrt.dll。 加载COMDLG32.dll时出错 加载SHELL32.dll时出错 加载WINSPOOL.DRV时出错 加载ole32.dll时出错 加载SHLWAPI.dll时出错 加载COMCTL32.dll时出错 加载OLEAUT32.dll时出错 ntdll.dll。 加载版本.dll时出错

怎么回事


为什么有些DLL加载了,有些没有加载?

发生故障的模块还没有加载。这样做,我预测您的代码将按预期工作:

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

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

它可能不在同一路径中,或者可能已损坏,或者可能是注册表问题。请参阅此部分了解如何解决此问题。您是否阅读了
GetModuleHandle
的文档?什么使您认为所有引用的DLL都已加载?
WCHAR*funcname=(WCHAR\u t*)malloc(sizeof(WCHAR\u t))
lpstrlibname=(char*)malloc(sizeof(char))-这两种初始化都太小,都不是必需的。将它们都初始化为零。Carey Gregory,是的,关于DLL的数量,您是对的。根据OllyDBG的数据,并不是所有的都加载了,只有14/23。我等了90分钟才发帖)EJP,libname工作正常。filName看起来是另一个真实的程序。我把它剪下来是为了提问。我应该怎么做(我的意思是我应该如何从dll加载函数)?我的意思是,为另一个程序加载dll可能不是一个好主意。一些应用程序引用了数百个DLL,其中许多DLL在正常运行时永远不会加载,但如果强制加载所有DLL,则可能会出现相当大的性能问题。但是,如果您必须知道应用程序不仅引用DLL x,而且还可以加载该DLL,那么您必须使用
LoadLibrary
。我希望在大多数情况下,只要知道应用程序引用了DLL就足够了。好的,谢谢。我想到了“LoadLibrary”,但后来看到了一些新东西并尝试了一下。
LoadLibrary(dllName);
PEinfo.DLLModule = GetModuleHandle(dllName);