如何在 64 位窗口中加载 32 位 DLL
How to load a 32bit DLL in a 64bit windows
>我在 64 位窗口中安装了Mozilla FireFox x64
,现在我想LoadLibrary(mozglue.dll)
但我收到错误号 193
LoadLibrary(mozglue.dll)
在具有Mozilla FireFox 86
的 32 位窗口中运行良好
我使用此代码:
#include <Windows.h>
#include <strsafe.h>
int main()
{
HMODULE hndl;
DWORD dwError = 0;
WCHAR errorBuff[MAX_PATH] = {};
hndl = LoadLibraryW(L"C:\Program Files\Mozilla Firefox\mozglue.dll");
dwError = GetLastError();
StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError);
MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK);
FreeLibrary(hndl);
return 0;
}
这段代码有什么问题?
编辑:
我使用:
LoadLibraryExW(L"C:\Program Files\Mozilla Firefox\mozglue.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
而不是:
LoadLibraryW(L"C:\Program Files\Mozilla Firefox\mozglue.dll");
现在GetLastError
返回 0 但GetProcAddress
失败...
#include <Windows.h>
#include <strsafe.h>
typedef enum SECItemType {
siBuffer = 0,
siClearDataBuffer = 1,
siCipherDataBuffer,
siDERCertBuffer,
siEncodedCertBuffer,
siDERNameBuffer,
siEncodedNameBuffer,
siAsciiNameString,
siAsciiString,
siDEROID,
siUnsignedInteger,
siUTCTime,
siGeneralizedTime
};
struct SECItem {
SECItemType type;
unsigned char *data;
size_t len;
};
typedef enum SECStatus {
SECWouldBlock = -2,
SECFailure = -1,
SECSuccess = 0
};
typedef struct PK11SlotInfoStr PK11SlotInfo;
typedef SECStatus(*NSS_Init) (const char *);
typedef SECStatus(*NSS_Shutdown) (void);
typedef PK11SlotInfo * (*PK11_GetInternalKeySlot) (void);
typedef void(*PK11_FreeSlot) (PK11SlotInfo *);
typedef SECStatus(*PK11_Authenticate) (PK11SlotInfo *, int, void *);
typedef SECStatus(*PK11SDR_Decrypt) (SECItem *, SECItem *, void *);
PK11_GetInternalKeySlot PK11GetInternalKeySlot;
PK11_FreeSlot PK11FreeSlot;
PK11_Authenticate PK11Authenticate;
PK11SDR_Decrypt PK11SDRDecrypt;
NSS_Init fpNSS_INIT;
NSS_Shutdown fpNSS_Shutdown;
BOOL loadFunc()
{
HMODULE hndl;
DWORD dwError = 0;
WCHAR errorBuff[MAX_PATH] = {};
BOOL retVal = FALSE;
hndl = LoadLibraryExW(L"C:\Program Files\Mozilla Firefox\mozglue.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
dwError = GetLastError();
StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError);
MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK);
hndl = LoadLibraryExW(L"C:\Program Files\Mozilla Firefox\nss3.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
dwError = GetLastError();
StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError);
MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK);
if (hndl)
{
fpNSS_INIT = (NSS_Init)GetProcAddress(hndl, "NSS_Init");
fpNSS_Shutdown = (NSS_Shutdown)GetProcAddress(hndl, "NSS_Shutdown");
PK11GetInternalKeySlot = (PK11_GetInternalKeySlot)GetProcAddress(hndl, "PK11_GetInternalKeySlot");
PK11FreeSlot = (PK11_FreeSlot)GetProcAddress(hndl, "PK11_FreeSlot");
PK11Authenticate = (PK11_Authenticate)GetProcAddress(hndl, "PK11_Authenticate");
PK11SDRDecrypt = (PK11SDR_Decrypt)GetProcAddress(hndl, "PK11SDR_Decrypt");
}
return !(!fpNSS_INIT || !fpNSS_Shutdown || !PK11GetInternalKeySlot || !PK11Authenticate || !PK11SDRDecrypt || !PK11FreeSlot);
}
int main()
{
if (loadFunc())
{
MessageBoxW(NULL, L"OK", L"", MB_OK);
}
else
{
MessageBoxW(NULL, L"NO", L"", MB_OK);
}
return 0;
}
第一个问题是 64 位程序无法加载 32 位 DLL,32 位程序无法加载 64 位 DLL 以执行代码。MSDN 的进程互操作性信息中对此进行了描述:
可以使用仿真层在 64 位 Windows 上运行基于 Win32 的应用程序。有关详细信息,请参阅运行 32 位应用程序。
在 64 位 Windows 上,64 位进程无法加载 32 位动态链接库 (DLL)。此外,32 位进程无法加载 64 位 DLL。
如果您需要同时支持 32 位程序和 64 位,最简单的方法是安装 32 位版本的 MozillaDLL(通过 32 位 Mozilla 安装),并对 64 位 Mozilla 执行相同的操作。默认情况下,64位Mozilla应放在C:Program FilesMozilla Firefox
中,32位Mozilla应放在C:Program Files (x86)Mozilla Firefox
中。在生成 64 位应用程序时需要考虑不同的目录,在加载 DLL 时需要考虑 32 位应用程序
mozglue.dll
您不检查hndl
是否为 NULL。只需检查返回的句柄是否为 NULL,而不是检查返回的句柄是否为 NULL,GetLastError
检查。其次,使用LOAD_LIBRARY_AS_DATAFILE
调用LoadLibraryExW
允许您加载 DLL 资源,但不允许您使用GetProcAddress
检索函数地址。这记录在 LoadLibraryEx 的 MSDN 文档中:
LOAD_LIBRARY_AS_DATAFILE 0x00000002
如果使用此值,系统会将文件映射到调用进程的虚拟地址空间,就像它是数据文件一样。不执行任何操作来执行或准备执行映射文件。因此,不能使用此 DLL 调用 GetModuleFileName、GetModuleHandle 或GetProcAddress等函数。使用此值会导致写入只读内存以引发访问冲突。当您只想加载 DLL 以从中提取消息或资源时,请使用此标志。
牢记上述想法,我使用修订后的loadfunc
编译了您的代码,并将其构建为 64 位应用程序。完成后,程序将在消息框中打印OK
:
BOOL loadFunc()
{
HMODULE hndl;
DWORD dwError = 0;
WCHAR errorBuff[MAX_PATH] = {};
BOOL retVal = FALSE;
hndl = LoadLibraryW(L"C:\Program Files\Mozilla Firefox\mozglue.dll");
// if the handle is NULL then check for an error otherwise proceed
if (!hndl)
{
dwError = GetLastError();
StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError);
MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK);
return TRUE;
}
hndl = LoadLibraryW(L"C:\Program Files\Mozilla Firefox\nss3.dll");
// if the handle is NOT NULL then try to retrieve the method addresses
if (hndl)
{
fpNSS_INIT = (NSS_Init)GetProcAddress(hndl, "NSS_Init");
fpNSS_Shutdown = (NSS_Shutdown)GetProcAddress(hndl, "NSS_Shutdown");
PK11GetInternalKeySlot = (PK11_GetInternalKeySlot)GetProcAddress(hndl, "PK11_GetInternalKeySlot");
PK11FreeSlot = (PK11_FreeSlot)GetProcAddress(hndl, "PK11_FreeSlot");
PK11Authenticate = (PK11_Authenticate)GetProcAddress(hndl, "PK11_Authenticate");
PK11SDRDecrypt = (PK11SDR_Decrypt)GetProcAddress(hndl, "PK11SDR_Decrypt");
}
// the handle was NULL if we get here so show the error
else
{
dwError = GetLastError();
StringCbPrintfW(errorBuff, MAX_PATH, L"%d", dwError);
MessageBoxW(NULL, errorBuff, L"GetLastError", MB_OK);
return TRUE;
}
return !(!fpNSS_INIT || !fpNSS_Shutdown || !PK11GetInternalKeySlot || !PK11Authenticate || !PK11SDRDecrypt || !PK11FreeSlot);
}
对于 32 位程序,您需要将上述代码中的路径更改为前面提到的 32 位 Mozilla 目录,并编译为 x86 32 位应用程序。前面提到的 32 位代码的默认路径为C:Program Files (x86)Mozilla Firefox
我从这个下载链接下载了64 位版本的 Mozilla,从这个链接下载了 32 位 Mozilla 安装。
您尝试将 32 位 DLL 加载到 64 位进程中,或将 64 位 DLL 加载到 32 位进程中。 这是做不到的。
我想如果你有"Mozilla FireFox x64",mozglue.dll
是64位的 - 所以你需要编译和链接你的测试程序为64位。
- Python ctypes:不会按预期加载 dll
- 在 Linux 平台的 C++ 中动态加载 DLL
- 为什么 LoadLibrary 失败,而 LoadLibraryA 成功加载 DLL?
- 为什么有些延迟加载 DLL 会立即使用 FFMPEG 卸载?
- 了解加载库无法加载 DLL 的原因
- 应用程序仅在qt调试器中加载dll,而不是独立加载
- dll 生成成功,但在加载 dll 时执行错误
- QT 加载.dll不调用解析
- 通过重新加载DLL,避免使用DLL预加载漏洞,任何更好的方法
- 问题在具有依赖性时从其他路径上加载DLL的DLL
- C++插件不能延迟加载dll时
- Java加载DLL,该DLL从JNI中的另一个DLL导出方法
- C++ 动态加载 DLL 错误
- GHCi 无法在 Windows 上加载.dll lib(C++ lib)
- 使用C++应用程序加载 DLL
- System.DllNotFoundException:无法使用 dotnet core 加载 DLL
- 当应用程序在不同系统上运行时,无法加载DLL异常
- 如何停止二级IMPLICITLY加载DLL的DLL劫持
- 无法加载dll libglorycolx2010.dll.该应用程序未能启动,因为其并排配置不正确.Hresult:0x
- 如何在Acrobat JavaScript中加载DLL文件