hi,
I'm trying to find out as much as i can about this interesting thing so far i have created these fasm structures. if anyone can help me either add to or correct these that would be great. also if anyone could point me to texts which cover this topic...i have already read matt pietreks text, but he seems to leave alot of info out but it's an otherwise great read.
thanks


struc TIB_NT
{
.pExcept dd ?;00
.pvStackUserTop dd ?;04
.pvStackUserBase dd ?;08
.SubSystemTib dd ?;0C
.FiberData dd ?;10
virtual at .FiberData
.Version dd ?;10
end virtual
.pvArbitrary dd ?;14
.ptibSelf dd ?;18
.Unknown1 dd ?;1C
.processID dd ?;20
.threadID dd ?;24
.Unknown2 dd ?;28
.pvTLSArray dd ?;2C
}


struc TIB_9X
{
.pExcept dd ?;00
.pvStackUserTop dd ?;04
.pvStackUserBase dd ?;08
.pvTDB dw ?;0C
.pvThunkSS dw ?;10
.pvArbitrary dd ?;14
.ptibSelf dd ?;18
.TIBFlags dw ?;1C
.Win16MutexCount dw ?;20
.DebugContext dd ?;24
.pCurrentPriority dd ?;28
.pvQueue dd ?;2C
.pvTLSArray dd ?;30
.pProcess dd ?;34
}
Posted on 2003-02-24 13:43:47 by keyoke
Hi

I've got this one article on the TIB/TEB structure, the link used to be
http://wiki.forth.org.ru/ThreadEnvironmentBlock
but I doubt it works, so attached.

Seems I also saved a thread from this board on the subject about a year ago (April 14th, 2002), search under General > Main > two questions post. Author Arthur_Chen

Kayaker
Posted on 2003-02-24 21:21:19 by Kayaker
There is no TIB_NT structure. There is NT_TIB structure which is the first part of TEB structure.

TEB - Thread Environment Block
NT_TIB - Thread Information Block

This definition is from masm32's windows.inc:
NT_TIB STRUCT

ExceptionList dd ?
StackBase dd ?
StackLimit dd ?
SubSystemTib dd ?
union
FiberData dd ?
Version dd ?
ends
ArbitraryUserPointer dd ?
Self dd ?
NT_TIB ENDS

This definition is fron W2K DDK:
//

// Thread Environment Block (and portable part of Thread Information Block)
//

//
// NT_TIB - Thread Information Block - Portable part.
//
// This is the subsystem portable part of the Thread Information Block.
// It appears as the first part of the TEB for all threads which have
// a user mode component.
//
//

// begin_winnt

typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
PVOID StackBase;
PVOID StackLimit;
PVOID SubSystemTib;
union {
PVOID FiberData;
ULONG Version;
};
PVOID ArbitraryUserPointer;
struct _NT_TIB *Self;
} NT_TIB;
typedef NT_TIB *PNT_TIB;

This definition shows Kernel Debugger:
kd> !kdex2x86.strct NT_TIB

Loaded kdex2x86 extension DLL
struct _NT_TIB (sizeof=28)
+00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList
+04 void *StackBase
+08 void *StackLimit
+0c void *SubSystemTib
+10 void *FiberData
+10 uint32 Version
+14 void *ArbitraryUserPointer
+18 struct _NT_TIB *Self

The TEB (Thread Environment Block) is completely undocumented.
Even in *.pdb from W2K i couldn't find anything.

The definition below i've fetched from ntoskrnl.pdb file from XP DDK.

