Retrieving information from TEB (Thread Environment Block) may be a pain in some cases, specially because the structure seems to varies from OS to OS, but, it can be easy once you know the equates related to it.
So, i built a serie of equates related to TEb and PEB to make easier to access data from it
Programmatically, this can be done like:
[BaseStaticServerData: D$ 0]
call GetBaseStaticServerFromTEB BaseStaticServerData
add eax SYSTEM_STRINGS.BaseNamedObjects.LengthDis ; <---- Points to the start of the structure UNICODE_STRING where the ObjectName Server is stored
mov D@ObjAttrib.ObjectNameDis eax
; Get starting address Pointer of the Structure ReadOnlyStaticServerData
Proc GetBaseStaticServerFromTEB:
Arguments @pOutout
Uses edi
mov edi D@pOutout
mov eax D$fs:TEB.Tib.SelfDis ; retrieve TEB structure for the current process
mov eax D$eax+TEB.PebDis ; pointer to a PEB structure
mov eax D$eax+PEB.ReadOnlyStaticServerDataDis ; retrieve the ReadOnlyStaticServerData (a TEXT_INFO structure)
mov eax D$eax+TEXT_INFO.SystemStringsDis ; pointer to a SYSTEM_STRINGS structure (eah member points to a UNICODE_STRING Structrure)
mov D$edi eax
EndP
Equates are:
[TEB.Tib.ExceptionListDis 0
TEB.Tib.StackBaseDis 4
TEB.Tib.StackLimitDis 8
TEB.Tib.SubSystemTibDis 12
TEB.Tib.FiberDataDis 16
TEB.VersionDis 16
TEB.Tib.ArbitraryUserPointerDis 20
TEB.Tib.SelfDis 24
TEB.EnvironmentPointerDis 28
TEB.ClientId.UniqueProcessDis 32
TEB.ClientId.UniqueThreadDis 36
TEB.ActiveRpcDDis 40
TEB.ThreadLocalStoragePointerDis 44
TEB.PebDis 48
TEB.LastErrorValueDis 52
TEB.CountOfOwnedCriticalSectionsDis 56
TEB.CsrClientThreadDis 60
TEB.Win32ThreadInfoDis 64
TEB.Win32ClientInfoDis 68
TEB.WOW32ReservedDis 192
TEB.CurrentLocaleDis 196
TEB.FpSoftwareStatusRegisterDis 200
TEB.SystemReserved1Dis 204
TEB.Spare1Dis 420
TEB.ExceptionCodeDis 424
TEB.SpareBs1Dis 428
TEB.SystemReserved2Dis 468
TEB.GdiTebBatch.OffsetDis 508
TEB.GdiTebBatch.HDCDis 512
TEB.GdiTebBatch.BufferDis 516
TEB.gdiRgnDis 1756
TEB.gdiPenDis 1760
TEB.gdiBrushDis 1764
TEB.RealClientId.UniqueProcessDis 1768
TEB.RealClientId.UniqueThreadDis 1772
TEB.GdiCachedProcessDDis 1776
TEB.GdiClientPIDDis 1780
TEB.GdiClientTIDDis 1784
TEB.GdiThreadLocaleInfoDis 1788
TEB.UserReservedDis 1792
TEB.glDispachTableDis 1812
TEB.glReserved1Dis 2932
TEB.glReserved2Dis 3036
TEB.glSectionInfoDis 3040
TEB.glSectionDis 3044
TEB.glTableDis 3048
TEB.glCurrentRCDis 3052
TEB.glContextDis 3056
TEB.LastStatusValueDis 3060
TEB.StaticUnicodeString.LengthDis 3064
TEB.StaticUnicodeString.MaximumLengthDis 3066
TEB.StaticUnicodeString.BufferDis 3068
TEB.StaticUnicodeBufferDis 3072
TEB.PADDINGDis 3594
TEB.DeallocationStackDis 3596
TEB.TlsSlotsDis 3600
TEB.TlsLinks.FlinkDis 3856
TEB.TlsLinks.BlinkDis 3860
TEB.VdmDis 3864
TEB.ReservedForNtRpcDis 3868
TEB.DbgSsReservedDis 3872
TEB.HardErrorDisabledDis 3880
TEB.InstrumentationDis 3884
TEB.WinSockDataDis 3948
TEB.GdiBatchCountDis 3952
TEB.Spare2Dis 3956
TEB.Spare3Dis 3960
TEB.Spare4Dis 3964
TEB.ReservedForOleDis 3968
TEB.WaitingOnLoaderLockDis 3972
TEB.Reserved5Dis 3976
TEB.TlsExpansionSlotsDis 3988]
[PEB.InheritedAddressSpaceDis 0
PEB.ReadImageFileExecOptionsDis 1
PEB.BeingDebuggedDis 2
PEB.SpareBoolDis 3
PEB.MutantDis 4
PEB.ImageBaseAddressDis 8
PEB.LdrDataDis 12
PEB.ProcessParametersDis 16
PEB.SubSystemDataDis 20
PEB.ProcessHeapDis 24
PEB.FastPebLockDis 28
PEB.FastPebLockRoutineDis 32
PEB.FastPebUnlockRoutineDis 36
PEB.EnvironmentUpdateCountDis 40
PEB.KernelCallbackTableDis 44
PEB.EventLogSectionDis 48
PEB.EventLogDis 52
PEB.FreeListDis 56
PEB.TlsExpansionCounterDis 60
PEB.TlsBitmapDis 64
PEB.TlsBitmapBitsDis 68
PEB.ReadOnlySharedMemoryBaseDis 76
PEB.ReadOnlySharedMemoryHeapDis 80
PEB.ReadOnlyStaticServerDataDis 84
PEB.AnsiCodePageDataDis 88
PEB.OemCodePageDataDis 92
PEB.UnicodeCaseTableDataDis 96
PEB.NumberOfProcessorsDis 100
PEB.NtGlobalFlagDis 104
PEB.Spare2Dis 108
PEB.CriticalSectionTimeoutDis 112
PEB.HeapSegmentReserveDis 120
PEB.HeapSegmentCommitDis 124
PEB.HeapDeCommitTotalFreeThresholdDis 128
PEB.HeapDeCommitFreeBlockThresholdDis 132
PEB.NumberOfHeapsDis 136
PEB.MaximumNumberOfHeapsDis 140
PEB.ProcessHeapsDis 144
PEB.GdiSharedHandleTableDis 148
PEB.ProcessStarterHelperDis 152
PEB.GdiDCAttributeListDis 156
PEB.LoaderLockDis 160
PEB.OSMajorVersionDis 164
PEB.OSMinorVersionDis 168
PEB.OSBuildNumberDis 172
PEB.OSPlatformIdDis 176
PEB.ImageSubSystemDis 180
PEB.ImageSubSystemMajorVersionDis 184
PEB.ImageSubSystemMinorVersionDis 188
PEB.ImageProcessAffinityMaskDis 192
PEB.GdiDBufferDis 196
PEB.PostProcessInitRoutineDis 332
PEB.TlsExpansionBitmapDis 336
PEB.TlsExpansionBitmapBitsDis 340
PEB.SessionIdDis 468]
[TEXT_INFO.ReservedDis 0
TEXT_INFO.SystemStringsDis 4]
[SYSTEM_STRINGS.SystemRoot.LengthDis 0
SYSTEM_STRINGS.SystemRoot.MaximumLengthDis 2
SYSTEM_STRINGS.SystemRoot.BufferDis 4
SYSTEM_STRINGS.System32Root.LengthDis 8
SYSTEM_STRINGS.System32Root.MaximumLengthDis 10
SYSTEM_STRINGS.System32Root.BufferDis 12
SYSTEM_STRINGS.BaseNamedObjects.LengthDis 16
SYSTEM_STRINGS.BaseNamedObjects.MaximumLengthDis 18
SYSTEM_STRINGS.BaseNamedObjects.BufferDis 20]
; the structure UNICODE_STRING is the ones used to store the ReadOnlyStaticServerData
[UNICODE_STRING:
UNICODE_STRING.Length: W$ 0
UNICODE_STRING.MaximumLength: W$ 0
UNICODE_STRING.Buffer: D$ 0]
Also, you can always use NtQueryInformationThread from access to certain structures inside the TEB
http://sysmagazine.com/posts/187226
Below is a good example of retrieving a module´s handle without GetModuleHandle Api and using only PEB.
http://asbra.net/getmodulehandle-without-winapi-from-peb/
nice - thanks :t
i think the TEB and PEB are structures, though - defined in Winternl.h (or elsewhere)
i learned a little trick, the other day
the initial contents of the EBX register (program startup) is the address of the PEB :biggrin:
typedef struct _TEB {
NT_TIB Tib;
PVOID EnvironmentPointer;
CLIENT_ID Cid;
PVOID ActiveRpcInfo;
PVOID ThreadLocalStoragePointer;
PPEB Peb;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
PVOID CsrClientThread;
PVOID Win32ThreadInfo;
ULONG Win32ClientInfo[0x1F];
PVOID WOW32Reserved;
ULONG CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID SystemReserved1[0x36];
PVOID Spare1;
ULONG ExceptionCode;
ULONG SpareBytes1[0x28];
PVOID SystemReserved2[0xA];
ULONG GdiRgn;
ULONG GdiPen;
ULONG GdiBrush;
CLIENT_ID RealClientId;
PVOID GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
PVOID GdiThreadLocaleInfo;
PVOID UserReserved[5];
PVOID GlDispatchTable[0x118];
ULONG GlReserved1[0x1A];
PVOID GlReserved2;
PVOID GlSectionInfo;
PVOID GlSection;
PVOID GlTable;
PVOID GlCurrentRC;
PVOID GlContext;
NTSTATUS LastStatusValue;
UNICODE_STRING StaticUnicodeString;
WCHAR StaticUnicodeBuffer[0x105];
PVOID DeallocationStack;
PVOID TlsSlots[0x40];
LIST_ENTRY TlsLinks;
PVOID Vdm;
PVOID ReservedForNtRpc;
PVOID DbgSsReserved[0x2];
ULONG HardErrorDisabled;
PVOID Instrumentation[0x10];
PVOID WinSockData;
ULONG GdiBatchCount;
ULONG Spare2;
ULONG Spare3;
ULONG Spare4;
PVOID ReservedForOle;
ULONG WaitingOnLoaderLock;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
} TEB, *PTEB;
NT_TIB is in defined in WinNT.h
typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
PVOID StackBase;
PVOID StackLimit;
PVOID SubSystemTib;
union {
PVOID FiberData;
DWORD Version;
};
PVOID ArbitraryUserPointer;
struct _NT_TIB *Self;
} NT_TIB;
typedef NT_TIB *PNT_TIB;
//
// 32 and 64 bit specific version for wow64 and the debugger
//
typedef struct _NT_TIB32 {
DWORD ExceptionList;
DWORD StackBase;
DWORD StackLimit;
DWORD SubSystemTib;
union {
DWORD FiberData;
DWORD Version;
};
DWORD ArbitraryUserPointer;
DWORD Self;
} NT_TIB32, *PNT_TIB32;
typedef struct _NT_TIB64 {
DWORD64 ExceptionList;
DWORD64 StackBase;
DWORD64 StackLimit;
DWORD64 SubSystemTib;
union {
DWORD64 FiberData;
DWORD Version;
};
DWORD64 ArbitraryUserPointer;
DWORD64 Self;
} NT_TIB64, *PNT_TIB64;
typedef struct _THREAD_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PPEBLOCKROUTINE FastPebLockRoutine;
PPEBLOCKROUTINE FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PPVOID KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PPVOID ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PPVOID *ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, *PPEB;
use the index or search tabs.....
http://undocumented.ntinternals.net/ (http://undocumented.ntinternals.net/)
Hi Dave, Tks :)
Yep. They are only structures. What i´ve done is simply create the equates related to those structures to make easier to retrieve using "mov eax D$Fs:XX" Where "XX" is only the equate (position) of the structure member
In masm, i believe the syntax may be like: mov eax [dword ptr]FS:XX or something similar, i actually don´t remember the proper masm syntax
ABout the usage of ebx, are you talking about some packers that uses CONTENT.EBX to store it ? If it is, then, yes..it is possible to retrieve the PEB from ebx, but i don´t know if it can be done always. Do you know if ebx holds the PEB always after using a Exception routine at the start of a specific function ? (If it does, it can be a good starting point from some updates i´m making in RosAsm´s debugger and disassembler)