CreateProcessXXX hooking in Windows 7

c++ / delphi package - dll injection and api hooking
Nico Bendlin
Posts: 46
Joined: Fri Apr 28, 2006 1:17 pm

Post by Nico Bendlin »

If you are reading the RTL_USER_PROCESS_PARAMETERS you should care about RTL_USER_PROC_PARAMS_NORMALIZED in the Flags member. Depending on this flag the Buffers are absolute addresses or offsets from the start of the RTL_USER_PROCESS_PARAMETERS structure.
mikec
Posts: 166
Joined: Sun Jul 16, 2006 9:01 pm
Location: UK

more information, pleassssssssse

Post by mikec »

Hay Nico,

Thanks for the pointers so far - they have helped me moved me forward.

I started my downloading the WRK and looking at the RTL equivalent in the XP kernel. Its prototype is different from the one used in Vista / Windows 7. The XP prototype has 10 parameters, the Vista one has 11, starting with a pointer to a process handle.

Having looked at the RTL code, all I want to do at the moment is access the NtImagePathName parameter (1st param in XP, 2nd param in vista). I can’t even do this. My hook appears ok - I use OutputDebugString() to show that it is being called. However, if i try and access the image path parameter i get nothing. Code looks like this:

Code: Select all


function NtCreateUserProcessCallback(
	ProcessHandle : PHANDLE; 
	ImagePath : PUNICODE_STRING; 
	ObjectAttributes : ULONG;
	ProcessParameters : PRTL_USER_PROCESS_PARAMETERS; 
	ProcessSecurityDescriptor : PSECURITY_DESCRIPTOR;
	ThreadSecurityDescriptor : PSECURITY_DESCRIPTOR; 
	ParentProcess	: HANDLE; 
	InheritHandles : BOOLEAN;
	DebugPort : HANDLE; 
	ExceptionPort : HANDLE; 
	ProcessInformation : PRTL_PROCESS_INFO
	) : NTSTATUS; stdcall;
begin
   OutputDebugStringW(ImagePath^.Buffer);
   OutputDebugString('NtCreateUserProcess');
   result := NtCreateUserProcessNxt(ProcessHandle, 
			ImagePath, 
			ObjectAttributes, 
			ProcessParameters, 
			ProcessSecurityDescriptor, 
			ThreadSecurityDescriptor,
			ParentProcess, 
			InheritHandles, 
			DebugPort, 
			ExceptionPort, 
			ProcessInformation);
end;
OutputDebugStringW(ImagePath^.Buffer) never shows up - the RTL comments say this should always represent the value of the target process.

I need to work out how to determine which process the call is relating to i.e. which executable is being launched, if it is possible to modify this value, and finally, if it is possible to create a new thread in the process once NtCreateUserProcess has returned.

Any help, pointers or suggestions would be gratefully received.

Many thanks in advance

Mike C
hwiniol
Posts: 7
Joined: Fri Sep 12, 2008 4:36 pm

Post by hwiniol »

Personally I would prefer to hook CreateProcessInternalW instead of all those single CreateProcess APIs or the Native APIs. As far as I know all Win32 APIs to create processes will call CreateProcessInternalW since Windows XP SP1.

Essentially CreateProcessInternalW has the same signature as CreateProcessW except it has 2 additional parameters:

Code: Select all

function CreateProcessInternalW(firstUnknown : DWORD; lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW;
  var lpProcessInformation: TProcessInformation; secondUnknown : DWORD): BOOL; stdcall;
Maybe you want to try that instead of hooking some native APIs.
msp
Posts: 3
Joined: Tue Jan 25, 2011 2:37 pm

Re: CreateProcessXXX hooking in Windows 7

Post by msp »

Hi Nico, Hi Mike C,

unfortunately, I don't have academic access to the Windows Research Kernel (WRK) :cry: Could anyone of you be so kind and provide a prototype for NtCreateUserProcess() here?

