Implicit library linking and GetModuleHandle/GetProcAdress
<p>We are trying to understand some of the finer details of locating a symbol at runtime. I've already reviewed Jeffrey Richter's <a href="https://rads.stackoverflow.com/amzn/click/com/1572319968" rel="nofollow noreferrer" rel="nofollow noreferrer">Programming Applications for Microsoft Windows</a>, Chapters 19 (<em>DLL Basics</em>) and 20 (<em>DLL Advanced</em>). Richter is a bit more comprehensive and more cohesive than MSDN.</p>

<p>We are trying to combine implicit library linking with dynamic symbol location. We want to avoid calls to <code>LoadLibrary</code> because of some of the potential security hazards. We are also trying to avoid loader lock issues <em>if</em> a user wanders into doing too much in a <code>DllMain</code> function.</p>

<pre class="lang-cxx prettyprint-override"><code>#include &lt;windows.h&gt;
#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 &lt;&lt; "kernel32: " &lt;&lt; std::hex &lt;&lt; (void*)hInst &lt;&lt; std::endl;
    std::cout &lt;&lt; "GetOverlappedResult: " &lt;&lt; std::hex &lt;&lt; (void*)pfn1 &lt;&lt; std::endl;
    std::cout &lt;&lt; "GetOverlappedResultEx: " &lt;&lt; std::hex &lt;&lt; (void*)pfn2 &lt;&lt; std::endl;

    return 0;
}
</code></pre>

<p>We kind of got lucky with <code>GetOverlappedResult</code> and <code>GetOverlappedResultEx</code> because <code>kernel32.dll</code> provides both of them regardless of the platform. <code>kernel32.dll</code> has another nice property because every Windows application links to it, and there's no way to disgorge it.</p>

<p>Random numbers from the platform appear to be a little more troublesome. On Windows 7 and below we have <code>CryptGenRandom</code> from <code>advapi32.dll</code>; while Windows 10 and above uses <code>BCryptGenRandom</code> from <code>bcrypt.dll</code>. Windows 8 is a grey area because some versions, like Windows Phone 8, do not offer anything. We believe we can guard inclusion of a library based on <code>WINVER</code> or <code>_WINNT_VER</code>.</p>

<p>I feel like the pattern of implicit library linking combined with <code>GetModuleHandle</code> and <code>GetProcAdress</code> is unusual but it meets our requirements. Its unusual because it uses implicit linking and <code>GetModuleHandle</code> rather than <code>LoadLibrary</code>. I also cannot find text that forbids implicit linking and <code>GetModuleHandle</code>.</p>

<p>It meets our requirements because we will not be responsible for insecure library loading due to binary planting and other DLL redirection tricks. We will also avoid DoS'es from accidental mis-use by doing too much in a <code>DLLmain</code>.</p>

<p>My question is, is the code a legal combination or pattern. If its a defective pattern, then what is the defect?</p>

<hr>

<p>We support Windows XP and Visual Studio .Net through Windows 10/Phone 10/Store 10 using Visual Studio 2015.</p>

<p>On Windows XP the code produces the following result:</p>

<pre class="lang-none prettyprint-override"><code>&gt;cl.exe /TP /EHsc test.cxx /Fetest.exe
...
&gt;.\test.exe
kernel32: 7D4C0000
GetOverlappedResult: 7D52E12C
GetOverlappedResultEx: 00000000
</code></pre>

<p>On Windows 7 the code produces the following result:</p>

<pre class="lang-none prettyprint-override"><code>&gt;cl.exe /TP /EHsc test.cxx /Fetest.exe
...
&gt;.\test.exe
kernel32: 772A0000
GetOverlappedResult: 772CCC69
GetOverlappedResultEx: 00000000
</code></pre>

<p>On Windows 8 the code produces the following result (Windows 10 is similar):</p>

<pre class="lang-none prettyprint-override"><code>&gt;cl.exe /TP /EHsc test.cxx /Fetest.exe
...
&gt;.\test.exe
kernel32: 74FD0000
GetOverlappedResult: 74FEF8C0
GetOverlappedResultEx: 7675C4D0
</code></pre>

<p>On Windows 8 and 10 we can only test the cross-compile and link with ARM Developer Prompt. We test the compile for Desktop, Phone and Store using the following additional <code>CXXFLAGS</code>:</p>

<ul>
<li>To test Desktop app, add the following <code>CXXFLAGS</code>:

<ul>
<li><code>/DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP</code></li>
</ul></li>
<li>To test Windows Store app, add the following <code>CXXFLAGS</code>:

<ul>
<li><code>/DWINAPI_FAMILY=WINAPI_FAMILY_APP</code></li>
</ul></li>
<li>To test Windows Phone, add the following <code>CXXFLAGS</code>:

<ul>
<li><code>/DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP</code></li>
</ul></li>
<li>To test Surface RT (ARM tablet), add the following <code>CXXFLAGS</code>:

<ul>
<li><code>/D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 /DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP</code></li>
</ul></li>
</ul>

<hr>

<p>I'm finding lots of hits like <a href="https://stackoverflow.com/q/4794032">Implicit vs. Explicit linking to a DLL</a>, but I have not been able to find one that examines some of the security issues that <code>LoadLibrary</code> can impose, and how to avoid <code>LoadLibrary</code> altogether. </p>