struct _TEB {

/*<thisrel this+0x0>*/ /*|0x1c|*/ struct _NT_TIB NtTib;
/*<thisrel this+0x1c>*/ /*|0x4|*/ void* EnvironmentPointer;
/*<thisrel this+0x20>*/ /*|0x8|*/ struct _CLIENT_ID ClientId;
/*<thisrel this+0x28>*/ /*|0x4|*/ void* ActiveRpcHandle;
/*<thisrel this+0x2c>*/ /*|0x4|*/ void* ThreadLocalStoragePointer;
/*<thisrel this+0x30>*/ /*|0x4|*/ struct _PEB* ProcessEnvironmentBlock;
/*<thisrel this+0x34>*/ /*|0x4|*/ unsigned long LastErrorValue;
/*<thisrel this+0x38>*/ /*|0x4|*/ unsigned long CountOfOwnedCriticalSections;
/*<thisrel this+0x3c>*/ /*|0x4|*/ void* CsrClientThread;
/*<thisrel this+0x40>*/ /*|0x4|*/ void* Win32ThreadInfo;
/*<thisrel this+0x44>*/ /*|0x68|*/ unsigned long User32Reserved[26];
/*<thisrel this+0xac>*/ /*|0x14|*/ unsigned long UserReserved[5];
/*<thisrel this+0xc0>*/ /*|0x4|*/ void* WOW32Reserved;
/*<thisrel this+0xc4>*/ /*|0x4|*/ unsigned long CurrentLocale;
/*<thisrel this+0xc8>*/ /*|0x4|*/ unsigned long FpSoftwareStatusRegister;
/*<thisrel this+0xcc>*/ /*|0xd8|*/ void* SystemReserved1[54];
/*<thisrel this+0x1a4>*/ /*|0x4|*/ long ExceptionCode;
/*<thisrel this+0x1a8>*/ /*|0x14|*/ struct _ACTIVATION_CONTEXT_STACK ActivationContextStack;
/*<thisrel this+0x1bc>*/ /*|0x18|*/ unsigned char SpareBytes1[24];
/*<thisrel this+0x1d4>*/ /*|0x4e0|*/ struct _GDI_TEB_BATCH GdiTebBatch;
/*<thisrel this+0x6b4>*/ /*|0x8|*/ struct _CLIENT_ID RealClientId;
/*<thisrel this+0x6bc>*/ /*|0x4|*/ void* GdiCachedProcessHandle;
/*<thisrel this+0x6c0>*/ /*|0x4|*/ unsigned long GdiClientPID;
/*<thisrel this+0x6c4>*/ /*|0x4|*/ unsigned long GdiClientTID;
/*<thisrel this+0x6c8>*/ /*|0x4|*/ void* GdiThreadLocalInfo;
/*<thisrel this+0x6cc>*/ /*|0xf8|*/ unsigned long Win32ClientInfo[62];
/*<thisrel this+0x7c4>*/ /*|0x3a4|*/ void* glDispatchTable[233];
/*<thisrel this+0xb68>*/ /*|0x74|*/ unsigned long glReserved1[29];
/*<thisrel this+0xbdc>*/ /*|0x4|*/ void* glReserved2;
/*<thisrel this+0xbe0>*/ /*|0x4|*/ void* glSectionInfo;
/*<thisrel this+0xbe4>*/ /*|0x4|*/ void* glSection;
/*<thisrel this+0xbe8>*/ /*|0x4|*/ void* glTable;
/*<thisrel this+0xbec>*/ /*|0x4|*/ void* glCurrentRC;
/*<thisrel this+0xbf0>*/ /*|0x4|*/ void* glContext;
/*<thisrel this+0xbf4>*/ /*|0x4|*/ unsigned long LastStatusValue;
/*<thisrel this+0xbf8>*/ /*|0x8|*/ struct _UNICODE_STRING StaticUnicodeString;
/*<thisrel this+0xc00>*/ /*|0x20a|*/ unsigned short StaticUnicodeBuffer[261];
/*<thisrel this+0xe0c>*/ /*|0x4|*/ void* DeallocationStack;
/*<thisrel this+0xe10>*/ /*|0x100|*/ void* TlsSlots[64];
/*<thisrel this+0xf10>*/ /*|0x8|*/ struct _LIST_ENTRY TlsLinks;
/*<thisrel this+0xf18>*/ /*|0x4|*/ void* Vdm;
/*<thisrel this+0xf1c>*/ /*|0x4|*/ void* ReservedForNtRpc;
/*<thisrel this+0xf20>*/ /*|0x8|*/ void* DbgSsReserved[2];
/*<thisrel this+0xf28>*/ /*|0x4|*/ unsigned long HardErrorsAreDisabled;
/*<thisrel this+0xf2c>*/ /*|0x40|*/ void* Instrumentation[16];
/*<thisrel this+0xf6c>*/ /*|0x4|*/ void* WinSockData;
/*<thisrel this+0xf70>*/ /*|0x4|*/ unsigned long GdiBatchCount;
/*<thisrel this+0xf74>*/ /*|0x1|*/ unsigned char InDbgPrint;
/*<thisrel this+0xf75>*/ /*|0x1|*/ unsigned char FreeStackOnTermination;
/*<thisrel this+0xf76>*/ /*|0x1|*/ unsigned char HasFiberData;
/*<thisrel this+0xf77>*/ /*|0x1|*/ unsigned char IdealProcessor;
/*<thisrel this+0xf78>*/ /*|0x4|*/ unsigned long Spare3;
/*<thisrel this+0xf7c>*/ /*|0x4|*/ void* ReservedForPerf;
/*<thisrel this+0xf80>*/ /*|0x4|*/ void* ReservedForOle;
/*<thisrel this+0xf84>*/ /*|0x4|*/ unsigned long WaitingOnLoaderLock;
/*<thisrel this+0xf88>*/ /*|0xc|*/ struct _Wx86ThreadState Wx86Thread;
/*<thisrel this+0xf94>*/ /*|0x4|*/ void** TlsExpansionSlots;
/*<thisrel this+0xf98>*/ /*|0x4|*/ unsigned long ImpersonationLocale;
/*<thisrel this+0xf9c>*/ /*|0x4|*/ unsigned long IsImpersonating;
/*<thisrel this+0xfa0>*/ /*|0x4|*/ void* NlsCache;
/*<thisrel this+0xfa4>*/ /*|0x4|*/ void* pShimData;
/*<thisrel this+0xfa8>*/ /*|0x4|*/ unsigned long HeapVirtualAffinity;
/*<thisrel this+0xfac>*/ /*|0x4|*/ void* CurrentTransactionHandle;
/*<thisrel this+0xfb0>*/ /*|0x4|*/ struct _TEB_ACTIVE_FRAME* ActiveFrame;
};
// <size 0xfb4>
Posted on 2003-02-25 05:13:36 by Four-F
shot for the help :)
this is the struc i have now after reading these...but the virtual's mite be wrong still but this is fasm specific so ill ask there


