WRK – Random IT Utensils https://blog.adamfurmanek.pl IT, operating systems, maths, and more. Sat, 02 Jan 2021 19:09:27 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 Windows Research Kernel Part 4 — New module https://blog.adamfurmanek.pl/2018/08/11/windows-research-kernel-part-4/ https://blog.adamfurmanek.pl/2018/08/11/windows-research-kernel-part-4/#comments Sat, 11 Aug 2018 08:00:51 +0000 https://blog.adamfurmanek.pl/?p=2551 Continue reading Windows Research Kernel Part 4 — New module]]>

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

To create a new module, you need to prepare some directories and a make file. First, create the following structure in base\ntos

module
|- amd64
|- BUILD
   |- objamd64
   |- obji386
|-i386

Next, in module\BUILD\ put a makefile file building the module:

library = $(module)
 
!if "$(targ)" == "i386"
# Anything related to i386
 
asobjs= \
	$(OBJ)\x86asmmodule.obj
 
ccarchobjs= \
	$(OBJ)\x86cmodule.obj
 
!else
#  Anything for amd64
!endif
 
ccobjs= \
	$(OBJ)\module.obj
 
!include $(ntos)\BUILD\makefile.build

At the end, you need to tell the global makefile to include your module in the building process. Go to base\ntos\makefile and add your module in line 26 (list of modules modules = rtl …).

Recompile and you are good to go.

]]>
https://blog.adamfurmanek.pl/2018/08/11/windows-research-kernel-part-4/feed/ 1
Windows Research Kernel Part 3 — Syscall https://blog.adamfurmanek.pl/2018/08/04/windows-research-kernel-part-3/ https://blog.adamfurmanek.pl/2018/08/04/windows-research-kernel-part-3/#comments Sat, 04 Aug 2018 08:00:42 +0000 https://blog.adamfurmanek.pl/?p=2546 Continue reading 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:

TABLE_ENTRY  HelloKernel, 1, 1

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:

SYSSTUBS_ENTRY1  296, HelloKernel, 1
SYSSTUBS_ENTRY2  296, HelloKernel, 1
SYSSTUBS_ENTRY3  296, HelloKernel, 1
SYSSTUBS_ENTRY4  296, HelloKernel, 1
SYSSTUBS_ENTRY5  296, HelloKernel, 1
SYSSTUBS_ENTRY6  296, HelloKernel, 1
SYSSTUBS_ENTRY7  296, HelloKernel, 1 
SYSSTUBS_ENTRY8  296, HelloKernel, 1

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:

NTSTATUS
NtHelloKernel(
    int count
    )
{
    int i;
    PAGED_CODE();
    for (i=0; i < count; ++i) {
        DbgPrint("Hello world: [%d]",i);
    }

    return STATUS_SUCCESS;
}

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:

void
CallNtHelloKernel(
	int count
	)
{
	void** stackFrame = (void*)(&count);

	__asm {
		mov eax, 0x0128
		mov edx, stackFrame
		int 0x2E
	}
}

int main(int argc, char* argv[]) {

	printf("calling HelloKernel\n");

	// use new system service call
	CallNtHelloKernel(5);
}

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.

]]>
https://blog.adamfurmanek.pl/2018/08/04/windows-research-kernel-part-3/feed/ 1
Windows Research Kernel Part 2 — Monitoring the function invocation https://blog.adamfurmanek.pl/2018/07/28/windows-research-kernel-part-2/ https://blog.adamfurmanek.pl/2018/07/28/windows-research-kernel-part-2/#comments Sat, 28 Jul 2018 08:00:00 +0000 https://blog.adamfurmanek.pl/?p=2543 Continue reading Windows Research Kernel Part 2 — Monitoring the function invocation]]>

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

In this part we are going to monitor the invocation of QuerySystemInformation system function by using the debugger.
First, make sure that you can debug the kernel. Next, open file base\ntos\ex\sysinfo.c. You can see that the function starts in line 1390. We will add a static variable to count the invocations, so go to the line 1721 and add the following:

static int NumTimesCalled = 0

Next, just before Status = STATUS_SUCCESS; in line 1728 add this:

