Instead of replacing the pointers in the SSDT, which makes it easy to recognize, an attacker can modify the kernel function or function in an existing kernel driver with a jmp instruction to reroute the execution flow to the malicious code. As mentioned earlier in this chapter, you can use the apihooks plugin to detect inline hooking in the kernel space. By specifying the -P argument, you can tell the apihooks plugin to only scan for the hooks in the kernel space. In the following example of a TDL3 rootkit, the apihooks detect the hooks in the kernel functions IofCallDriver and IofCompleteRequest. The hooked API functions are redirected to the 0xb878dfb2 and 0xb878e6bb addresses within a malicious module whose name is unknown (possibly because it is hiding by unlinking the KLDR_DATA_TABLE_ENTRY structure):
$ python vol.py -f tdl3.vmem --profile=WinXPSP3x86 apihooks -P
Volatility Foundation Volatility Framework 2.6
************************************************************************
Hook mode: Kernelmode
Hook type: Inline/Trampoline
Victim module: ntoskrnl.exe (0x804d7000 - 0x806cf580)
Function: ntoskrnl.exe!IofCallDriver at 0x804ee120
Hook address: 0xb878dfb2
Hooking module: <unknown>
Disassembly(0):
0x804ee120 ff2500c25480 JMP DWORD [0x8054c200]
0x804ee126 cc INT 3
0x804ee127 cc INT 3
[REMOVED]
************************************************************************
Hook mode: Kernelmode
Hook type: Inline/Trampoline
Victim module: ntoskrnl.exe (0x804d7000 - 0x806cf580)
Function: ntoskrnl.exe!IofCompleteRequest at 0x804ee1b0
Hook address: 0xb878e6bb
Hooking module: <unknown>
Disassembly(0):
0x804ee1b0 ff2504c25480 JMP DWORD [0x8054c204]
0x804ee1b6 cc INT 3
0x804ee1b7 cc INT 3
[REMOVED]
Even though the name of the hooking module is unknown, it is still possible to detect the malicious kernel module. In this case, we know the API functions are redirected to addresses starting with 0xb87 within the malicious module, which means the malicious module must be residing at some address starting with 0xb87. Running the modules plugin does not detect any module at that address range (because it is hidden), whereas the modscan plugin detected a kernel module called TDSSserv.sys loaded at base address 0xb878c000 with a size of 0x11000. In other words, the start address of the kernel module TDSSserv.sys is 0xb878c000 and the end address is 0xb879d000 (0xb878c000+0x11000). You can clearly see that the hook addresses 0xb878dfb2 and 0xb878e6bb fall within the address range of TDSSserv.sys. At this point, we have successfully identified the malicious driver. You can now dump the driver to disk for further analysis:
$ python vol.py -f tdl3.vmem --profile=WinXPSP3x86 modules | grep -i 0xb878
Volatility Foundation Volatility Framework 2.6
$ python vol.py -f tdl3.vmem --profile=WinXPSP3x86 modscan | grep -i 0xb878
Volatility Foundation Volatility Framework 2.6
0x0000000009773c98 TDSSserv.sys 0xb878c000 0x11000 \systemroot\system32\drivers\TDSSserv.sys