I'm working on an application which saves state of custom process and then restores it from the point stopped at.
Right now there is the following issue. When system is reboot, all base addresses of system modules are randomized (ntdll.dll
, kernelbase.dll
, kernel32.dll
and so on). OS is Windows 7 x64 Enterprise. When trying to restore application after reboot, it obviously crashes (but worked fine from restoration point before reboot). I see 2 solutions to this:
- Make addresses of system modules static when they are loaded in application
- Patch all the references to target modules in the application (addresses of functions on stack, addresses which may be saved in a heap and so on)
Obviously, the 2nd way is difficult. We are to make the full application analysis, differ code from data, differ data where it may be simple integer from reference to system module... So I have chosen the 1st way.
When loading modules in virtual memory, OS first checks if there is already a module with such a name in physical memory. If there is one, it simply maps this module to virtual address space. In this case, the module is loaded from its initial location, in case of ntdll.dll
- from C:\Windows\System32\ntdll.dll
. Even if you copy this module to application directory, disable ASLR flag and patch image base to some value, this module will still be loaded from system directory. Some way of redirection is needed.
From MSDN we learn the following (section "Search Order for Desktop Applications"):
Desktop applications can control the location from which a DLL is loaded by specifying a full path, using DLL redirection, or by using a manifest. If none of these methods are used, the system searches for the DLL at load time as described in this section.
So there are again at least 2 ways to achieve the aim.
On the page about DLL redirection we see:
Known DLLs cannot be redirected. For a list of known DLLs, see the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs. The system uses Windows File Protection to ensure that system DLLs such as these are not updated or deleted except by operating system updates such as service packs.
Modules I want to redirect are known DLLs, so this variant cannot be applied.
Manifests are left. There is an excellent article about using them. The author of the article creates stub DLL to replace original one (user32.dll
) and then makes application to load this replaced DLL. The point is that this DLL is loaded when searching for imported functions, not at the very start of application, like ntdll.dll
.
To be more specific, let's refer to "Windows Internals, Sixth Edition", p. 359 where details of process creation are explained. There are 7 stages there:
- Converting and Validating Parameters and Flags
- Opening the Image to Be Executed
- Creating the Windows Executive Process Object
- Creating the Initial Thread and Its Stack and Context
- Performing Windows Subsystem–Specific Post- Initialization
- Starting Execution of the Initial Thread
- Performing Process Initialization in the Context of the New Process
The most important points here:
mapping of
ntdll.dll
occurs at stage 3;at start of stage 5 we read (emphasis is mine):
At this point, Kernel32.dll sends a message to the Windows subsystem so that it can set up SxS information (see the end of this section for more information on side-by-side assemblies) such as manifest files, DLL redirection paths, and out-of-process execution for the new process.
It means that ntdll.dll
is loaded before redirection has a chance to occur. There are a lot of questions on SO on the topic of redirection but they all are about DLLs that are loaded while searching for imported functions or explicitly via LoadLibrary
, when redirection may occur in application.
However, ntdll.dll
is loaded in application in any case at a very early stage.
Using all the info I have gathered so far I was able to make application search, for example, for kernel32.dll
in application's directory (using link from this paragraph). But I was not able to redirect searching for ntdll.dll
.
Is it possible at all from user mode?
P.S. There is a way of disabling ASLR globally, see this post. However, it is a very rude way, applications like Internet Explorer
, Adobe Reader
fail to work and the whole OS is open to vulnerabilities.