我们正在尝试理解在运行时定位符号的一些更详细的细节。我已经复习了杰弗里·里希特的Microsoft Windows的编程应用程序,第19章(DLL基础)和第20章(DLL高级版)。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及更低版本上,我们使用来自advapi32.dll的BCryptGenRandom;而Windows 10及更高版本则使用来自bcrypt.dll的BCryptGenRandom。Windows 8是一个灰色地带,因为有些版本,如Windows 8,不提供任何东西。我们相信我们可以保护基于WINVER或_WINNT_VER的库的包含。
我觉得与GetModuleHandle和GetProcAdress相结合的隐式库链接模式是不寻常的,但它符合我们的要求。这是不寻常的,因为它使用隐式链接和GetModuleHandle而不是LoadLibrary。我也找不到禁止隐式链接和GetModuleHandle的文本。
它满足我们的要求,因为我们将不负责不安全的库加载,因为二进制种植和其他DLL重定向技巧。我们还将通过在DLLmain中做太多的事情来避免意外误用。
我的问题是,代码是法律上的组合还是模式。如果是有缺陷的模式,那么缺陷是什么?
我们使用Visual 2015通过Windows10/Phone 10/Store 10支持Windows和Visual .Net。
在Windows上,代码产生以下结果:
>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开发人员提示的链接。我们使用以下附加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
我找到了很多像隐式链接与显式链接到DLL这样的热门网站,但是我还没有找到一个能检查LoadLibrary可以强制执行的一些安全问题,以及如何完全避免LoadLibrary。
发布于 2016-10-09 10:36:15
这里没什么好说的。通过调用GetProcAddress获得的模块句柄使用GetModuleHandle是完全合法的。
Update:我写这篇文章是基于这个问题的原始形式,它并没有清楚地说明这个问题是为了涵盖移动平台和桌面。
https://stackoverflow.com/questions/39941690
复制相似问题