March 22nd, 2017

You can peek to see whether your delay-loaded function loaded successfully

The Query­Optional­Delay­Loaded­API function lets you ask whether a function marked as delay-loaded was in fact found. Here’s a tiny demonstration:

#include <windows.h>
#include <commdlg.h>
#include <libloaderapi2.h>
#include <stdio.h>

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HMODULE_THISCOMPONENT reinterpret_cast<HMODULE>(&__ImageBase)

int __cdecl main(int argc, char** argv)
{
    if (QueryOptionalDelayLoadedAPI(HMODULE_THISCOMPONENT,
          "comdlg32.dll", "GetOpenFileNameW", 0))
    {
        printf("GetOpenFileNameW can be called!\n");
    }
    return 0;
}

This gives you function-by-function granularity on checking whether a delay-loaded function was successfully loaded, which is an improvement over being told whether all the imports for a DLL were loaded.

Note also that the original problem with the Win16 model for weak linking wasn’t that developers built but never ran their programs. Developers built their programs, and they ran fine on all the systems they tested because the function was present on all the systems they tested. It never occurred to them that the function might not exist in the first place. I mean, suppose you wrote a 16-bit program that called Get­Open­File­Name. It runs great on all your systems! But oh no, you get a report from a customer that it crashes on their system. The reason: COMMDLG.DLL was not a mandatory OS component. Users had the option of installing Windows without it, at which point all the programs that called Get­Open­File­Name would start crashing.

Win32’s response to this was “If you want weak linking, you know where to find it.” Namely, Get­Proc­Address. The fact that you called a function to get an address will hopefully remind you to check whether the function actually succeeded.

The introduction of the Query­Optional­Delay­Loaded­API function is to allow Store apps (which are not allowed by policy to call Load­Library) to detect whether their delay-loaded function actually got loaded. The fact that the requested functions are in the delay-loaded function table means that a static analysis can still find all the functions that the program could potentially call.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.