It is strange that such an important and central APIis so poorely documented. It is not even listed on undocumented.ntinternals.net and a google search did not reveal anything useful either. I understand that NtCreateUserProcess() was added only lately in WinVista or Win7. Is there any relation between the function NtCreateUserProcess() and the function RtlCreateUserProcess(), which already exists in WinXP?


Regards,
Matthias
iconic
Site Admin
Posts: 1067
Joined: Wed Jun 08, 2005 5:08 am

Re: CreateProcessXXX hooking in Windows 7

Post by iconic »

Code: Select all

NTSTATUS NTAPI NtCreateUserProcess(
PHANDLE ProcessHandle, 
ULONG_PTR Parameter1,
ULONG_PTR Parameter2,
ULONG_PTR Parameter3,
ULONG_PTR ProcessSecurityDescriptor,
ULONG_PTR ThreadSecurityDescriptor,
ULONG_PTR Parameter6,
ULONG_PTR Parameter7,
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
ULONG_PTR Parameter9,
ULONG_PTR Parameter10
);
--Iconic
msp
Posts: 3
Joined: Tue Jan 25, 2011 2:37 pm

Re: CreateProcessXXX hooking in Windows 7

Post by msp »

Thanks for the quick reply, Iconic. Your prototype spares me some time of having to figure out all arguments by myself. At least the most important arguments are clear now. I wouldn't be surprised if the other arguments of RtlCreateUserProcess() (see http://undocumented.ntinternals.net/Use ... ocess.html) would also show up in NtCreateUserProcess(). Does anyone know how these two functions are related?

Code: Select all

NTSYSAPI 
NTSTATUS
NTAPI
RtlCreateUserProcess(

  IN PUNICODE_STRING      ImagePath,
  IN ULONG                ObjectAttributes,
  IN OUT PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
  IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL,
  IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,
  IN HANDLE               ParentProcess,
  IN BOOLEAN              InheritHandles,
  IN HANDLE               DebugPort OPTIONAL,
  IN HANDLE               ExceptionPort OPTIONAL,
  OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation );

