CreateProcessXXX hooking in Windows 7
-
- Posts: 46
- Joined: Fri Apr 28, 2006 1:17 pm
more information, pleassssssssse
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:
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
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;
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
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:
Maybe you want to try that instead of hooking some native APIs.
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;
Re: CreateProcessXXX hooking in Windows 7
Hi Nico, Hi Mike C,
unfortunately, I don't have academic access to the Windows Research Kernel (WRK) 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
unfortunately, I don't have academic access to the Windows Research Kernel (WRK) 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
Re: CreateProcessXXX hooking in Windows 7
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
);
Re: CreateProcessXXX hooking in Windows 7
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?
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 )
Regards,
Matthias
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 )
Regards,
Matthias
iconic wrote:--IconicCode: 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 );
Re: CreateProcessXXX hooking in Windows 7
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
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
Re: CreateProcessXXX hooking in Windows 7
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
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
Re: CreateProcessXXX hooking in Windows 7
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 ?
--Iconic
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 ?
--Iconic