Windows Research Kernel Part 3 — Syscall

This is the third part of the WRK series. For your convenience you can find other parts in the table of contents in Part 1 — Compiling and debugging

Today we are going to write a very simple hello world in the kernel space. Let’s go.

Kernel

First, we need to add new syscall to the table of services. Go to the file base\ntos\ke\i386\systable.asm. In line 392 add the following:

This specifies that at least one argument must be passed (first 1) and at most one as well (second 1).
Next, replace TABLE_END 295 with TABLE_END 295.

Now we need to add a stub. Go to base\ntos\ke\i386\sysstubs.asm and add the following in line 2485:

Now the linker expects a method with one int parameter. We need to implement it, so let’s go to base\ntos\ps\psquery.c and add the following in line 4220:

Recompile the kernel and reboot the os.

User mode

Now we need to execute the method from the user space. In theory we should implement a wrapper for the syscall in a DLL. Next, we would just write an application calling the method via the DLL. But, we are going to do it a little differently:

We first define a method with exactly the same signature as the method in the kernel. Next, we define a stack frame for the parameter. Finally, we switch to the kernel space with the interrupt. eax register holds the ordinal of the syscall (remember what number we put in sysstubs.asm?) and edx holds a stack frame.

Finally, we just call this method from the C code.

Compile the code to a binary. This binary is completely unrelated to the WRK, it is just an application like every other. Copy it to your VM and run in your modified kernel. As a bonus, try to run it with the unmodified WRK kernel and see what happens.