A final beginners (?) question: Assuming that the arguments ''ULONG' ObjectAttributes' and 'BOOLEAN InheritHandles' appear somewhere in the argument list of NtCreateUserProcess(), would then 'ULONG_PTR' still be a correct replacement for 'ULONG', resp. 'BOOLEAN' under 64bit, even though the sizes mismatch? Or is this not an issue because the (shadow) stack space of all pointer arguments would be QWORD aligned anyway? (before anyone asks: yes, I do know the basics about 64bit calling conventions http://msdn.microsoft.com/en-us/library ... s.80).aspx :wink:)

Regards,
Matthias

iconic wrote:

Code: Select all

NTSTATUS NTAPI NtCreateUserProcess(
PHANDLE ProcessHandle, 
ULONG_PTR Parameter1,
ULONG_PTR Parameter2,
ULONG_PTR Parameter3,
ULONG_PTR ProcessSecurityDescriptor,
ULONG_PTR ThreadSecurityDescriptor,
ULONG_PTR Parameter6,
ULONG_PTR Parameter7,
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
ULONG_PTR Parameter9,
ULONG_PTR Parameter10
);
--Iconic
iconic
Site Admin
Posts: 1067
Joined: Wed Jun 08, 2005 5:08 am

Re: CreateProcessXXX hooking in Windows 7

Post by iconic »

Hello msp,

What is your main goal with hooking a native API such as NtCreateUserProcess? Are you trying to ask permission for a process to spawn? Are you doing it merely for logging purposes with no user interaction? I thought it'd be important to mention the fact that you can call any native process creation function from usermode (all of them ending up calling ntdll!KiFastSystemCall) so they will all need to be hooked, not just NtCreateUserProcess. NtCreateUserProcess, NtCreateProcess and NtCreateProcessEx would all need to be hooked (if available on the target OS / svcpack configuration) since as I mentioned they are all native services which use either INT 0x2E/SYSENTER directly.

The most reliable usermode method with the least amount of work from what I see is to only hook csrss.exe->csrsrv.dll!CsrCreateProcess, it will accomplish everything that can be done by hooking process creation APIs. Of course there can be multiple sessions running so you'd need to make sure that you have caught every additional csrss instance too and repeat the aforementioned step of hooking csrsrv.dll!CsrCreateProcess.

--Iconic
msp
Posts: 3
Joined: Tue Jan 25, 2011 2:37 pm

Re: CreateProcessXXX hooking in Windows 7

Post by msp »

Hello Iconic

thanks for pointing out this interesting method to me. Googling 'CsrCreateProcess', I also found your discussion with madshi about this topic (viewtopic.php?t=5205). However, hooking csrss.exe will not be feasible for me, since csrss is running under the local system account and I am assuming to have no admin privileges.

As for your question: My goal is to have the web browser (and its process decendants) running in a sandbox on a secure desktop with file system and registry virtualization, similar to sandboxIE. However, there is a 'handicap': The sandbox itself is downloaded on-the-fly and has to be able to run out-of-the-box without admin privileges or any prior setup by an administrator. So my possibilities are very limited. (see remark *)

I need to intercept process creation in order to recursively hook applications and their descendants. Since I am mainly hooking at the native level (ntdll.dll) and not at the kernel32 level (**) , it seemed natural to use the native apis for process creation instead of hooking all flavours of kernel32!CreateProcessA/W, kernel32!CreateProcessAsUserA/W, etc., etc. I did not expect the native proces api to be so poorely documented. Even after reading the chapter on process creation in Mark Russinovichs book it is still confusing to me, which parts of the creation are done by kernel32, the kernel, and csrss, respectively. Even more since Micrsoft introduced all this shim and application compatibility stuff.

After some testing I found out that kernel32!CreateProcessInternalW/A seems to be a good place for me to place my hook. This function exists since WinXP (or even earlier) and seems to be the central routine eventually called by all flavours of kernel32!CreateProcess*. And no 'standard' win32 application would take the effort to bypass kernel32, would it?

--msp


Remarks:
(*) Of course I now that user mode hooking is not really a means of establishing security. (It's a political decision and not a programmers choice to do it this way.) In my case the primary aim of the sandbox is not to prevent malicious software from corrupting the system, but rather to provide some limited safety and privacy given a clean computer and reasonably well behaved programs. (like IE and Acrobat Reader)

(**) Using native hooks for file system virtualization instead of kernel32 hooks is not only more natural, it is also mandatory in Win7, since the explorer (resp. the file selection dialog) nowadays bypasses FindFirstFile/FindNextFile and uses NtQueryDirectoryFile directly, which it didn't use to do in WinXP
iconic
Site Admin
Posts: 1067
Joined: Wed Jun 08, 2005 5:08 am

Re: CreateProcessXXX hooking in Windows 7

Post by iconic »

Hi msp,

Yes, hooking CreateProcessInternalW should do mostly what you need to accommodate your solution. CreateProcessInternalA will end up calling CreateProcessInternalW so you'd only need to hook the unicode variant of this API. I took a quick peek at the inner workings of CreateProcessInternalW on Windows 7, it's just a higher level wrapper for NtCreateUserProcess. On Windows XP SP2 for example, since NtCreateUserProcess isn't available, CreateProcessInternalW calls NtCreateProcessEx instead. Not really a surprise ;)

Also, to answer your earlier question which you had asked more than once... the relation of Rtl* APIs is the fact that they're typically native service wrappers. i.e> on XP RtlCreateUserProcess will eventually call its lower-level counterpart NtCreateProcess and on Windows 7 RtlCreateUserProcess will call NtCreateUserProcess.

See the pattern ? :D

--Iconic
Post Reply