I already described how to search for processes and threads - but I still didn't explain why I think this is necessary. In this article I will summarize the state-of-the-art in Windows memory analysis and propose an improvement based on searching.
During the course of the year 2005 I found out about three programs for Windows memory forensic.
The two other tools I'm aware of, MemParser and kntlist, came off as winners from the Memory Analysis Challenge by the Digital Forensics Research Workshop (DFRWS). Unfortunately both tools are not available to the public.
MemParser by Chris Betz also seems to walk a list of processes, just like WMFT. The tool's output available from the DFRWS website doesn't show any traces of processes which had already terminated, for instance an exploit against the Local Security Authority Subsystem (LSASS) of the victim's system.
Kntlist by George M. Garner Jr. and Robert-Jan Mora also walks internal lists of the Windows kernel. In contrary to the previously mentioned tools kntlist does not rely solely on a list of processes, but also walks threads, files, sockets and other kinds of objects.
I can see two limitations in all those list-walkers, as I'd like to call them. At first, they are prone to a hiding technique called Direct Kernel Object Manipulation or short DKOM, which is common among rootkits. In brevity, a rootkit will hide a process (or any other object) by removing it from the list. It then fills the gap by cross-linking the object's neighbours with each other. From all three programs only kntlist may counter the attack because it checks several lists and detects inconsistencys. For example, the threads belonging to a process hidden by DKOM will still show up in the scheduler's list of threads. Kntlist will pick them up there and then follow the ThreadsProcess pointer to the EPROCESS structure describing the hidden process.
The second limitation arises from the fact that the internal lists were not intended for auditing purposes but only for housekeeping by the kernel. Windows will remove unused objects like terminated threads and processes from the corresponding lists as soon as possible. Hence a list-walker can't find a properly terminated process or thread.
The following graph shows the hierarchy of processes generated by an early version of PTfinder from one of the images provided for the DFRWS challenge. I compared the findings with the results from the leading tool, kntlist. Processes marked in red were not found by kntlist.
It's almost the same as undeleting a file. One would try to recover the directory entry and then rebuild the file from the meta-information. If that fails one could still try to carve the file from unallocated clusters. Searching for EPROCESS and ETHREAD structures in memory images is like searching for deleted directory entries. It recovers a lot of meta-information about a process or thread, but not its memory allocations, code and state.
It would be hard if not impossible to define proper search patterns for the vast amount of information list-walkers can retrieve from all those lists. That's why I don't see searchers like PTfinder as replacement for list-walkers in general and kntlist in particular. Each class has its own strengths and weaknesses. The combination of both principles would lead to a better tool: A search could identify defunct or hidden objects as starting points for a list-walker, which would then add all the remaining information. Crosschecking the results of searchers and list-walkers could make the forensic examiner instantaneously becoming aware of suspicious system activity.