There are anti-rootkit applications that can rebuild the system call table. This can be done by reinitializing kernel memory from the original file, ntoskrnl.exe. If the system call table is rebuilt after your rootkit is installed, all hooks will be lost. To prevent this possibility, newer rootkits follow the table entries to the actual functions and patch the functions themselves to jump to their respective rootkit routines. This technique is called trampolining and will be used for process injection in Chapter 4.
Of course, newer anti-rootkit applications can also follow the table entries to the actual functions and then restore any function that has been altered, so your rootkit will need a way to trap checks of the system call table, or trap the loading of ntoskrnl.exe. Because adding jumps inside the actual kernel functions only makes it harder for anti-rootkit software to remove your hooks, adding even more hooks to prevent anti-rootkit software from seeing the actual system call table (or the actual contents of ntoskrnl.exe) is the only guaranteed approach.
Of the two, trapping checks of the system call table is recommended. This is because of the possibility that anti-rootkit software may one day come with a static version of ntoskrnl.exe for every version of every Windows operating system. If the anti-rootkit version of ntoskrnl.exe has another name, hooking ZwOpenFile and looking for ntoskrnl.exe won’t catch it!
To trap checks of the system call table you will need to hook MmCreateMdl and look for the base address of the system call table (KeServiceDescriptorTable.ServiceTableBase). You should also hook ZwOpenSection and look for an OBJECT_ATTRIBUTE using \device\physicalmemory. If the process that opened physical memory also attempts to write to the system call table, you can be sure your hooks are in jeopardy. Of course, it may only be another rootkit.