3. Hide SSDT hooks by manipulating the KTHREAD structure
The second technique equals to the one described above. Again some copies of kernel structures are made. But now the service table pointer of each thread is changed to one of the copies. If you disassemble KiSystemService you see the resolving of function pointers by using the ServiceTable pointer of the current thread's KTHREAD structure. The ServiceTable pointer is set by KeInitThread() and later by PsConvertToGuiThread(). Depending on the thread type the address of KTHREAD either points to the SSDT or the SSDT-Shadow. The shadow structure contains pointers to functions which are used by GUIs and therefore PsConvertToGuiThread() will change normally the ServiceTable pointer to the SSDT-Shadow. Below you find the KTHREAD structure:
To stealth the SSDT hooks by manipulating the KTHREAD structure a copy of the SSDT and the SSDT-Shadow is made. For the next step the SSDT or SSDT-Shadow copy is modified to get control over certain system functions. Now the ServiceTable pointers to the corresponding structures in PsConvertToGuiThread() and KeInitThread() are changed to the copies by modifying the loaded kernel code. Furthermore all threads are enumerated and again the ServiceTable pointers are exchanged.
We have tested the detection of the hidden hooks with anti-rootkit tools like RootkitUnhooker, GMER, SVV and some more tools. None of them detected the kernel code and KTHREAD modification.
4. Results
The demo shows the loading of a driver example which hooks NtOpenProcess() by exchanging the ServiceTable pointer of new and existing threads. After hooking the latest RootkitUnhooker version is started to check any detections. You will see no detection success of the SSDT or SSDT-Shadow modification.