我们试图了解在运行时定位符号的一些更精细的细节。我已经审核了Jeffrey Richter的Programming Applications for Microsoft Windows,第19章( DLL Basics )和20( DLL Advanced )。 Richter比MSDN更全面,更有凝聚力。
我们正在尝试将隐式库链接与动态符号位置相结合。由于某些潜在的安全隐患,我们希望避免拨打LoadLibrary
。我们还试图避免加载器锁定问题如果用户在DllMain
函数中徘徊太多。
#include <windows.h>
#pragma comment(lib, "kernel32")
extern "C" {
typedef BOOL (WINAPI * PFN_GOR)(HANDLE, LPOVERLAPPED, LPDWORD, BOOL);
typedef BOOL (WINAPI * PFN_GORX)(HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL);
}
int main(int argc, char* argv[])
{
HINSTANCE hInst = GetModuleHandle("kernel32");
PFN_GOR pfn1 = hInst ? (PFN_GOR)GetProcAddress(hInst, "GetOverlappedResult") : NULL;
PFN_GORX pfn2 = hInst ? (PFN_GORX)GetProcAddress(hInst, "GetOverlappedResultEx") : NULL;
std::cout << "kernel32: " << std::hex << (void*)hInst << std::endl;
std::cout << "GetOverlappedResult: " << std::hex << (void*)pfn1 << std::endl;
std::cout << "GetOverlappedResultEx: " << std::hex << (void*)pfn2 << std::endl;
return 0;
}
我们很幸运GetOverlappedResult
和GetOverlappedResultEx
,因为无论平台如何,kernel32.dll
都提供了这两者。 kernel32.dll
有另一个不错的属性,因为每个Windows应用程序都链接到它,并且无法将其删除。
平台上的随机数似乎有点麻烦。在Windows 7及更低版本中,我们CryptGenRandom
来自advapi32.dll
; Windows 10及更高版本使用BCryptGenRandom
中的bcrypt.dll
。 Windows 8是一个灰色区域,因为某些版本(如Windows Phone 8)不提供任何功能。我们相信我们可以根据WINVER
或_WINNT_VER
保留对图书馆的加入。
我觉得隐式库链接的模式与GetModuleHandle
和GetProcAdress
相结合是不寻常的,但它符合我们的要求。它不寻常,因为它使用隐式链接和GetModuleHandle
而不是LoadLibrary
。我也找不到禁止隐式链接的文本和GetModuleHandle
。
它符合我们的要求,因为由于二进制种植和其他DLL重定向技巧,我们不负责不安全的库加载。我们还会通过在DLLmain
中做太多来避免因意外误用而致DoS。
我的问题是,代码是合法的组合还是模式。如果它是一个有缺陷的模式,那么缺陷是什么?
我们使用Visual Studio 2015通过Windows 10 / Phone 10 / Store 10支持Windows XP和Visual Studio .Net。
在Windows XP上,代码产生以下结果:
>cl.exe /TP /EHsc test.cxx /Fetest.exe
...
>.\test.exe
kernel32: 7D4C0000
GetOverlappedResult: 7D52E12C
GetOverlappedResultEx: 00000000
在Windows 7上,代码产生以下结果:
>cl.exe /TP /EHsc test.cxx /Fetest.exe
...
>.\test.exe
kernel32: 772A0000
GetOverlappedResult: 772CCC69
GetOverlappedResultEx: 00000000
在Windows 8上,代码产生以下结果(Windows 10类似):
>cl.exe /TP /EHsc test.cxx /Fetest.exe
...
>.\test.exe
kernel32: 74FD0000
GetOverlappedResult: 74FEF8C0
GetOverlappedResultEx: 7675C4D0
在Windows 8和10上,我们只能测试交叉编译并与ARM Developer Prompt链接。我们使用以下附加CXXFLAGS
测试桌面,电话和商店的编译:
CXXFLAGS
:
/DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP
CXXFLAGS
:
/DWINAPI_FAMILY=WINAPI_FAMILY_APP
CXXFLAGS
:
/DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP
CXXFLAGS
:
/D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP
我发现很多点击次数如Implicit vs. Explicit linking to a DLL,但我找不到能够检查LoadLibrary
可以施加的一些安全问题,以及如何避免{{}} {{}} 1}}完全。
答案 0 :(得分:3)
这里不多说。将GetProcAddress
与通过调用GetModuleHandle
获得的模块句柄一起使用是完全合法的。
更新:我是根据问题的原始形式写的,但没有说清楚这个问题是为了涵盖移动平台还是桌面。