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
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.
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.
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);
int Getlasterror(t_thread *pthr,ulong *error,wchar_t *s);