获取进程TEB、PEB的方法
Thread Environment Block
NtCurrentTeb
ntdll.dll导出的函数,文档显示要求Win7以上系统:https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-ntcurrentteb
PTEB teb = ::NtCurrentTeb();
从寄存器获取
查看MSVC的STL实现,发现NtCurrentTeb并未直接调用ntdll中导出的函数,而是从寄存器获取的,因为这样更高效,并且可以在Win7以下系统中工作。
#define PcTeb 0x18
...
__inline struct _TEB * NtCurrentTeb( void ) { return (struct _TEB *) (ULONG_PTR) __readfsdword (PcTeb); }
根据前人总结的信息,可以得出
#ifdef _WIN64
PTEB teb = (PTEB)__readgsqword(0x30);
#else
PTEB teb = (PTEB)__readfsdword(0x18);
#endif
Process Environment Block
RtlGetCurrentPeb
这是在ntdll.dll中导出的函数,虽然没有文档化,不过可以直接引用符号。
#include
EXTERN_C PPEB NTAPI RtlGetCurrentPeb(VOID);
#pragma comment(lib, "ntdll.lib");
PPEB peb = ::RtlGetCurrentPeb();
NtQueryInformationProcess
调用 NtQueryInformationProcess 方法,第二个参数传递ProcessBasicInformation。
PROCESS_BASIC_INFORMATION info{ 0 };
NTSTATUS status = NtQueryInformationProcess(handle, ProcessBasicInformation, &info, sizeof(info), &len);
PebBaseAddress指向PEB地址
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
从寄存器获取
32位进程从fs寄存器获取,64位进程从gs寄存器获取。
#ifdef _WIN64
PPEB peb = (PPEB)__readgsqword(0x60);
#else
PPEB peb = (PPEB)__readfsdword(0x30);
#endif
相关阅读
枚举windows进程模块的几种方法—PEB内核结构详解
探索 PEB