我在64位窗口中安装了Mozilla FireFox x64
,现在我想要LoadLibrary(mozglue.dll)
,但我收到错误编号193
LoadLibrary(mozglue.dll)
适用于Mozilla FireFox 86
我使用此代码:
#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;
}
答案 0 :(得分:1)
您的第一个问题是64位程序无法加载32位DLL,而32位程序无法加载64位DLL以执行代码。 MSDN的Process Interopability信息中描述了这一点:
您可以使用仿真层在64位Windows上运行基于Win32的应用程序。有关更多信息,请参阅运行32位应用程序。
在64位Windows上,64位进程无法加载32位动态链接库(DLL)。此外,32位进程无法加载64位DLL。
如果您需要同时支持32位程序和64位,最简单的方法是安装32位版本的Mozilla DLL(通过32位Mozilla安装),并为64位执行相同的操作Mozilla的。默认情况下,64位Mozilla应放在C:\Program Files\Mozilla Firefox\
和C:\Program Files (x86)\Mozilla Firefox\
中的32位Mozilla中。在加载像mozglue.dll
您不会检查hndl
是否为NULL。您应该只检查GetLastError
返回的句柄是否为NULL,而不是当它不是NULL时。其次,使用LoadLibraryExW
调用LOAD_LIBRARY_AS_DATAFILE
可以加载DLL资源,但不允许您使用GetProcAddress
检索函数地址。这在LoadLibraryEx的MSDN文档中有记录:
LOAD_LIBRARY_AS_DATAFILE 0x00000002
如果使用此值,系统会将文件映射到调用进程的虚拟地址空间,就好像它是一个数据文件一样。执行或准备执行映射文件没有任何操作。因此,您无法使用此DLL调用 GetModuleFileName,GetModuleHandle或 GetProcAddress 等函数。使用此值会导致写入只读内存以引发访问冲突。如果要仅加载DLL以从中提取消息或资源,请使用此标志。
记住上面的想法我用修改后的loadfunc
编译了你的代码并将其构建为64位应用程序。完成后,程序在MessageBox中打印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\
我从download link下载了64位版本的Mozilla,并从this link下载了32位Mozilla安装。
答案 1 :(得分:0)
您要么尝试将32位DLL加载到64位进程,要么将64位DLL加载到32位进程中。它无法完成。
我想如果你的'Mozilla FireFox x64'mozglue.dll
是64位的 - 那么你需要编译并将你的测试程序链接为64位。