Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CreateProcess STATUS_DLL_NOT_FOUND - which dll?

I have a process which calls CreateProcess. It appears that CreateProcess returns nonzero indicating success. However, the HANDLE to the process then gets immediately set, indicating the process has exited. When I call GetExitCodeProcess, STATUS_DLL_NOT_FOUND is then returned.

I understand that a DLL is missing. I even know exactly which one. However, what I don't understand is how to figure that out programmatically.

I noticed that Windows will present a dialog saying that the process failed to start because it couldn't find the specified DLL (screenshot: http://www.mediafire.com/view/?kd9ddq0e2dlvlb9 ). In the dialog, Windows specifies which DLL is missing. However, I find no way to get that information myself programmatically.

If a process fails to start and would return STATUS_DLL_NOT_FOUND, how do I programmatically retrieve the library name to which the target process was linked which couldn't be found? That way I can automatically record in an error report what DLL appears to be missing or corrupt in a given installation.

like image 745
Keith4G Avatar asked Aug 21 '13 19:08

Keith4G


4 Answers

Just since this is somehow the top stackoverflow result on Google for "STATUS_DLL_NOT_FOUND". How to trace and solve any random occurence:

Download SysInternals procmon64.exe (or just the entire set). After startup immediately hit the looking glass 'Stop capture' button (Ctrl+E). And 'Clear' (Ctrl+X).

Set filters for:

  • 'Process name' is to whatever the mentioned process name was (for me it was 'build-script-build.exe') [Add]
  • 'Result' is not 'SUCCESS' [Add]
  • 'Path' ends with '.dll' [Add] [OK]

Start capture again (Ctrl+E).

Run the thing that had a problem again (for me: build cargo). Google for the last listed DLL file.

For me that was VCRUNTIME140.dll, so I installed the VC++ 2015 to 2019 redistributable.

ProcMon is kind of like unix strace.

like image 193
Henk Poley Avatar answered Sep 28 '22 02:09

Henk Poley


The best way is to use loader snaps. Basically you use gflags.exe (which is included with windbg) to enable loader snaps; then, run the process with the debugger attached. Loader snaps will enable the loader to print out dbg messages of the process and it will print the failures.

gflags.exe -i yourcode.exe +sls
windbg yourcode.exe

I know this is not a "programmatic" way to find out the problem, but what the loader does is complicated, and you don't really want to be redoing its logic to find the failure. That is why loader snaps were invented.

like image 27
sam msft Avatar answered Nov 18 '22 07:11

sam msft


CreateProcess returns 0 indicating success.

CreateProcess() returns a BOOL, where 0 is FALSE, aka failure not success.

If a process fails to start and would return STATUS_DLL_NOT_FOUND, how do I programmatically retrieve the library name to which the target process was linked which couldn't be found?

Unfortunately, there is no API for that. Your only option would be to manually access and enumerate the executable's IMPORTS table to find out what DLLs it uses, and then recursively access and enumerate their IMPORTS tables, manually checking every DLL reference you find to see whether that DLL file exists on the OS's search path or not.

like image 5
Remy Lebeau Avatar answered Nov 18 '22 06:11

Remy Lebeau


If the dll is statically linked you can walk the iat and see if the dll exists. If the dll is dynamically loaded then starting the process suspended and hooking LoadLibrary (or instead of hooking emulate a debugger) is the only way I see.

like image 2
Remko Avatar answered Nov 18 '22 07:11

Remko