文章作者:SystEm32
TEB的结构
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 Tib; //0x00
PVOID EnvironmentPointer; //0x1c
CLIENT_ID Cid; //0x20
PVOID ActiveRpcInfo; //0x28
PVOID ThreadLocalStoragePointer; //0x2c
PPEB Peb; //0x30
NT_TIB的结构如下
struct _NT_TIB, 8 elements, 0x1c bytes
+0x000 ExceptionList
+0x004 StackBase
+0x008 StackLimit
+0x00c SubSystemTib
+0x010 FiberData
+0x010 Version
+0x014 ArbitraryUserPointer : (null)
+0x018 Self : struct _NT_TIB, 8 elements, 0x1c bytes
0x18指向NT_TIB自己,所以FS:0x00 与 FS:0x18 指向一致,都指向TEB
TEB的0x30偏移处存放指向PEB的指针,即PEB的基址
PEB的结构如下:
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;
其中头部的几个结构
BOOLEAN InheritedAddressSpace; //0x00
BOOLEAN ReadImageFileExecOptions; //0x01
BOOLEAN BeingDebugged; //0x02
BOOLEAN Spare; //0x03
HANDLE Mutant; //0x04
PVOID ImageBaseAddress; //0x08
PPEB_LDR_DATA LoaderData; //0x0c
其中PPEB_LDR_DATA的结构如下
typedef struct _PEB_LDR_DATA {
ULONG Length; //0x00
BOOLEAN Initialized; //0x04
PVOID SsHandle; //0x08
LIST_ENTRY InLoadOrderModuleList; //0x0c
LIST_ENTRY InMemoryOrderModuleList; //0x14
LIST_ENTRY InInitializationOrderModuleList; //0x2c
} PEB_LDR_DATA, *PPEB_LDR_DATA;
_LDR_MODULE 结构
typedef struct _LDR_MODULE {
LIST_ENTRY InLoadOrderModuleList; //0x00
LIST_ENTRY InMemoryOrderModuleList; //0x08
LIST_ENTRY InInitializationOrderModuleList; //0x10
PVOID BaseAddress; //0x18
PVOID EntryPoint; //0x1c
ULONG SizeOfImage; //0x20 UNICODE_STRING FullDllName; //0x28
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
LDR_MODULE结构 其实是紧接在 PEB_LDR_DATA结构后面的
PEB_LDR_DATA的倒数3个成员,就是LDR_MODULE的头3个成员
所以
FS:0x30 -》PEB
PEB的0x0c偏移处指向 -》PEB_LDR_DATA
PEB_LDR_DATA的0x0c处得到 -》LIST_ENTRY
LIST_ENTRY
{
FLINK //0x00
BLINK //0x04
}
其中的FLINK偏移0x18处得到BaseAddress,0x28处得到FullDllName
FLink本身指向上一个FLink,BLink本生指向下一个Link,形成一个双向循环链表
链表的节点就是LDR_MODULE结构。
下面我给出一段程序获取Kernel32的基址
#include
#include
#include
void main()
{
DWORD Kernel32;
__asm
{
mov eax, fs:0x30
mov eax, [eax + 0x0c]
mov esi, [eax + 0x0c]
lodsd
mov eax, [eax] //如果没有这一句则得到ntdll.dll的基址
mov eax, [eax + 0x18]
add eax,1000h
mov Kernel32,eax
}
printf("The Kernel32 address is %x",Kernel32);
}