struc _TIB
{
.pExcept dd ? ;00
.pvStackUserTop dd ? ;04
.pvStackUserBase dd ? ;08
virtual at $ ;win95
.pvTDB dw ? ;0C
.pvThunkSS dw ? ;0E
.unknown dd ? ;10
end virtual
virtual at $ ;winnt
.SubSystemTib dd ? ;0C
.FiberData dd ? ;10
end virtual
.pvArbitrary dd ?;14
.ptibSelf dd ?;18
virtual at $ ;win95
.TIBFlags dw ? ;1C
.Win16MutexCount dw ? ;1E
.DebugContext dd ? ;20
.pCurrentPriority dd ? ;24
.pvQueue dd ? ;28
end virtual
virtual at $ ;winnt
.unknown1 dd ? ;1C
.processID dd ? ;20
.threadID dd ? ;24
.unknown2 dd ? ;28
end virtual
.pvTLSArray dd ?;2C
virtual at $
.pProcess dd ? ;30
end virtual
}

Posted on 2003-02-25 05:43:41 by keyoke
Never used fasm. Sorry. You'd better ask in fasm-specific forum on this board about virtual.
Posted on 2003-02-25 08:28:26 by Four-F
if any1 is interested this is my version of tib/teb structure it's fasm specific tho
thnx for the help guys :)


struc _TIB
{
.pExcept dd ? ;00
.pvStackUserTop dd ? ;04
.pvStackUserBase dd ? ;08
virtual at $ ;win95
.pvTDB dw ? ;0C
.pvThunkSS dw ? ;0E
.unknown dd ? ;10
end virtual
virtual at $ ;winnt
.SubSystemTib dd ? ;0C
.FiberData dd ? ;10
virtual at .FiberData
.Version dd ? ;10
end virtual
end virtual
rd 2;reserve 2 double words
.pvArbitrary dd ?;14
.ptibSelf dd ?;18
virtual at $ ;win95
.TIBFlags dw ? ;1C
.Win16MutexCount dw ? ;1E
.DebugContext dd ? ;20
.pCurrentPriority dd ? ;24
.pvQueue dd ? ;28
end virtual
virtual at $ ;winnt
.unknown1 dd ? ;1C
.processID dd ? ;20
.threadID dd ? ;24
.unknown2 dd ? ;28
end virtual
rd 4 ;reserve 4 double words
.pvTLSArray dd ?;2C
virtual at $
.pProcess dd ? ;30
end virtual
}
Posted on 2003-02-25 13:21:32 by keyoke
Can't see any reason to change original field's names.
Posted on 2003-02-26 05:14:21 by Four-F
havent changed any field names i think used same naming convention as in matt pietrek's paper of teb
Posted on 2003-02-26 06:42:11 by keyoke
The only reason why Matt has named it so is the absence of oficial info.
This stuff is a bit out of date. It's better, IMHO, to follow Microsoft's names.
Posted on 2003-02-26 06:59:24 by Four-F
ok i will change em to ms way of doing it
Posted on 2003-02-28 03:52:58 by keyoke
ok here we go but i'm having trouble with the _EXCEPTION_REGISTRATION_RECORD structure .Exceptionlist is a pointer to this structure but i cant seem to get it rite in my code :(
is .Next pointing to a structure of itsel how would i implement this corretly and PEXCEPTION_ROUTINE wat is its value i looked the masm includes and found it to be just a dword is this correct?



