A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #16956  by Tigzy
 Sun Dec 02, 2012 10:54 am
Hello

I would like to know how to find the entry point of a Worker thread?
Seems like Xuetr is able to do it.

I've parsed the system threads, and looked at the ETHREAD object.
Can't find anything pointing the entry point of the worker thread.

See attached - I've highlighted one particular thread seen in both Xuetr and my script.
We clearly see that StartAddress != Routine entry
Capture.PNG
Capture.PNG (62.21 KiB) Viewed 540 times
 #16958  by EP_X0FF
 Sun Dec 02, 2012 1:02 pm
And why do you think that system worker thread StartAddress must be WorkerThread routine itself? That is ridiculous assume. What is worker thread? Worker thread is system thread created by ntos during initialization in ExpInitializeExecutive->ExInitSystem->ExpInitSystemPhase1 and next count of WorkerThreads are decided dynamically by special balance manager thread. ExQueueWorkItem inserts new item inside ExWorkerQueue[QueueType] which is per-queue dynamic thread state.
 #16960  by Tigzy
 Sun Dec 02, 2012 1:27 pm
Yeah, but I though once the WorkItem was de-queued and the thread started it could be feasible to know where that thread has started.
And yes it's feasible as Xuetr does it. You have no idea?
 #16962  by EP_X0FF
 Sun Dec 02, 2012 2:03 pm
No idea in what? I gave you direct tip where to dig. ExQueueWorkItem inserts new WorkItem struct into ExWorkerQueue list depending of QueueType.

http://msdn.microsoft.com/en-us/library ... s.85).aspx
Code: Select all
VOID
ExQueueWorkItem (
    IN OUT PWORK_QUEUE_ITEM WorkItem,
    IN WORK_QUEUE_TYPE QueueType
    )
{

    .............
      Queue = &ExWorkerQueue[QueueType];
      KeInsertQueue(&Queue->WorkerQueue, &WorkItem->List);

   ............

}
Probably this piece of shit, I mean Xuetr, is parsing this lists. Or what you want? StartAddress of worker thread or how to identify worker thread?
 #16965  by Tigzy
 Sun Dec 02, 2012 4:12 pm
Sorry for the confusing.
Actually I already looked at that queues

http://msdn.microsoft.com/en-us/library ... 85%29.aspx
The system worker thread removes the work item from the queue before it calls the worker thread. Thus, a driver thread can safely queue the work item again as soon as the worker thread starts to run.
As soon as the Thread is running, the work item no longer exists in the queue.
You cannot retrieve it from there. (This is what I understand)

PS: Rkhunter already gave me that tip, but we concluded that indeed, running thread cannot be retrieved in the queue (after coding something to dump the remaining items)
 #16966  by EP_X0FF
 Sun Dec 02, 2012 4:22 pm
Sure you can't because ExpWorkerThread
Code: Select all
Entry = KeRemoveQueue (&WorkerQueue->WorkerQueue,
                               WaitMode,
                               Timeout);

        if ((ULONG_PTR)Entry != STATUS_TIMEOUT) {

            InterlockedIncrement ((PLONG)&WorkerQueue->WorkItemsProcessed);
            WorkItem = CONTAINING_RECORD(Entry, WORK_QUEUE_ITEM, List);
            WorkerRoutine = WorkItem->WorkerRoutine;
            Parameter = WorkItem->Parameter;

            // Execute the specified routine.
               ((PWORKER_THREAD_ROUTINE)WorkerRoutine) (Parameter);
So what do you want to do? And why?
 #16967  by Tigzy
 Sun Dec 02, 2012 4:27 pm
// Execute the specified routine.
((PWORKER_THREAD_ROUTINE)WorkerRoutine) (Parameter);
Get this : (ULONG)WorkerRoutine
What I want is identify the driver (by address range) where all worker threads are running from.
When unknown driver, be able to suspend the thread (NtSuspendThread? That's another question)

Maybe you know where I'm going if you have (and you surely did) analysed TDL4
 #16968  by EP_X0FF
 Sun Dec 02, 2012 4:41 pm
Tigzy wrote:
// Execute the specified routine.
((PWORKER_THREAD_ROUTINE)WorkerRoutine) (Parameter);
Get this : (ULONG)WorkerRoutine
What I want is identify the driver (by address range) where all worker threads are running from.
When unknown driver, be able to suspend the thread (NtSuspendThread? That's another question)

Maybe you know where I'm going if you have (and you surely did) analysed TDL4

Yes UM NtSuspendThread can suspend it. OK, TDL3/TDL4/TDL4+ works from self-allocated memory block outside of loaded drivers range. Analyse worker thread stack. It will lead you to TDL4 allocated memory.
 #16970  by EP_X0FF
 Sun Dec 02, 2012 4:59 pm
Tigzy wrote:
Analyse worker thread stack
Well, I was afraid of that... :/ Some libs for stack trace dumping in KM?
Try this, have no idea if this works, because PE can't display anything for me.
http://forum.sysinternals.com/howto-cap ... 19356.html

However I never used it, because for ARK it was much better and fastest ways (as we thought in 2007-2008).
There's no KM NtSuspendThread?
IIRC they all (NtSuspendThread->PsSuspendThread->KeSuspendThread) are not exported. Use hacks (call pointer from SSDT with hacked PreviousMode) or reinvent the wheel (Apc). Or simple call it from UM which is the best and easiest solution that ever can be imagined.