DbgPrint("WRK  %d: Entering NTQuerySystemInformation\n", ++NumTimesCalled);

Recompile the kernel, add new boot option to the boot.ini, restart the OS, attach the debugger and you should see:

WRK  1: Entering NTQuerySystemInformation
WRK  2: Entering NTQuerySystemInformation

This is just a sample of what you can do with the code. Next time, we are going to implement the syscall.

]]>
https://blog.adamfurmanek.pl/2018/07/28/windows-research-kernel-part-2/feed/ 1
Windows Research Kernel Part 1 — Compiling and debugging https://blog.adamfurmanek.pl/2018/07/21/windows-research-kernel-part-1/ https://blog.adamfurmanek.pl/2018/07/21/windows-research-kernel-part-1/#comments Sat, 21 Jul 2018 08:00:47 +0000 https://blog.adamfurmanek.pl/?p=2539 Continue reading Windows Research Kernel Part 1 — Compiling and debugging]]>

This is the first part of the WRK series. For your convenience you can find other parts using the links below (or by guessing the address):
Part 1 – Compiling and debugging
Part 2 – Monitoring and function invocation
Part 3 — Syscall
Part 4 — New module

Nowadays Microsoft is very happy to share code of its tools with the open source community. But it wasn’t always the same — .NET Framework code wasn’t freely available, however, there was the project Rotor (or Shared Source CLI 2.0) which was a .NET implementation for research purposes. You could download the code, compile it on your own and experiment with the internals of the platform. It wasn’t exactly the same though, but it was good enough to see the code and play with it.

Similarly, there was a project with Windows OS source code, namely Windows Research Kernel. In this series we are going to compile the code, change some of its internals and see it in action.

WRK

Windows Research Kernel (WRK) is a source code of the kernel of Windows Server 2003 SP 1. It was released for research purposes so you couldn’t download it just like that, however, right now you might find it on Github pretty easily. The code is old, which means that getting it to work is a little hard, however, you should be able to follow the guide Getting started with WRK.doc to compile the project since it comes down to just running the bat file (assuming you have installed all of the dependencies). You can build the code for x86 and x64. There is also a solution (VS 2008!), you can just choose the configuration and build everything with your favorite IDE.

But the kernel is not enough, you need to have the rest of the Windows OS to actually test it. That’s why it was distributed with virtual machine based on Virtual PC 2007 (do you even remember this application?) which you could use to boot the kernel. The Windows Server 2003 installed in that VM was a little different than the normal one, i.e., it was showing the build number of the desktop so you could see which kernel you booted. Also, it had SP 1 installed and disabled updates because SP 2 was not compatible with the WRK.

Debugging

Let’s start with enabling debugging for the VM. I assume you downloaded the WRK and the VM image and you can run it correctly. I will be using VMWare Player. By the way, did you know that you can use the same hard drive file for VMWare, Virtual Box and Hyper-V? This way you can configure your VM to be able to boot it with any hypervisor you like, and also support boot to VHD to use it natively on your machine. Pretty cool.

First, you need to configure serial port for the machine and expose it as a named pipe for the host. You can see the configuration below:

Serial port configuration

The OS should have debugging enabled by default. If it is not, then you need to add the following to the boot.ini:

default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003, Standard"
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003, WRK" /kernel=wrkx86.exe /hal=< your HAL > /debug /debugport=com1
multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003, WRK - No Debugger" /kernel=wrkx86.exe /hal=< your HAL >

Remember to set correct HAL.

Finally, you need to configure WinDBG. Just use the following settings:

WinDBG settings

Also, configure your symbols to the correct directory. You can automate this by using the following script to run the debugger:

@echo off
set wrksymbols=%wrkpath%\base\ntos\BUILD\EXE
set dbgpipe=\\.\pipe\debugPipe
set dbgargs=-k com:pipe,port=%dbgpipe%,resets=0,reconnect -y %wrksymbols%
windbg %dbgargs%

Done. You should now be able to debug the kernel and play with it.

]]>
https://blog.adamfurmanek.pl/2018/07/21/windows-research-kernel-part-1/feed/ 3