寻找kernel32.dll的地址

时间:2022-04-01 14:45:13

为了寻找kernel32.dll的地址,可以直接输出,也可以通过TEB,PEB等查找。

 

寻找TEB:

dt _TEB


nt!_TEB
+0x000 NtTib : _NT_TIB
+0x01c EnvironmentPointer : Ptr32 Void
+0x020 ClientId : _CLIENT_ID
+0x028 ActiveRpcHandle : Ptr32 Void
+0x02c ThreadLocalStoragePointer : Ptr32 Void
+0x030 ProcessEnvironmentBlock : Ptr32 _PEB
+0x034 LastErrorValue : Uint4B

0x30处就是PEB

 

dt _PEB
nt!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
+0x002 BeingDebugged : UChar
+0x003 BitField : UChar
+0x003 ImageUsesLargePages : Pos 0, 1 Bit
+0x003 IsProtectedProcess : Pos 1, 1 Bit
+0x003 IsLegacyProcess : Pos 2, 1 Bit
+0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
+0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
+0x003 SpareBits : Pos 5, 3 Bits
+0x004 Mutant : Ptr32 Void
+0x008 ImageBaseAddress : Ptr32 Void
+0x00c Ldr : Ptr32 _PEB_LDR_DATA
+0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS

0x0C处是 LDR

 


dt _PEB_LDR_DATA

nt!_PEB_LDR_DATA
+0x000 Length : Uint4B
+0x004 Initialized : UChar
+0x008 SsHandle : Ptr32 Void
+0x00c InLoadOrderModuleList : _LIST_ENTRY
+0x014 InMemoryOrderModuleList : _LIST_ENTRY
+0x01c InInitializationOrderModuleList : _LIST_ENTRY
+0x024 EntryInProgress : Ptr32 Void
+0x028 ShutdownInProgress : UChar
+0x02c ShutdownThreadId : Ptr32 Void

InMemoryOrderModuleList 是嵌套在一个更大的结构体 _LDR_DATA_TABLE_ENTRY 里面

dt _LDR_DATA_TABLE_ENTRY

nt!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x008 InMemoryOrderLinks : _LIST_ENTRY       //就是InMemoryOrderModuleList
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x018 DllBase : Ptr32 Void

第二参数就是我们要找的而_LIST_ENTRY表示结构体中的单个元素,InMemoryOrderLinks位于结构体首地址偏移8字节处

其Flink和Blink并不指向临近结构的第一个字节,相反它们引用了临近结构的地址。每个结构的地址
正好是第一个成员的地址Flink。
所以为了得到相邻结构的地址,需要从Flink中减去8字节的偏移。

下面是两种得到kernel32.dll地址的方法

VOID Sub_1();
int main()
{

Sub_1();

HMODULE v1
= NULL;
v1
= LoadLibrary(L"kernel32.dll"); //加载DLL
printf("0x%08p\r\n", v1);

return 0;
}

VOID Sub_1()
{
int address = 0;
__asm
{
xor ebx, ebx;
mov ebx, fs:[
0x30];
mov ebx, [ebx
+ 0x0c];
mov ebx, [ebx
+ 0x14];
mov ebx, [ebx];
mov ebx, [ebx];
mov ebx, [ebx
+ 0x10];
mov address, ebx;
}
printf(
"0x%08p\r\n", address);
}

 


我的测试结果是 0x76C00000


在用户模式下,TEB的创建方式总是相同的,与该地址对应的段选择器自动放置在FS段寄存器中,TEB的偏移地址总是0.
TEB的地址可以被表示为 FS:00000000H.