I'm fooling around trying to learn more about Windows Kernel.
My target computer is running Windows 7 x86.
I wanted to call
ZwCreateProcess
from my driver, but failed to do so. I evaded a BSOD because I checked with
MmGetSystemRoutineAddress
(which returns NULL if the routine isn't found) and unloaded the driver before anything bad could happen.
Seeing that I can't find Nt or ZwCreateProcess I did a bit of researched and found out that on Vista and above Nt/ZwCreateUserProcess are used.
Wanted to be sure, I made a small driver that checks if any of the routines my research brought out are actually exported.
Here's the function that does this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
VOID
Search()
{
UNICODE_STRING dest;
PCWSTR find[5];
UINT32 i = 0;
find[0] = L"NtCreateProcess";
find[1] = L"ZwCreateProcess";
find[2] = L"NtCreateUserProcess";
find[3] = L"ZwCreateUserProcess";
RtlInitUnicodeString(&dest,
L"MmGetSystemRoutineAddress");
// if this call returns NULL it means that
// I don't use MmGetSystemRoutineAddress corectly
if(!MmGetSystemRoutineAddress(&dest))
{
DbgPrint("time to do some re-research\n");
}
for(i = 0; i <= 3; i++)
{
RtlInitUnicodeString(&dest,
find[i]);
if(dest.Length) // if Length == 0 my unicode string has some problems
{
DbgPrint("%d ", i);
if(MmGetSystemRoutineAddress(&dest))
{
DbgPrint("found\n");
}
else
{
DbgPrint("not found\n");
}
}
}
}
| |
It founds nothing.
From DriverEntry I register a DRIVER_UNLOAD routine, I call search and I return STATUS_SUCCESS so there's no need to post it all.
Now, where's my problem? The check call for MmGetSystemRoutineAddress is passed so I guess I'm not interpreting that function in a wrong way.
What is the Kernel function that is ultimately called when a new process is created?
EDIT:
I did the overkill:
I used MmGetSystemRoutineAddress to get ZwQuerySystemInformation. I called ZwQuerySystemInformation with SYSTEM_INFORMATION_CLASS = SystemModuleInformation, I iterated through them in search of the one who exports NtCreateProcess, I parsed it's PE to get to the exports table, I searched the exports table for NtCreateProcess and took it's address.
I found it. I still have to test to see how correct is this approach (hook this NtCreateProcess and see if it's called when a new process is created), but I'll let this for tomorrow.