Log in

View Full Version : Retrieving System, Process and Thread information using ZwQuerySystemInformation


Kayaker
February 21st, 2004, 00:22
Hi All,

I wasn't particularly planning on releasing this, but it is a useful enough utility and example of driver programming. It demonstrates all the information you can retrieve using ZwQuerySystemInformation with the Information Classes of SystemBasicInformation, SystemProcessorInformation, SystemProcessesAndThreadsInformation and SystemModuleInformation.

In terms of more advanced driver programming, it gives an example of mapping kernel memory to user mode using MDL's, as described in the included OSR file 'Sharing Memory Between Drivers and Applications'.


The main reason I'm presenting it is in response to a question about detecting "invisible" processes, or possibly detecting if your code has been "injected". There is a bit of information that ZwQuerySystemInformation discloses that might be of some use. In particular, the SystemProcessesAndThreadsInformation class retrieves a few interesting bits of info for each running process, the ProcessId, and more importantly the InheritedFromProcessId, as well as the complete SYSTEM_THREADS listing.

Why is this important? A little playing with this utility will show that most User processes are started from the everpresent Windows Explorer process, and an applications' InheritedFromProcessId value reflects this. In other words, the ProcessId of Explorer = the InheritedFromProcessId of normally started applications. This appears to be true of applications started from the Desktop, StartMenu or Taskbar.


Now, can the InheritedFromProcessId tell the protectionist anything about the 'hijacking' loader? In terms of an attached Win32 debugger (i.e. OllyDbg), the answer is Yes, InheritedFromProcessId directly indicates the PID of the debugger. In terms of an injected dll, not necessarily, other than it exists, because in many cases of dll injection the "loader" has exited and only the injected dll remains, so the InheritedFromProcessId may be invalid or arbitrary.

So how to tell if your process is running an injected dll? By the number of threads running - if your program has only 1 main thread, but SystemProcessesAndThreadsInformation indicates 2, then you've got a stowaway and the CLIENT_ID structure will give you the ThreadID of it.

What you do then is your choice


I haven't explored all the possibilities of this in terms of protection or otherwise, nor tested with every known injection technique etc., this is just observations from a little playing with my own information gathering utility for personal use. Perhaps this will be of some use or interest to others, full source, tested on Win2K.

Regards,
Kayaker

mmk
February 21st, 2004, 00:44
You can always inject code into explorer and launch the app from an explorer.exe thread. That's what people will do if more apps check parent pid.

You also don't need to write a device driver to call ZwQuerySystemInformation().

Injecting code in another process doesn't mean you have to create a new thread.

It's a cat and mouse game, as you already know. You try to detect me, and I'll try to hide better. And do you know who the winner will be? Me. All I need to do is write a perfect CPU simulator and you'll never be able to tell if you're being debugged or not.

Kayaker
February 21st, 2004, 01:01
>You can always inject code into explorer and launch the app from an explorer.exe thread. That's what people will do if more apps check parent pid.

Good point, might be an interesting experiment.

>You also don't need to write a device driver to call ZwQuerySystemInformation().

Nope, but I was more interested in a reason for learning to use MDL's than in what the 'subject' was, nor was this meant to be a caveat for injection detection, a simple driver example and information utility only.

>It's a cat and mouse game, as you already know. You try to detect me, and I'll try to hide better. And do you know who the winner will be? Me. All I need to do is write a perfect CPU simulator and you'll never be able to tell if you're being debugged or not.

S'OK, I'm not trying to detect anybody, but you're right it is a fun game nonetheless

sna
February 22nd, 2004, 08:08
here's a note for all the protectionists that might be reading this thread and thinking that these are good techniques for preventing software cracking. now that Kayaker has been nice enough to create this module that plugs right into your software, before using it you should be aware of the possible drawbacks and problems that could arise from doing so.

first of all, everyone might not be big fans of the default windows shell and as commonly happens with things that we don't like they get replaced. this happens. quite often. http://www.shell-shocked.org/

second of all, if your application relies on any third-party code whatsoever (read: uses the Windows API) then there will be no guarantees of any kind as to how many/which modules are loaded. also, just because you're not creating separate job threads doesn't mean that the third-party code isn't. for example what if the Microsoft programmers decide that Windows 2005 should stick a garbage collector in every process?

just something to ponder...

regards, sna

Opcode
March 1st, 2004, 19:50
No one should trust in this module to see all process and threads running.
Rootkits are in a very advanced stage of hiding process and threads.
Actually, the unique tool that show all threads and process is the
Klister module (only for windows 2k).
It detects even processes hidden by the Fu rootkit.

Klister at
http://www.rootkit.com/project.php?id=14