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.
Related
Has anyone been successful at packaging a Gtk3 app for Windows for the Microsoft store?
I'm playing with this at the moment:
Visual Studio 2019;
Gtk3/Gtkmm distro obtained via vcpkg;
C++ app;
VS Application Packaging Project.
The application runs fine on its own. I then package it, and then run the MSIX bundle installer. When I then run the installed application, it starts but:
an Access Denied error appears in a dialog box;
the application appears with broken icons and incorrect colors (wrong or no theme).
I have tracked the error having to do with Gio-2.DLL where it attempts to spawn a child process, looks like something to do with creating a dbus server/session (??). I believe the child process (dbus server?) starts but then attempts to do something that is not permitted in the sandbox that Windows creates for the app.
Anyone?
After some more investigation, I may have found a workaround. I'll post it here in case it helps anyone else. This workaround allows making a packaged Gtk3 application for Windows. A Windows packaged application runs in a sandbox of sorts, with heavily restricted access to resources outside the package.
First, the issue: during initialization, the version of Gio-2.DLL for Windows spawns a child process to serve as a DBus session daemon (I may get the terminology wrong here as I'm not that familiar with DBus). It does so only for the first instance. If one launches additional instances of applications that use Gio-2.DLL, the additional instances use the existing daemon from the first instance.
To launch the daemon, Gio-2.DLL calls CreateProcess() to fork a RUNDLL32.EXE child, with the full path to Gio-2.DLL (i.e. itself), and g_win32_run_session_bus() as the name of the function to call. It looks like RUNDLL32.EXE does launch successfully, since it is able to display the "RUNDLL" error dialog box. However it fails to make the requested function call into Gio-2.DLL. I gather that at least one of the system calls that RUNDLL32.EXE makes to load the DLL and call the requested function is prohibited when running in a packaged application.
At the moment, my workaround is this. Assume my application executable is called 'myapp.exe':
the application package contains myapp.exe, all the necessary DLLs for Gtk3 and dependencies, and another executable 'dbus_daemon_launcher.exe';
before entering the Gtk main loop, myapp.exe calls CreateProcess() to start dbus_daemon_launcher.exe;
dbus_daemon_launcher.exe is also linked with Gio-2.DLL and makes a call to g_win32_run_session_bus() with the DLL;
myapp.exe then proceeds to start the Gtk main loop. Since the Dbus daemon is then already running, Gio-2.DLL does not attempt to call RUNDLL32.EXE to launch it, which avoids the error.
This workaround has the advantage that it does not require making a custom version of Gio-2.DLL. Also, I'm using Gtk3: perhaps this issue has been addressed in the more recent Gtk4, and the workaround is unnecessary in this case.
I've got a program that needs to be able to update itself. I have a second program that will perform the updates, downloading and installing. The updater will obviously need to be able to update the main program, and for that, the main program can't be running. So I want to have the main program launch the updater with a call to ShellExecuteEx, but the MSDN documentation has me a little confused.
It says that:
The SEE_MASK_NOASYNC flag must be specified if the ... process will
terminate soon after ShellExecuteEx returns. Under such conditions,
the calling thread will not be available to complete the DDE
conversation, so it is important that ShellExecuteEx complete the
conversation before returning control to the calling application.
Failure to complete the conversation can result in an unsuccessful
launch of the document.
And under SEE_MASK_NOASYNC, it says that the ShellExecuteEx call won't return until the operation is complete. What I want is to launch the updater and then immediately terminate the main program, so the updater can run without trouble. Is that the correct way to do it? And is there anything special I need to do to keep the launched updater from being marked as a "child process" that will be killed when the main process shuts down?
Do you have to call ShellExecute? I do something similar and launch via CreateProcess and it works fine.
(In reality, cmd.exe is launched which runs a batch file. The batch file waits, starts the updater and waits for it to finish, then waits a bit, then launches the main app again. Never had any trouble with it)
DDE won't be used to launch an EXE directly. (It's only used to launch certain types of files if they are regsitered as needing to be launched that way. If you're just running an EXE by name, DDE should be irrelevant.)
So you should specify SEE_MASK_NOASYNC (to make sure the ShellExecuteEx call finishes doing all it needs to do and your app is then free to end the thread as soon as the call returns) and the API should return very quickly.
here's a good CodeProject article about launching an updater:
http://www.codeproject.com/Articles/395572/Executable-Integration-Example-External-settings-a
I want to be able to detect whether a given exe was shellex'd programmatically or if it was entered and executed interactively in, say, CMD.EXE.
Is there anything about the way an exe is launched that indicates the mechanism that was used to launch it?
Context: Windows XP, Visual Studio 6 languages.
There might be an easier way, but the only way I can think of is to check the parent process name, which involves a few steps:
Get the ID of the parent process.
Get the handle of the process, using the ID.
Use GetModuleFileNameEx with the handle found (and NULL as the module) to get the executable's name.
Check if the executable's name is cmd.exe or whatever.
Bear in mind that the parent process might already be gone when (or while) you do this check.
Edit:
If your program is a console application, you can also check the console it's running in. If it was run from cmd, it will usually use the same console. So, you can use GetConsoleTitle, for instance, and see if it's "Command Prompt". This might not work on localized or different versions of Windows, but it's easy if you have limitated cases. You can also use GetConsoleWindow and GetWindowThreadProcessId instead of steps 1 and 2.
You can differ between say CMD and Explorer by inspecting the parent process, but you can't tell if it happened due to user action or not. Also AFAIK all ways to launch a process result in the same NtCreateProcess/PspCreateProcess call, so you can't tell which API was used either.
I've written a program with a manifest that includes requireAdministrator. On Windows 7 systems with UAC enabled, Windows pops up a dialog asking for permissions, as it should. Works great.
If a user starts my program by right-clicking it and choosing "Run as administrator", then Windows 7 also pops up a dialog asking for permissions. However, there are some slight differences in how my program operates in some of the more esoteric parts of my program.
So what are the differences between "Run as administrator" and a manifest with requireAdministrator? Any links to documentation that describe differences would be appreciated.
Edit: This is with UAC enabled.
Edit: As promised below is the full explanation of the difference I'm seeing.
I'm using the EasyHook library to inject a DLL into another process. When my application is run with "Run as administrator", the injected process crashes and EasyHook returns the error "Unknown error in injected assembler code". None of the code in my DLL gets a chance to execute; the crash occurs before then. (Moreover, the crash occurs even if I strip the DLL down to nothing)
If I run my program normally (i.e., elevated via requireAdministrator), everything works fine.
My application is composed of a few different executables. The process that the user launches is not the same process that performs the injection.
With the information given there would be no differences in the permissions between the two processes.
If you request an execution level of "requireAdministrator" via the applications manifest your application will either be launched with the full access token of an administrator or not at all if the user denies consent (see Create and Embed an Application Manifest (UAC) for further information).
The same will happen when a user chooses Run as Administrator.
The only difference is the way that the process is started. When you start an executable from the shell, e.g. by double-clicking in Explorer or by selecting Run as Administrator from the context menu, the shell will call ShellExecute to actually start process execution. The whole process of elevation is hidden inside this function. Kenny Kerr describes this process in more details in Windows Vista for Developers – Part 4 – User Account Control:
ShellExecute first calls CreateProcess to attempt to create the new process. CreateProcess does all the work of checking application compatibility settings, application manifests, runtime loaders, etc. If it determines that the application requires elevation but the calling process is not elevated then CreateProcess fails with ERROR_ELEVATION_REQUIRED. ShellExecute then calls the Application Information service to handle the elevation prompt and creation of the elevated process since the calling process obviously doesn’t have the necessary permissions to perform such a task. The Application Information service ultimately calls CreateProcessAsUser with an unrestricted administrator token.
If on the other hand you want to create an elevated process regardless of what application information is available then you can specify the little-known “runas” verb with ShellExecute. This has the effect of requesting elevation regardless of what an application’s manifest and compatibility information might prescribe. The runas verb is not actually new to Windows Vista. It was available on Windows XP and Windows 2003 and was often used to create a restricted token directly from the shell. This behavior has however changed. Here is a simple example:
::ShellExecute(0, // owner window
L"runas",
L"C:\\Windows\\Notepad.exe",
0, // params
0, // directory
SW_SHOWNORMAL);
So essentially starting an executable using the Run as Administrator option means that ShellExecute bypasses the checks for compatibility settings, application manifests etc and directly requests elevation.
Kenny Kerr's article also has sample code to query the current process' token for its permission using the OpenProcessToken function. Possibly you can use the example to identify that there are no differences in the way your process is elevated.
I'm definitely curious to know which differences you are observing as I strongly doubt they are related to elevation.
As a last thing: Can you double check that you really request a level of requireAdministrator and not by mistake only a level of highestAvailable?
One possible difference might be the rarely used/understood/deliberately-chosen uiAccess attribute. Can you create two manifests, one with uiAccess=false and one with uiAccess=true, then tell us whether one of them gives the same behaviour as you see with right-click-run-as-admin?
The EasyHook documentation for the RemoteHooking class' IsAdministrator property mentions:
Due to UAC on Windows Vista, this property in general will be false even if the user is in the builtin-admin group. As you can't hook without administrator privileges you should just set the UAC level of your application to requireAdministrator.
It's hard to imagine why this is happening, but it is conceivable (especially as you are seeing it happen!) that assets, processes, assemblies, &c, with possibly different trust levels and so forth, will not inherit the elevation of your main app. Setting the requireAdministrator flag may handle/enforce this globally across the entire scope of resources and dependencies. Would love to know how this turns out.
I thought I was seeing a difference between these as well. However, it turned out that in my case the issue was this:
When I click "Run as Administrator" from my file browser (Q-Dir), the working directory is different than when I try simply double clicking an application with requireAdministrator set in the manifest. This changed the behavior of some buggy DLLs I had received. In fact, it turned out that 100% of the differences I saw were due to running from different working directories (specifically, it mattered whether I was on C: drive or a different drive letter) and that the method of getting the program to run as administrator had nothing to do with it.
It's an issue that is specific to my computer's exact configuration, but it is a possible clue into the type of thing that might be happening (or might have happened 7 years ago . . . )
I'm developing an NSIS installer, to update a program that runs in background. Obviously, I'd like to send the program termination signals, because otherwise I repeatedly get a "can't write" error. How can I do this, with a limited overhead on installer size?
If your app has a window with a unique class name, you could just send it WM_CLOSE/WM_QUIT or whatever message you need.
Or your app could register a local server COM object the uninstaller could call (The system plugin can call COM methods)
Another way to do this is for the program to create a named event and wait on it, the uninstaller would signal it, this would be the clue for the program to quit.
As a last resort, you could kill the process with one of several plugins: KillProcDLL, Processes plug-in, KillProc plug-in and NsProcess
Also, the Locked List plugin might be a better alternative.