struct _EXCEPTION_REGISTRATION_RECORD
{ ;08
.Next _EXCEPTION_REGISTRATION_RECORD; ;00
.Handler PEXCEPTION_ROUTINE; ;04
}


here is the tib struc with the different names but now it should have have more change.


struc _TIB
{
.ExceptionList dd EXCEPTION_REGISTRATION_RECORD ;00
.StackBase dd ? ;04
.StackLimit dd ? ;08
virtual at $ ;win95
.pvTDB dw ? ;0C
.pvThunkSS dw ? ;0E
.unknown dd ? ;10
end virtual
virtual at $ ;winnt
.SubSystemTib dd ? ;0C
.FiberData dd ? ;10
virtual at .FiberData
.Version dd ? ;10
end virtual
end virtual
rd 2
.ArbitraryUserPointer dd ?;14
.Self dd ?;18
virtual at $ ;win95
.TIBFlags dw ? ;1C
.Win16MutexCount dw ? ;1E
.DebugContext dd ? ;20
.pCurrentPriority dd ? ;24
.pvQueue dd ? ;28
end virtual
virtual at $ ;winnt
.unknown1 dd ? ;1C
.processID dd ? ;20
.threadID dd ? ;24
.unknown2 dd ? ;28
end virtual
rd 4
.pvTLSArray dd ?;2C
virtual at $
.pProcess dd ? ;30
end virtual
}
Posted on 2003-02-28 04:04:45 by keyoke
You need to read Iczelion's and Hutch's tuts 28 thru 30 very carefully and there is another one in between, not sure of name but there are 4 debug tuts.
Posted on 2003-03-04 03:33:25 by mrgone
thanks mrgone ill have a look at them when get back
Posted on 2003-03-04 04:32:57 by keyoke
I know this is a old thread, but i've got some info who could be useful to someone searching. I've been poking around trying to figure out how Structured Exception Handling works and thus found this info;



//==================================================
// File: TIB.H
// Author: Matt Pietrek
// From: Microsoft Systems Journal "Under the Hood", May 1996
//==================================================
#pragma pack(1)

typedef struct _EXCEPTION_REGISTRATION_RECORD
{
struct _EXCEPTION_REGISTRATION_RECORD * pNext;
FARPROC pfnHandler;
} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;

typedef struct _TIB
{
PEXCEPTION_REGISTRATION_RECORD pvExcept; // 00h Head of exception record list
PVOID pvStackUserTop; // 04h Top of user stack
PVOID pvStackUserBase; // 08h Base of user stack

union // 0Ch (NT/Win95 differences)
{
struct // Win95 fields
{
WORD pvTDB; // 0Ch TDB
WORD pvThunkSS; // 0Eh SS selector used for thunking to 16 bits
DWORD unknown1; // 10h
} WIN95;

struct // WinNT fields
{
PVOID SubSystemTib; // 0Ch
ULONG FiberData; // 10h
} WINNT;
} TIB_UNION1;

PVOID pvArbitrary; // 14h Available for application use
struct _tib *ptibSelf; // 18h Linear address of TIB structure

union // 1Ch (NT/Win95 differences)
{
struct // Win95 fields
{
WORD TIBFlags; // 1Ch
WORD Win16MutexCount; // 1Eh
DWORD DebugContext; // 20h
DWORD pCurrentPriority; // 24h
DWORD pvQueue; // 28h Message Queue selector
} WIN95;

struct // WinNT fields
{
DWORD unknown1; // 1Ch
DWORD processID; // 20h
DWORD threadID; // 24h
DWORD unknown2; // 28h
} WINNT;
} TIB_UNION2;

PVOID* pvTLSArray; // 2Ch Thread Local Storage array

union // 30h (NT/Win95 differences)
{
struct // Win95 fields
{
PVOID* pProcess; // 30h Pointer to owning process database
} WIN95;
} TIB_UNION3;

} TIB, *PTIB;
#pragma pack()


There's some more info on the fields in the article here; Under the Hood May 1996
Posted on 2004-02-07 15:19:19 by Cuby