目录
我们有进程的概念,也有线程的概念。 而这些其实在操作系统内核中是由记录的。
这里我简单的说下重要字段。 我们可以使用 windbg 加载好符号之后
使用 dt _EPROCESS 来查看这个结构体
这里我之所以讲下字段是因为在每个系统中进程结构体中偏移中记录的成员变量可能会有差异。
首先 EPROCESS的第一个成员是 KPROCESS 所以我们先说下 KPROCESS代表的是啥
请注意这里只说下重要结构,且操作系统内核中的结构是随着系统改变的。所以简单了解下。
我会删除一些不需要的偏移。
成员如下:
nt!_KPROCESS
+0x000 Header : _DISPATCHER_HEADER //此字段如果有值代表我们可以被 waitforsingobject来进行等待(ring3的线程同步函数)
+0x028 DirectoryTableBase : Uint8B //很重要的字段,代表当前进程的页目录表 (也就是CR3,熟悉此字段可以进行内存读写操作)
+0x030 ThreadListHead : _LIST_ENTRY
+0x050 Affinity : _KAFFINITY_EX //此字段代表允许当前进程在那个CPU上跑。按位来判断的。 如: 0000 0001 代表在0核上跑 0000 0010 代表在1核上跑。
+0x1c0 BasePriority : Char //基础的优先级,记录了当前进程的所有线程的基础优先级
+0x1c3 Flags : _KEXECUTE_OPTIONS //标志,一般都是很重要的。
+0x274 KernelTime : Uint4B //统计信息,代表当前进程启动时间
+0x278 UserTime : Uint4B //统计用户的时间
+0x27c ReadyTime : Uint4B //时间信息
其中上面最重要的成员就是页表。 熟悉了此结构可以实现 自定义的 内存读写函数
自己实现 ReadProcessMemory 以及 WriteProcessMemory
第二个就是Affinity 可以使用内核函数设置当前线程在那个CPU上跑。
KeSetSystemAffinityThread 应该是这个函数。 设置之后我们则可以获取每个核心的GDT表并且显示出来。
EPROCESS 记录的信息很多。记录的东西比KPROCESS 还多。
看下结构 在我调试的Windows10 1909上面结构体成员偏移已经突破了 0x800了 所以暂时没在我认知能力中的成员以及不重要的成员都会删除
nt!_EPROCESS
+0x000 Pcb : _KPROCESS //记录了KPROCESS 参考上面
+0x2e8 UniqueProcessId : Ptr64 Void //记录了当前进程的PID
+0x2f0 ActiveProcessLinks : _LIST_ENTRY //重要成员,记录了当前进程的活动链表。
+0x30c Flags : Uint4B //清零可以使我们的进程不被打开。 Ring3层的 OpenProcess就会打开我们失败
+0x310 CreateTime : _LARGE_INTEGER //进程的创建时间
+0x318 ProcessQuotaUsage : [2] Uint8B //物理页的使用信息
+0x328 ProcessQuotaPeak : [2] Uint8B
+0x338 PeakVirtualSize : Uint8B
+0x340 VirtualSize : Uint8B
+0x348 SessionProcessLinks : _LIST_ENTRY //Session链表
+0x358 ExceptionPortData : Ptr64 Void //异常以及调试信息相关成员
+0x358 ExceptionPortValue : Uint8B
+0x358 ExceptionPortState : Pos 0, 3 Bits
+0x360 Token : _EX_FAST_REF //当前进程的Tokenx信息
//我认为的SESSION比较重要的字段
+0x3c0 SectionObject : Ptr64 Void
+0x3c8 SectionBaseAddress : Ptr64 Void
+0x3d0 Cookie : Uint4B
+0x3f8 Peb : Ptr64 _PEB //ring0层也记录的PEB 信息。 PEB信息掌握好了可以进行模块隐藏
+0x400 Session : Ptr64 _MM_SESSION_SPACE // 当前进程Session信息
+0x410 QuotaBlock : Ptr64 _EPROCESS_QUOTA_BLOCK
+0x418 ObjectTable : Ptr64 _HANDLE_TABLE //句柄表,记录了当前进程使用的其它的内核对象的句柄
+0x420 DebugPort : Ptr64 Void //调试端口。 如果清0 可以让我们不被调试(注意是线程一直清零来达到反调试的目的)
+0x448 ImageFilePointer : Ptr64 _FILE_OBJECT //记录的当前进程的 文件对象 可以通过它查询File的信息
+0x450 ImageFileName : [15] UChar //记录了当前进程的名字,但是只有15个可用字节,所以我们可以使用FILE_OBJECT得到名字或者路径
+0x488 ThreadListHead : _LIST_ENTRY //记录了当前进程的所有线程
+0x498 ActiveThreads : Uint4B //记录了当前进程的 活动线程的数量
+0x4e8 CommitChargeLimit : Uint8B //虚拟内存统计信息
+0x4f0 CommitCharge : Uint8B
+0x4f8 CommitChargePeak : Uint8B
+0x658 VadRoot : _RTL_AVL_TREE //VAD树,记录了ring3层未使用的内存,在ring3申请内存的时候都会查询
+0x660 VadHint : Ptr64 Void
+0x668 VadCount : Uint8B
+0x670 VadPhysicalPages : Uint8B
+0x678 VadPhysicalPagesLimit : Uint8B //Vad物理内存界限
+0x6c0 ExitTime : _LARGE_INTEGER //进程的退出时间
比较重要的成员我会列出来 可以实现什么共呢个也进行说明