3

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:

  1. Make addresses of system modules static when they are loaded in application
  2. 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:

  1. Converting and Validating Parameters and Flags
  2. Opening the Image to Be Executed
  3. Creating the Windows Executive Process Object
  4. Creating the Initial Thread and Its Stack and Context
  5. Performing Windows Subsystem–Specific Post- Initialization
  6. Starting Execution of the Initial Thread
  7. 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.

Community
  • 1
  • 1
greenpiece
  • 621
  • 8
  • 20
  • 1
    *ntdll.dll* contains the process bootstrapping code. It has to be the first module mapped into a process object. You cannot change that, without rewriting the kernel. – IInspectable May 30 '16 at 19:52

2 Answers2

3

ntdll is mapped from kernel, during process creation. when first user mode instruction in process begin executing (this is LdrInitializeThunk from ntdll) ntdll is already mapped in process (at begin only exe and ntdll mapped, all another dll is loaded by ntdll or late by exe). and ntdll must be at same address loaded in all processes, because system use address of some callbacks located in ntdll (LdrInitializeThunk, KiUser*Dispatcher)

RbMm
  • 31,280
  • 3
  • 35
  • 56
1

There are some (theoretical) options:

  • Use delegated ntdll for WOW64 processes on Windows 10 (I never tried this, but in theory you should be able to specify registry settings to do so. See http://redplait.blogspot.de/2017/07/delegatedntdll.html)
  • Set some compatibility options (to make sure apphelp.dll is loaded) and use manifest files to load a custom apphelp.dll, that you can use to load your own ntdll and patch the loaded module list to make your own dll the one to be used as import for any other modules. I did so far not do this (I like to try it when I find the time), but I was able to load a custom win32u.dll, which forwards most exports to a copy of the original win32u.dll and hooks into some win32 syscalls. See also http://stackoverflow.com/questions/2100973/dll-redirection-using-manifests