发新话题
打印

[转载]通过TEB获取Kernerl32的基址

[转载]通过TEB获取Kernerl32的基址

文章作者: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);
}
人情如冰六月寒,花做一份艳,为谁笑人间? 如果任何人发现我转载的有图像的文章中图像失效或者文章有问题,请及时短消息通知我。先谢谢。::)) coup de foudre

TOP

发新话题