How is the Windows notification about a missing DLLs implemented? - windows

We've all seen "The code execution cannot proceed because xxxxxx.dll was not found." message box in Windows, that pops up when application launch fails due to a missing dependency.
And yet, I cannot figure out how it works: there seems to be no Windows API that allows to discover which DLL is missing after CreateProcess fails with a STATUS_DLL_NOT_FOUND error code...
Does anyone know how this is implemented?
Edit: And yeah, I'd like to obtain name of the missing DLL programmatically, in the process that calls CreateProcess().

there seems to be no Windows API that allows to discover which DLL is missing after CreateProcess fails with a STATUS_DLL_NOT_FOUND error code
Correct, there is no such API available.
Does anyone know how is this implemented?
When an EXE is being loaded prior to starting the execution of its code, the OS's loader scans the EXE's PE header to discover the required DLLs, and then it attempts to load each of those DLLs. If any of those DLLs fail to load, the loader is the one who is displaying the popup message, and it knows which DLL just failed, so it includes that DLL's name in the error message. But that information is not passed down to the caller who originally asked for the EXE to run.
FYI, when using CreateProcess() to run an EXE, you can disable that popup error message by calling SetErrorMode()/SetThreadErrorMode() beforehand, specifying the SEM_FAILCRITICALERRORS flag:
Value
Meaning
SEM_FAILCRITICALERRORS0x0001
The system does not display the critical-error-handler message box. Instead, the system sends the error to the calling process.Best practice is that all applications call the process-wide SetErrorMode function with a parameter of SEM_FAILCRITICALERRORS at startup. This is to prevent error mode dialogs from hanging the application.

Related

How to debug minidump.mdmp from a different computer with original solution?

Developer console of Microsoft Store provides users' minidump.mdmp files for crashes of my published program. I try to debug them by loading the solution with the version used for publishing that exe, and opening that minidump.mdmp file.
Clicking "Debug with Mixed" I get
Unhandled exception at 0x00007FF9ACCF9269 (ntdll.dll) in minidump.mdmp: 0xC0000374: A heap has been corrupted (parameters: 0x00007FF9ACD627F0).
so I assume it is not in managed code but call Stack is full with
`[Frames below may be incorrect and/or missing, no binaries loaded for MYPROGRAM.exe] `
so I am not sure it if this is the right procedure. It does not provide me with a breakpoint in my program, or anything else useful.
Is this the right way to use minidmp files?
If relevant, this is WPF desktop C# program packaged for Store.

"The operating system is not presently configured to run this application" Error when Running MAPI App

Thank you for your reply and comments.
Let me describe the situation more detailedly.
I use Visual C++ 2008 to write a small application that will invoke MAPI. I use MAPIStubLibrary to support both 32bit and 64bit MAPI. MAPIStubLibrary can be found at https://msdn.microsoft.com/en-us/library/office/cc963763.aspx#sectionSection2 . It works on other versions of Outlook and most of the systems. However, under Windows 10(32bit) with Office 2016(32bit) installed, when I execute the following statement to initialize MAPI:
MAPIInitialize(NULL);
I will get the above error message "The operating system is not presently configured to run this application". And there will be an unhandled exception raised from the function GetDefaultMapiHandle(), which is in StubUtils.cpp, part of the MAPIStubLibrary.
The exact line that cause the exception is:
hinstMapi = LoadLibraryW(wzPath);
It seems that MAPIStubLibrary is trying to load 32bit MAPI but fails. wzPath is pointing to olmapi32.dll instead of msmapi32.dll.
In the error message, if I click “OK” button in the error messagebox, the application will continue running without problems. However, the error message is still frustrating and confusing the users. Therefore, how to eliminate the error?
Thank you very much.
This usually happens when you are either loading a wrong MAPI dll (e.g. olmapi32.dll instead of msmapi32.dll) or if your app is running in the compatibility mode (do you include a manifest?) and the MAPI system ends up patching wrong Windows API functions assuming an older version of Windows.

Does "Image File Execution Options" intercept CreateProcess commands?

I want to know how the mechanism of debugger injection works. Why is "Image File Execution Options" so special?
I have two guesses.
CreateProcess will call an internal function that checks against the list of registry keys. If it is found, then it manipulates the arguments and calls the debugger exe instead.
There is some other service listening for CreateProcess calls and intercepts them. It kills the original call or message (if createprocess is a message or message-like), then it runs the new process as if the original caller called it.
My desire is to verify and update components before an application starts. I like the IFEO "feature" but i need to run the original process after the verification step so I need a way to run it without recursing into the updater. I hope that by learning more about the injection system I can get this system working.
This article explains how it works.
In Windows XP and 2003 the user-mode CreateProcess code reads the registry and, if required, launches the debugger instead.
In more recent versions of Windows this functionality has moved into kernel mode.
But neither case seems to involve a general interception mechanism for CreateProcess.

How do I trap Windows messages?

I'm making a program called Pwn16. It allows 16-bit applications to run on 64-bit systems by emulating an Intel 8086/Pentium processor and a DOS/Win3.x/Win98 system. Pwn16 uses a small loader program that detects when Windows gives the "not 16-bit compatible" messages (including the one from CMD) and when it notices said message(s) being summoned, it will close it and instead automatically launch Pwn16.
Are there any libraries that will let me "capture" these messages and do something else in place of the errors? I'm making most of this in VB6, so any code that can do this will also help. I have the emulation and GUI down, I just need to get this loader done to finish it.
Messages I need to capture:
"The version of this file is not compatible with the version of Windows you're running. Check your computer's system information to see whether you need an x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher."
"Unsupported 16-Bit Application: The program or feature '(file)' cannot start or run due to incompatibility with 64-bit versions of Windows. Please contact the software vendor to ask if a 64-bit Windows compatible version is available."
"This is not a valid Win32 application."
"The (file) application cannot be run in Win32 mode."
Thanks.
As far as I know, neither Explorer nor cmd.exe check the validity of the executable file in advance. Instead, they call CreateProcess and, if it fails, look at the error code returned.
So, if you hook calls to CreateProcess (or perhaps the underlying native API) you should be able to capture the error code being returned to Explorer/cmd.exe/whatever and do your thing instead.
I don't think capturing the message being presented to the user is going to be helpful. Quite apart from the inefficiency involved in examining every dialog box, and every piece of text written to every console, to see whether it contains the message you're looking for, how would you then identify which file the user was trying to run?

SetErrorMode has no effect?

I call
"SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);"
before loading a DLL. Nevertheless a windows message pops up
"This application has failed to start
because blabla.dll was not found...".
Why does that happen? I thought that was what SetErrorMode was supposed to prevent?
Thanks!
The call to SetErrorMode is probably never executed - if you statically link to the DLL, it will be loaded along with the executable. The message you see is popped by the operating system, and not by your code. If you want control over the load of the DLL, you should load it using LoadLibrary - but then using exported functions is a bit harder.
You can create your own loader (a different executable), which will make sure all DLLs are available, and then run the main executable. But that might be an overkill...

Resources