很多的时候,我们需要使用到无模块获取到Kernel32.dll的基址,这时候,我们就需要借助FS还完成:
1)通过FS得到TEB的地址
2)TEB偏移0x30处指向的是PEB指针
3)PEB偏移0x0C处指向PEB_LDR_DATA结构指针
4)PEB_LDR_DATA偏移0x1C处是InInitializationOrderModuleLis(模块初始化链表的头指针)
5)InInitializationOrderModuleLis中按顺序存在着此进程的初始化模块信息,在NT5.x内核中,第一个节点为ntdll.dll的基址,第二个节点为Kernel32.dll的基址; 在NT6.1内核中,第二个节点为KernelBase.dll的基址(包含着Kernel32.dll的大部分实现,其中就有GetProcAddress函数)
代码
#include "stdafx.h"
#include <windows.h>
//#define CONTAINING_RECORD(address, type, field) ((type *)( (PCHAR)(address)-(ULONG_PTR)(&((type *)0)->field)))
typedef struct _UNICODE_STRING {
<span style="white-space:pre"> </span>USHORT Length;
<span style="white-space:pre"> </span>USHORT MaximumLength;
<span style="white-space:pre"> </span>PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _PEB_LDR_DATA
{
<span style="white-space:p