Adding system call to WRK Kernel RRS feed

  • Question

  • Hi all:
        I'm developing an application on WRK, and now I need to add a system call to pass some info. to the kernel. I searched the net and there's very few resources about adding system calls, fortunately I got an attached ppt which is other people's work,but there're still some questions:

    here is the procedure to add system call extracted from the ppt(red is my comments):

    this step is to add the entry in the dispatcher table
    Edit the file: ntos\ke\i386\systable.asm:
    1. insert the code under line 392: TABLE_ENTRY New_syscall, 1, 2 <- 1 and 2 are the number of bytes of in the arguments, but not
    2. edit the following line as follows: TABLE_END 296                            match since the arguments are LONG and PCHAR ???

    I can't even find the "Netexapi.h" file
    Edit the file: public\sdk\inc\Netexapi.h:
    Insert the following code under line 2766 (it's a declearation of system call):
    NtNew_syscall(__in LONG input, __out PCHAR output);

    Is it true that all implementation of added system call must stay here?
    Edit the file: ntos\ex\Exatom.c
    From line 302 insert the implementation of the system call:
    LONG NtNew_syscall(__in LONG input, __out PCHAR output)
    {*output = 'A; return 100;'}

    Edit the file: ntos\init\ntoskrnl.src
    At line 912 insert this code: NtNew_syscall


    in the implementation, I need to access two variables decleared in a file resisting in another directory, how can I do it? include the header file where the declearation of the two variables exist in? Anyone can help? thanks a lot.
    Monday, February 23, 2009 4:08 PM

All replies

  • Hi,

    We use the WRK for teaching undergraduate students, and, as part of their curriculum, they also need to implement a system call on their own. As there are several steps required, we created an online tutorial guiding you a bit more precisely through each single step.

    The tutorial has three parts, which you can find her:

    Part I,
    Part II, and
    Part III.

    Please let me know, if this was helpful to you.

    As far as your questions are concerned:

    1. insert the code under line 392: TABLE_ENTRY New_syscall, 1, 2

    I am not exactly sure on what the first number semantically means, but it is always 1 if this function has any arguments and is zero if it has none. The second argument to that macro defines the number of arguments of your system call.

    The TABLE_END macro just defines how many system calls your kernel has.

    2. Ntexapi.h

    I have never edited this file when creating a system call. In my opinion, it's just necessary, if other components of the kernel, or drivers, should be able to use your function. If you just use your function as system call by your own application, it should not be necessary to declare your function there.

    3. Is it true that all implementation of added system call must stay here?

    No, its not. You can even add a new C file to the kernel that contains the implementation of your system call. You have, however, to make sure that this file is compiled, which means you have to adapt the makefile of the respective module. For example, if you put your implementation in a file, say myimpl.c in the ntos\ex folder, you have to modify the ntos\ex\BUILD\makefile file. In this file, there is a definition of object files (the ccobjs variable) that should be compiled for the module. You just have to append your file here, i.e., append $(OBJ)\myimpl.obj to the list of object files. That should be it.

    4. Using global variables

    You can use of course variables you have defined in another module. If you want to use them, you have to declare them as extern in any file that wants to use this variables. The linker will then make sure you see the right variable. However, regarding my postings above, there is no reason why your implementation should not be contained where you have defined your variables.

    I hope my answers were helpful to you.


    Part II
    Wednesday, February 25, 2009 10:22 AM
  • Hi Alex:
        Thank you so much for your patient and time spent on answering my question. I have read the articles before seeing your reply and they are very helpful. Now I have another question, and I'll very appreciate if you can help:
        In my application, I created an process, and have got the process handle (of type HANDLE) and process id (of type DWORD), now I need to add a system call and in the implementation, I need the pointer to the EPROCESS structure. I tried to do so by using PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *process),  but the processId here is of type HANDLE, which I think is the one defined in EPROCESS structure, so it has nothing to do with the process id which I get when I create the process. Is there any other way to obtain the pointer to EPROCESS structure. Thank you .
    Thursday, February 26, 2009 9:21 PM
  • Hi,

    Although the process ID you get after invoking CreateProcess() is of type DWORD, you can just cast it into a HANDLE when invoking your system call. The type DWORD just does not exist in the kernel. All IDs (thread IDs and process IDs) are of type HANDLE. So, the PsLookupProcessByProcessId() will indeed work :)

    Tuesday, April 7, 2009 8:28 AM