Windows进程笔记

Windows进程笔记
Windows体系结构: 

Windows内核结构:



Windows关键组件:
hal.dll: 处于内核中,硬件抽象层, 隔离各种硬件平台
ntoskrnl.exe: 操作系统内核, 下层是微内核(提供线程调度,中断异常等), 上层是执行体(在微内核的基础上实现基本的对象管理和功能组件的封装)
win32k.sys: Windows子系统内核,提供窗口管理和图形设备输出, 上层的GDI/User32在内核的实现。
User32/GDI32/Kenel32: Windows子系统应用层API接口
Windows进程创建过程: 



下面介绍Windows进程中比较关键的几个数据结构:  EPROCESS, KPROCESS, PEB, CSR_PROCESS, W32PROCESS。



上面我们可以看到KPROCESS(PCB)是EPROCESS的一部分, EPROCESS存在于内核上层的执行体中, KROCESS(PCB)存在于内核下层的微内核中, 各施其职。
每个进程都在内核中都有一个EPROCESS, 所有进程共享同一个内核空间, 内核通过一个链表把所有的进程内核块(EPROCESS)串连起来。
EPROCESS包含了很多重要的进程信息: PCB, 进程ID, 进程token, 进程句柄表, 进程环境块(PEB), Win32进程块( W32PROCESS )。



上面的是PEB的结构图, PEB即进程环境块,存在于用户空间(非内核), 所以我们应用层可以直接访问(先通过FS寄存器访问TEB, 在通过TEB成员访问PEB), PEB也包含了很多有用的信息: 模块列表, 进程参数信息, 线程本地存储(TLS), 堆信息, 进程的GDI table等

我们每个Windows进程在创建和退出的时候都要通知Windows子系统, 在应用层csrss.exe负责管理所有的windows进程, 除了少数几个系统进程(sms.exe), 其他所有进程在csrss.exe中都有自己的一份CSR_PROCESS数据。



每个窗口进程在Windows子系统内核(win32k.sys)中都有一个W32PROCESS数据结构, 这个结构包含很多窗口和GDI相关的数据结构。
下面再介绍下线程相关的数据结构: ETHREAD, KTHREAD, TEB, CSR_THREAD, W32THREAD.

ETHREAD和KTHREAD分别在内核的执行体层和微内核层。


TEB(线程环境块)存在于用户层, 我们可以直接通过FS寄存器直接访问。


CSR_THREAD存在于csrss.exe进程中, 每个Windows进程创建线程后都会在这里登记。


W32THREAD, 存在于win32k.sys内核中, 每个UI线程在这里都有对应的结构。

我们可以看到Windows的整个系统各组件相互独立和协助的过程, 他们之间各个关键的数据结构又可以直接通过指针相互访问,有些存在于后台内核(ntoskrnl.exe), 有些存在于界面内核(win32k.sys), 有些又存在于每个进程的用户空间。

这样我们也明白了为什么内核对象(kernel object)句柄是每个进程独立, 但是内核对象本身又是各个进程都可以访问的?
因为内核对象句柄表存在于EPROCESS, 是每个进程都独立持有的, 但是内核对象本身又存在于内核, 是每个进程都可以通过指针直接访问的(需要open object)。

为什么GDI对象是每个进程独有的, 其他进程没法访问? 
因为GDI对象表存在于PEB中, 每个进程都有自己的一份, 其他进程没法访问。

为什么User object只要得到句柄,就可以直接夸进程访问?
User object(如window, menu, hook)明明在内核中,为什么叫用户对象, 因为在NT4.0之前他们是被放在csrss.exe中的,但是后来因为跨进程性能太低,微软把他们移到了内核( win32k.sys )中, 每个session共享同一用户对象列表, 所以它们以同样的句柄值, 可以跨进程直接访问。 

TLS(线程本地存储)又是怎么实现的? 
在每个进程的用户空间的PEB和TEB中分配存储空间。

怎么实现进程隐藏? 
我们既可以直接通过Hook API实现, 也可以通过直接修改进程列表实现, 我们看到CSR_PROCESS, W32PROCESS, EPROCESS 其实都是list, 我们只要修改这些列表,尤其是EPROCESS列表, 就可以实现彻底的进程隐藏。

SetWindowsHookEx是怎么实现的?
Windows子系统内核(Win32k.sys)在对消息进行处理前对用户态设置的回调函数进行调用。

你可能感兴趣的:(Windows进程笔记)