Tracing LoadLibrary or LdrLoadDll - winapi

I need to get the directory search path followed while loading a DLL. So I need to trace either the LoadLibrary or LdrLoadDll function call to get the path followed from its arguments. Is there any tool to trace it or any tool to obtain the directory search order followed while loading a DLL?

Use APIMonitor and trace the LdrLoadDll function

The article "Debugging LoadLibrary Failures" describes the official solution, and works out of the box.

Related

GetStagedPackageOrigin is not found in Kernel32.dll as documented, but in Kernelbase.dll instead

I'm trying to load GetStagedPackageOrigin WinAPI dynamically using LoadLibrary and GetProcAddress so that my app could also run on Windows 7. So according to documentation that API is supposed to be imported from Kernel32.dll, but in reality (in my Windows 10 v1709) it is not.
I was able to find it in Kernelbase.dll instead:
So I'm wondering, can I dynamically load it from Kernelbase.dll instead?
this definitely bug in documentation. if we call (test on win10)
GetProcAddress(GetModuleHandle(L"kernel32"), "GetStagedPackageOrigin");
we got 0 - this mean that this api not exported or forwarded from kernel32.dll
but if call
GetProcAddress(GetModuleHandle(L"kernelbase"), "GetStagedPackageOrigin");
we got it real address.
next - when I search in latest sdk libs - I not found GetStagedPackageOrigin in kernel32.lib too. only one lib containing this symbol - OneCoreUap.lib umbrella library - and marked it exported from api-ms-win-appmodel-runtime-l1-1-1.dll .this dll resolved in runtime to kernel.appcore.dll. implementation - simply jump to kernelbase.GetStagedPackageOrigin
so most correct I think try import this api from api-ms-win-appmodel-runtime-l1-1-1.dll
very strange appraisal for my look :) with so simply question
anybody can easy test this simply code on win8.1, win10
GetProcAddress(LoadLibrary(L"kernel32"), "GetStagedPackageOrigin");//fail
GetProcAddress(LoadLibrary(L"kernelbase"), "GetStagedPackageOrigin");//ok
GetProcAddress(LoadLibrary(L"kernel.appcore.dll"), "GetStagedPackageOrigin");//ok
GetProcAddress(LoadLibrary(L"api-ms-win-appmodel-runtime-l1-1-1"), "GetStagedPackageOrigin");//ok
and view that by fact GetStagedPackageOrigin not exported from kernel32.dll. this is simply fact.
about lib file - i have no win8.1 sdk under hand, but i search this api in 10.x sdk version through lib files - and i found that this api implemented only in OneCoreUap.lib (not this symbol in kernel32.lib). and OneCoreUap.lib say that this api ix exported by api-ms-win-appmodel-runtime-l1-1-1.dll. so if we link with this lib - we by fact will be try import this api with api-ms-win-appmodel-runtime-l1-1-1.dll (this name will be hardcoded in our pe file). so we need or link with OneCoreUap.lib (i advice add it at the end of lib list) or direct call GetProcAddress(LoadLibrary(L"api-ms-win-appmodel-runtime-l1-1-1"), "GetStagedPackageOrigin");.
and can note that which header files use - absolute not related to question at all. if somebody not agree with this - can i ask - which lib need use - please concrete answer. and from which dll - please concrete dll name application will be use when use this lib (this dll name will be hardcoded in pe import table)
I would certainly not bind it to the versioned api-ms-win-appmodel-runtime-l1-1-1.dll , but the two generic ones. kernelbase or kernel.appcore.
The versions are visual studio/ucrt version specific.

How to make dbghelp to load symbols from custom sym store?

