Driver can't find Nt/ZwCreateProcess

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.
Last edited on
FYI, many of the functions you are using are listed as effectively deprecated, for example:

MSDN wrote:
[ZwQuerySystemInformation is no longer available for use as of Windows 8. Instead, use the alternate functions listed in this topic.]
Well this is a good starting point to learn about the kernel. The functions "ZwCreateProcess()" and "ZwCreateUserProcess()" are both exported from 'ntdll.dll' which ntoskrnl.exe does not import by itself. You could of course link to this DLL from your driver but I'm pretty sure MSDN says specifically not to do that.

The functions that you can call from your stub are exported from ntoskrnl.exe and view-able the same way you would view them with a dll. If you don't have a tool for this I suggest 'DLL Export Viewer' by Nirsoft: http://www.nirsoft.net/utils/dll_export_viewer.html . The DLL's that are loaded are bootvid.dll, hal.dll and kdcom.dll so you can use functions from those files as well.
@Computergeek01 I started to explore with WinDbg and got to some pretty good results just following the flow of Create Process (there's even one chapter with this name in a Windows Internals book) and started to work my way from there. Now the image is clear. I have a pedumper that can dump the export table (or I could use dumpbin.exe), but that export viewer is nice. Thanks.

@Veltas I know, but I'm testing on Windows 7 and the objective was to explore the kernel so I used what functions I was more familiar with. Also, there's no officially supported way of getting SystemModuleInformation (or I haven't found it on MSDN). Unfortunately, I have no Windows 8 system at which I could poke around so that will have to wait.
Last edited on
Don't worry I'm not judging, it was just FYI.
This is the greatest answer I received on a problem I had.

I'm not worrying.
Topic archived. No new replies allowed.