KPROCESS,EPROCESS,ETHREAD,KTHREAD之间的关系图:
可以看出,EPROCESS和ETHREAD都是双向链表组织管理,一个EPROCESS中包含一个KPROCESS,这个KPROCESS中指向一个ETHREAD结构,在ETHREAD中又包含一个KTHREAD结构
二,SSDT
SSDT全称系统服务描述符表,通过ntoskrnl.exe导出。一个函数的调用,在应用层会先在kernel32.dll中调用,在通过ntdll中检查参数,之后通过调用中断进入0环,将调用函数的服务号存放到eax中,之后根据eax的值(索引)在SSDT中找到指定的函数
结构如下:
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase; //表的基地址
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices; //表中服务函数的个数
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
SSDT表最重要的两个成员一个为表的基地址,一个为函数个数
SSDT其实就是一个存放函数指针的数值,既然是函数指针,那寻址查找函数的方式就是:ServiceTableBase+index*4 (32位机器)
在64位上的寻址方式是基地址+索引*16。也可以用左移4位表示= [基地址+index*4]>>4+基地址
Shadow SSDT:它与SSDT类似,只是它包含的事ntoskrnel.exe和win32k.sys服务函数,主要处理user32.dll和GDI32.dll的系统调用
截屏保护,按键保护,搜索窗口保护,防止窗口关闭保护都可以从Shadow SSDT中的函数HOOK而实现
三,TEB(线程环境块)
一个进程的所有的TEB都存放在从0X7FFDE000开始的线性内存中,每4KB为一个完整的TEB
在fs:[0]的地址执行TEB结构,这个结构开头是一个NT_TIB结构
TEB结构:
TEB at fs:7FFDF000
+0x000 NtTib // _NT_TIB
+0x01c EnvironmentPointer // Ptr32 Void
+0x020 ClientId // _CLIENT_ID
+0x028 ActiveRpcHandle // Ptr32 Void
+0x02c ThreadLocalStoragePointer // Ptr32 Void
+0x030 ProcessEnvironmentBlock // Ptr32 _PEB 这里指向 PEB 表,即进程环境块
NT_TIB结构:
typedef struct _NT_TIB //sizeof 1ch
{
00h struct _EXCEPTION_REGISTRATION *ExceptionList; //SEH链入口
04h PVOID StackBase; //堆栈基址
08h PVOID StackLimit; //堆栈大小
0ch PVOID SubSystemTib;
union {
PVOID FiberData;
10h DWORD Version;
};
14h PVOID ArbitraryUserPointer;
18h struct _NT_TIB *Self; //本NT_TIB结构自身的线性地址
}NT_TIB;
如何访问TEB? 可以通过NtCurrentTeb函数和FS段寄存器访问这两种方法访问TEB
FS段寄存器访问:mov eax,dword ptr fs:[0x18]; //指向自身的TEB结构
这里如果是FS:[0]则表示为NT_TIB结构体
四,PEB
PEB在TEB的0x30偏移处查找,获取PEB的方法:
mov eax,dword ptr fs:[0x18]; //查找TEB
mov eax,dword ptr [eax+0x30]; //查找PEB
PEB+0X2地方为BeingDebugged.如果被调试该字段为1,反之为0
PEB结构的字段非常多,这里不一一赘述
总结下PEB,TEB和EPROCESS,ETHREAD关系