Is there any way for SymInitialize and SymFromAddr methods to automatically load symbols from a custom symbol store. I'm trying to resolve an address to a readable function name using SymFromAddr(). It seems to work fine if I have symbols for the given module stored locally, however I'd like it to automatically download them from the path given to SymInitialize, just like WinDbg does it.
I call SymInitialize like that:
SymInitialize(procHandle, "SRV*c:\\symbols*http://msdl.microsoft.com/download/symbols;http://mycustomstore.com/symbols", TRUE);
SymFromAddr returns error 487 "Attempt to access invalid address." as it can't find the symbol since it has never even attempted to download it.
Is there any way to force download them?
As it turned out dbghelp.dll needs symsrv.dll in order to load symbols. It was struggling to find it, so needed a bit of help.
I've used dbghelp logging to help track down the issue https://msdn.microsoft.com/en-us/library/ms680687.aspx
If you want to use a HTTP symbol store, you define it with
.sympath SRV*c:\mysymbols*http://example.com/symbols
To add the Microsoft symbol path, use
.symfix+ c:\microsoftsymbols
Looking at the WinDbg symbol path now gives you:
0:000> .sympath
srv*c:\mysymbols*http://example.com/symbols;SRV*c:\microsoftsymbols*http://msdl.microsoft.com/download/symbols
which tells us that your symbol path was not correct, since it didn't have the second SRV*...* part but just http://.... If you copy/paste the symbol path from your code to WinDbg, it probably wouldn't work as well.

File Path in C++ Assert not found on my disk

I am using Visual C++ to build a dll with some open source projects, but when I got an error, it read:
How did the "f:\dd\vctools\crt_bld\self_x86\crt\src\vsprintf.c" come out? I even didn't have a "f" disk. I've searched around about my source code, and there is no such string.
Any idea about this?
The file path as #Dcoder says is not from your disk.
This message is from the CRT (C run time library) that you link with your programs. MSVCRT.DLL (or a version of it)
When Microsoft wrote their source code to create this library they built special code called Assertions into it. This code (when you link to debug version of the library) checks the parameters that you sent to a function in the library, and passes helpful messages to you.
In this case you've called a function like printf or sprintf etc, and that eventually went into a piece of Microsoft function that lives in a microsoft file called vsprintf.c.
This file when the library was compiled inside Microsoft, it was done on the F: drive INSIDE Microsoft . It doesn't live on your disk.
Edit: if you add your code to your question we can help you find where this occurred.
As others have indicated in comments, the path described in the assertion dialog is the path of the source file that threw the assertion. In this case, a CRT sprintf function threw an assert.
The 'f:...' path doesn't refer to a path on your own machine: it's the path to the source file on the machine that compiled the file into the CRT DLL.
This is a debug assertion failure - you apparently passed a NULL-value to a function of the sprintf-family.
You should check your source-code for any NULL-values you pass to such a function.
It's where the Common Run Time (CRT) framework is installed. vsprintf.c is part of the CRT and something in that DLL has called one of the sprintf() functions with a null format string.

Linking against WinNLS

What static library should I use to link against to use the NormalizeString() function?
In contrast with most functions documented on MSDN, the static library required to use the function is not declared. I tried using the name derived from the DLL: normaliz.lib and it successfully linked, but then I get a pop-up at runtime saying Normalization.dll could not be found on my computer and the process is shut down.
As pointer out by Hans Passant, the correct import library is normaliz.lib. It seems there was some problem in my setup.
I was using Windows SDK v6.0A. After switching to Windows SDK v7.0A, my problems stopped.
The link at the bottom-ish of the page you linked states that the download contains implib and dll resources. You probably have to manifest the dll, or at least put it into PATH.

where are windows API functions defined?

when you need to use a function you include a header file but wheres the function code is defined?
Dave, the code lives in the various and many DLL files in your Windows\system32 directory.
The actual code that implements the Win-32 API are defined in various DLLs on your system. These DLLs have names like kernel32.dll, comctl32.dll etc. You will find them in C:\Windows\System32.
What generally happens is that you link your code with kernel32.lib etc. that have a little code to dynamically load the DLLs when your program starts. This allows Win32 API functions to directly call into the DLLS.
Well as explained above you are in the hands of microsoft.
You can always look at the msdn http://msdn.microsoft.com.
For most API functions you can find some information at the bottom.
For most function you get from there:
Minimum supported client
Minimum supported server
Header
Library
DLL
Unicode and ANSI names

Resources