A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #10102  by madaboo
 Sat Dec 03, 2011 3:13 pm
Hi,

Got two questions.
1. How to obtain list of all threads (even system one) ? One of the way is to use ZwQuerySystemInformation, but I'm looking for better solution (e.g modules has PsLoadedModulesList, so maybe there is something similiar for threads? Or like each eprocess has ActiveProcessList, then maybe threads has something?).

2. Is it possible to get routine address of thhe thread? e.g taking it from ethread structure?

Thank you for joining.
 #10107  by Alex
 Sat Dec 03, 2011 5:23 pm
1. ZwQuerySystemInformation checks the linked list of process's runing threads - Process->ThreadListHead, so you can do it directly or for example analyze thread scheduler lists - Rootkit Unhooker v3.8 It's Past, Present and Future of the NTx86 Rootkit Detection.

2. What dou you mean? Are you asking for thread's start routine address or current thread's call address? Both of them you can get directly from ETHREAD - Thread->StartAddress and HOWTO: Capture kernel stack traces, Grabbing Kernel Thread Call Stacks the Process Explorer Way.
 #10125  by EP_X0FF
 Sun Dec 04, 2011 1:57 am
madaboo wrote:Hi,

Got two questions.
1. How to obtain list of all threads (even system one) ? One of the way is to use ZwQuerySystemInformation, but I'm looking for better solution (e.g modules has PsLoadedModulesList, so maybe there is something similiar for threads? Or like each eprocess has ActiveProcessList, then maybe threads has something?).

2. Is it possible to get routine address of thhe thread? e.g taking it from ethread structure?

Thank you for joining.
1. You can get all threads by parsing PspCidTable, but I do not recommend you this in commercial app. As well as any offsets hardcoding if you want to traverse ETHREAD's manually. There always must be used documented ways as long as it only possible.

2. NtQueryInformationThread with ThreadQuerySetWin32StartAddress information class. Or Zw version for kernel.
Don't forget that values of StartAddress and Win32StartAddress in ETHREAD are not the same. Also keep in mind that most of threads initialized by BaseThreadStartThunk, RtlUserThreadStart (or BaseProcessStartThunk for the first thread in process). Also notice that for NT5.x kernels Win32StartAddress may contain value of LpcReceiveMessageId instead of real thread start address.
 #10147  by rkhunter
 Mon Dec 05, 2011 11:03 am
madaboo wrote:Ok guys.

Finally I've used ZwQuerySystemInformation, class 5 (SYSTEM_PROCESS_INFORMATION) and I am ab le to get all threads,
However how to get those threads hadnles?
When I traverse throu list of threads for given process I have this structure
http://undocumented.ntinternals.net/Use ... HREAD.html
So how to take handle?
ClientId.UniqueThread field
 #10149  by madaboo
 Mon Dec 05, 2011 12:29 pm
rkhunter thatnk you for your response.

So for now I would like to make summary what I would like to do.
There is workitem created by driver A.

Now I'm loading driver B and I would like to get handle of the thread that is going inside WorkItem created before.

So I'm ZwQUerying system information, checking if proc Id is 0x04 (system) And then go thru list of threads.

Assume we know base address of driver A. How can I take handle to drivers routine?
Code: Select all
NTSTATUS Status;

  ULONG SystemInformationLength = 0;

  PVOID SystemInformation;

  PSYSTEM_PROCESS_INFORMATION lpSystemProcessInformation;

  OBJECT_ATTRIBUTES oaThread;
  ULONG PreviousEntryOffset;
  HANDLE hThread;

	ULONG Count = 0;
	ULONG counter = 0;
	ULONG size = 0;


  ZwQuerySystemInformation(5, NULL, 0, &SystemInformationLength);

  SystemInformationLength += 0x400;

  SystemInformation = ExAllocatePool(NonPagedPool, SystemInformationLength);

  Status = ZwQuerySystemInformation(5, SystemInformation, SystemInformationLength, NULL);

  if (STATUS_SUCCESS == Status) {

    lpSystemProcessInformation = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;


    do

    {

		if (lpSystemProcessInformation->ProcessId !=  0x04 ) 
		{
				PreviousEntryOffset = lpSystemProcessInformation->NextEntryOffset;
				lpSystemProcessInformation = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)lpSystemProcessInformation + PreviousEntryOffset);
			continue;
		
		}


      ++Count;

	
	
		for (counter = 0; counter < lpSystemProcessInformation->NumberOfThreads; ++counter)
		{

// now how to get routine address of this thread??? I need to chceck if this is driver A rotuine??
		}

      PreviousEntryOffset = lpSystemProcessInformation->NextEntryOffset;

      lpSystemProcessInformation = (PSYSTEM_PROCESS_INFORMATION)((ULONG_PTR)lpSystemProcessInformation + PreviousEntryOffset);

    } while (PreviousEntryOffset);

  };

  KERNEL_DEBUG(("%u process found \r\n", Count));

  ExFreePool(SystemInformation);


 #10152  by madaboo
 Mon Dec 05, 2011 2:42 pm
Acctually I don't catch on what member StartAddress in SYSTEM_THREAD structure is really pointing?

It is pointig to ethread? Thread Objecty? routine?
What is it?

My first question about hwo to get routine address is still unsolved..

Thank you anyway.
 #10154  by Alex
 Mon Dec 05, 2011 4:13 pm
Returned StartAddress of worker threads should point to nt!ExpWorkerThread routine instead of to routine address assumed to WorkerRoutine.