Howto: Implementation of new system service calls (II)
Windows Research Kernel @ HPIIn this post we describe a very simple, but complete example of the implementation of a new system service call with the WRK. The system service prints a debug message from within the kernel and can be called from user mode.
You can download the application and a WRK patch for the necessary kernel modifications.
Kernel modifications
Our new system service call is called NtHelloKernel
.
It takes one integer value as argument and prints as many debug
messages. As explained in the
last post, we need to modify the system service dispatch table
and generate some stubs for the new system service call. Listing 1
and listing 2 show the necessary modifications.
.. TABLE_ENTRY QueryPortInformationProcess, 0, 0 TABLE_ENTRY GetCurrentProcessorNumber, 0, 0 TABLE_ENTRY WaitForMultipleObjects32, 1, 5 TABLE_ENTRY HelloKernel, 1, 1 TABLE_END 296 ..
.. SYSSTUBS_ENTRY8 295, WaitForMultipleObjects32, 5 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 STUBS_END
Finally, we need the implementation of the new system service routine. Listing 3 shows the implementation for our example.
NTSTATUS NtHelloKernel( int count ) { int i; PAGED_CODE(); if (count > 0) { for (i=0; i<count; ++i) { DbgPrint("Hello User! [%d]",i); } } return STATUS_SUCCESS; }
NtHelloKernel
implementation
The debug message is printed via DbgPrint
and
appears in the kernel debugger or in applications like DebugView.Now
compile the modified Windows kernel and boot your (virtual) machine
using this new kernel. The next section describes the development of
a simple test application.User mode application
We develop the application in two parts: a wrapper dynamic link library to call the new system service and the application program.
System service call wrapper DLL
Listing 4 and listing 5 show the header and the implementation
file for the wrapper DLL. We define a HelloKernel(int
count)
function which passes the count
argument
to the newly created system service.
#ifndef _MYNTDLL_H_ #define _MYNTDLL_H_ #ifdef MYNTDLL_EXPORT #define MYNTDLL_API __declspec(dllexport) NTSTATUS #define _X86_ #include <nt.h> #else #define MYNTDLL_API __declspec(dllimport) DWORD #pragma comment("lib","myntdll.lib") #include <windows.h> #endif MYNTDLL_API HelloKernel(int count); #endif // _MYNTDLL_H_ </windows.h></nt.h>
#define MYNTDLL_EXPORT #include "myntdll.h" NTSTATUS CallNtHelloKernel( int count ) { void** stackFrame = (void*)(&count); // call NtHelloKernel __asm { mov eax, 0x0128 // EE - modified WRK kernel mov edx, stackFrame int 0x2E } } MYNTDLL_API HelloKernel(int count) { return CallNtHelloKernel(count); }
HelloKernel
in the main function. The code is listed in listing 6.
#include <windows.h> #include <stdio.h> #include "myntdll.h" int main(int argc, char* argv[]) { printf("calling HelloKerneln"); // use new system service call HelloKernel(5); } </stdio.h></windows.h>
cmd.exe
) and initialize your build environment as
shown in listing 7. The adaptation of the include path is necessary
to make sure that the wrapper DLL and the application is built using
the SDK definitions from the WRK source tree. The WRKPATH
environment variable must be set to your WRK directory.
set ARCH=x86 set WRKPATH=X:WRK-v1.2 set PATH=%WRKPATH%toolsx86;%PATH% set INCLUDE=%WRKPATH%publicsdkinc;%WRKPATH%basentosinc;%WRKPATH%publicinternalbaseinc;%INCLUDE%
nmake
into command window. The makefile is shown in
listing 8.
all: myntdll.dll hellokernel.exe hellokernel.exe: myntdll.dll hellokernel.c myntdll.h cl /Zi hellokernel.c myntdll.lib myntdll.dll: myntdll.c myntdll.h cl /LD myntdll.c
hellokernel.exe
application. The next figure shows the result for a successful run
using DebugView.
If you try to execute the test application with an unmodified
Windows kernel (or a "normal" Windows XP system) you should receive
a "An invalid system service was specified in a system service
call."-message as result.Downloads
You can download and test the code of this article: kernelpatch and test application.
Comments
2 Responses to "Howto: Implementation of new system service calls (II)"
"An invalid system service was specified in a system service call."
Ah I know to well. Thanks for you have given me the solution to the problem that has been bugging me for far to long.
The code is nice and short too so there is less text for you to look over when checking for bugs and spelling mistakes. I once spent 2 hours figuring out the bug to a software I wrote and it turns out I misspelled one of the variables.