Threads

Windows processes consist of one or more threads, or independent concurrent execution sequences that share the same memory and resources. When Windows starts program, it creates the very first thread, called the main thread, which later may start other threads. In fact, there is nothing special with the main thread, it has the same rights as his children. The process terminates when the last thread in this process exits.

Each thread has its own set of registers ("context"), its own stack and optionally its own local storage (TLS) . To facilitate data handling, segment register FS in the contents of the thread points to the Thread Information Block (TIB). This structure contains pointer to the start of the SEH chain (SEH stays for Structured Exception handling), stack limits, thread ID, location of TLS and some other useful data. When you see the commands like MOV [FS:0],data, it means that thread adds or excludes exception filters to or from the SEH chain.

Every thread has 32-bit unique thread identifier.
This identifier is different each time you start the application. If you set conditional breakpoint that triggers on a thread with a certain ID, this breakpoint will no longer work after you restart the application. To overcome this problem, OllyDbg assigns ordinal to each newly created thread. Main thread has ordinal 1, first created thread - ordinal 2 etc. Of course, this will work only if the order of thread creation is always the same.

Under some circumstances (for example, when OllyDbg requests Windows to pause application) Windows may create service thread. Such threads get ordinal 0 and don't increment the counter. They are marked as Temp in the Threads window.

Main thread is created simultaneously with the process. When process and main thread start, 
plugin gets notification PN_NEWPROC (via ODBG2_Pluginnotify()). When any other thread starts, plugin receives PN_NEWTHR. If thread therminates but it is not the last thread in the process, the notification is PN_ENDTHR. And finally, termination of the last thread is marked by PN_ENDPROC.

OllyDbg keeps thread descriptions in the table of threads (accessible through the exported variable thread) in the set of  t_thread structures.


API functions:

t_thread * Findthread(ulong threadid);
t_thread * Findthreadbyordinal(int ordinal);
t_reg * Threadregisters(ulong threadid);
int Decodethreadname(wchar_t *s,ulong threadid,int mode);
void Registermodifiedbyuser(t_thread *pthr);
void Suspendallthreads(void);
void Resumeallthreads(void);
int Getlasterror(t_thread *pthr,ulong *error,wchar_t *s);
ulong Getcputhreadid(void);


See also:
Execution control, modules, t_thread, ODBG2_Pluginnotify()