avatar
文章
16
标签
8
分类
1
首页
标签
分类
归档
Pemic's Blog
搜索
首页
标签
分类
归档

Pemic's Blog

进程与线程(五)| 线程优先级、进程挂靠与跨进程读写
发表于2026-02-10|Windows 逆向
# 线程优先级 三种情况会导致线程切换: 主动调用 API:KiSwapThread → KiSwapContext → SwapContext CPU 时间片到期:KiDispatchInterrupt → KiQuantumEnd → SwapContext 存在备用线程:KiDispatchInterrupt → SwapContext 其中 KiSwapThread 和 KiQuantumEnd 都通过 KiFindReadyThread 查找下一个要执行的线程。那么 KiFindReadyThread 是根据什么条件选择线程的呢? # 调度链表 在 Windows 32 位系统中,共有 32 个双向链表(调度链表,对应优先级 0~31) 在 Windows 64 位系统中,同样为 32 个双向链表(优先级范围仍为 0~31) 线程在调度链表中的下标即表示其优先级 1dd KiDispatcherReadyListHead L50 # 分析 KiFindReadyThread 查找方式:按优先级从高到低查找:31 → 30 → 29 → … → ...
进程与线程(四)| 线程切换与时钟中断
发表于2026-02-10|Windows 逆向
# 线程切换概述 在 Windows 中,线程切换的核心实现位于 SwapContext 函数。以下将从上到下逐层分析。 # 分析 KiSwapContext KiSwapContext 是线程切换的入口函数,负责保存 / 恢复寄存器并调用 SwapContext 。 1234567891011121314151617181920212223242526272829303132333435.text:0040580E @KiSwapContext@4 proc near.text:0040580E.text:0040580E sub esp, 10h; 保存当前线程的寄存器现场.text:00405811 mov [esp+10h+var_4], ebx.text:00405815 mov [esp+10h+var_8], esi.text:00405819 mov [esp+10h+var_C], edi.text:...
进程与线程(三)| 等待链表、调度链表与线程切换模拟
发表于2026-02-09|Windows 逆向
# 等待链表 等待链表(Wait List) 用于存储正在等待某个资源或事件(如锁、信号量等)的线程队列,当资源可用时,系统会从等待链表中唤醒线程。 等待链表是一个双向链表 它有两个成员 —— Flink (Forward Link,指向下一个节点)和 Blink (Backward Link,指向上一个节点) 当线程调用了 Sleep 或 WaitForSingleObject 等函数时,线程会被挂到这个链表上 dd KiWaitListHead 线程在等待链表和调度链表中的挂载位置是同一个字段: 123456kd> dt _KTHREADntdll!_KTHREAD ... +0x060 WaitListEntry : _LIST_ENTRY // 等待链表 / 调度链表共用此节点 +0x060 SwapListEntry : _SINGLE_LIST_ENTRY ... # 实验:分析等待链表中的线程所属进程 一、 查看等待链表。 dd KiWaitListHead 二、 从链表中取出第一个节点,减去 ...
进程与线程(二)| 线程结构体与 KPCR
发表于2026-02-09|Windows 逆向
# ETHREAD 概述: 每个 Windows 线程在 0 环都有一个对应的 ETHREAD 结构体 该结构体包含了线程的所有重要信息 kd> dt _ETHREAD 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859ntdll!_ETHREAD +0x000 Tcb : _KTHREAD +0x1c0 CreateTime : _LARGE_INTEGER +0x1c0 NestedFaultCount : Pos 0, 2 Bits +0x1c0 ApcNeeded : Pos 2, 1 Bit +0x1c8 ExitTime : _LARGE_INTEGER +0x1c8 LpcReplyChain : _LIST_ENTRY +0x1c8 KeyedWaitChain : _LIS...
进程与线程(一)| 进程结构体
发表于2026-02-09|Windows 逆向
# EPROCESS 概述: 每个 Windows 进程在 0 环都有一个对应的 EPROCESS 结构体 该结构体包含了进程的所有重要信息 kd> dt _EPROCESS 12345678ntdll!_EPROCESS +0x000 Pcb : _KPROCESS +0x06c ProcessLock : _EX_PUSH_LOCK +0x070 CreateTime : _LARGE_INTEGER // 进程创建时间 +0x078 ExitTime : _LARGE_INTEGER // 进程退出时间 +0x080 RundownProtect : _EX_RUNDOWN_REF +0x084 UniqueProcessId : Ptr32 Void // 进程 PID +0x088 ActiveProcessLinks : _LIST_ENTRY // 双向链表(详见下文) ActiveProce...
系统调用(四)| 系统服务表
发表于2026-02-09|Windows 逆向
# 前言 上一篇我们分析了 KiSystemService 和 KiFastCallEntry 如何保存 3 环现场。本篇将分析它们的共同代码部分 —— 如何根据系统调用号找到并调用内核函数。 # SST(System Service Table,系统服务表) 系统服务表共有两张,第一张表后紧接第二张表。 第一张表的函数来自 ntoskrnl.exe (基本系统调用),第二张表的函数来自 win32k.sys (图形 / 窗口相关调用)。 它并不包含内核文件导出的所有函数,而是 3 环最常用的内核函数。 系统服务表指针位于 _KTHREAD + 0xE0 ( ServiceTable 成员)。 123456789typedef struct _SERVICE_DESCRIPTOR_TABLE{ PULONG ServiceTableBase; // 函数地址表指针,每个成员占 4 字节 PULONG ServiceCounterTableBase; // 当前系统服务表被调用的次数 ULONG NumberOfSer...
系统调用(三)| 保存现场
发表于2026-02-09|Windows 逆向
# 前言 上一篇我们了解了 3 环进 0 环的两种方式。本篇将分析进入 0 环后,操作系统如何保存 3 环的寄存器现场。 API 进入 0 环后调用的函数: 中断门: KiSystemService 快速调用: KiFastCallEntry # Trap Frame 结构 无论是通过中断门还是快速调用进入 0 环,进入 0 环前(3 环)的所有寄存器都会存到这个结构体中。 这个结构体本身处于 0 环,由 Windows 操作系统进行维护。 当程序通过中断门从 3 环进入 0 环时,ESP 指向 TrapFrame + 0x64 的位置。 当程序通过快速调用从 3 环进入 0 环时,ESP 指向 TrapFrame + 0x78 的位置。 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647kd> dt _KTRAP_FRAMEntdll!_KTRAP_FRAME // 调试等其他作用 +0x000 DbgEbp ...
系统调用(二)| 3 环进 0 环
发表于2026-02-09|Windows 逆向
# 前言 上一篇我们分析了 ReadProcessMemory 的调用过程,了解到 3 环函数最终通过 0x7FFE0300 地址处的函数进入 0 环。本篇将深入分析进入 0 环的两种方式。 # 0x7FFE0300 的含义 0x7FFE0300 就是 _KUSER_SHARED_DATA 结构体的成员 SystemCall ,它的作用是进入 0 环,而具体进入 0 环的方式由 CPU 决定。 当通过 eax=1 执行 CPUID 指令时,处理器的特征信息被放在 ecx 和 edx 寄存器中,其中 edx 包含了一个 SEP 位(第 11 位),该位指明了当前处理器是否支持 sysenter / sysexit 指令: 支持: ntdll.dll!KiFastSystemCall() 不支持: ntdll.dll!KiIntSystemCall() # 实验:判断 CPU 是否支持快速调用 一、在 OllyDbg 中修改 EAX = 1。 二、将当前汇编指令修改为 CPUID。 三、清空 ECX 与 EDX。 四、执行 CPUID,观察结果。 ...
系统调用(一)| API 调用过程
发表于2026-02-09|Windows 逆向
# 前言 本文是 "系统调用" 系列笔记的第一篇,通过分析 ReadProcessMemory 函数的调用过程,揭示 Windows API 从用户态(3 环)到内核态(0 环)的调用链。 参考资料:Intel 白皮书第二卷、第三卷 # Windows API Application Programming Interface,简称 API 函数。Windows 的 API 主要存放在 C:\WINDOWS\system32 下面的 DLL 文件中。 几个重要的 DLL: DLL 功能 Kernel32.dll 最核心的功能模块,管理内存、进程和线程相关的函数 User32.dll Windows 用户界面相关应用程序接口,如创建窗口和发送消息 GDI32.dll 图形设备接口(Graphical Device Interface),包含画图和显示文本的函数 Ntdll.dll 大多数 API 都会通过这个 DLL 进入内核(0 环) # 实验 1:分析 ReadProcessMemory 调用过程 一、使用 IDA...
保护模式(七)| TLB、中断异常与控制寄存器
发表于2026-02-09|Windows 逆向
# 前言 上一篇我们学习了页表基址和 2-9-9-12 分页。本篇是 "保护模式" 系列的最后一篇,将介绍 TLB、中断与异常、控制寄存器等内容。 # TLB(Translation Lookaside Buffer,快表) # 线性地址解析的开销 当计算机通过一个线性地址访问物理页(如 MOV EAX, [0x12345678] )时,CPU 未必只读了 4 个字节。 10-10-12 分页: 通过线性地址找到 PDE:4 字节 通过 PDE 找到 PTE:4 字节 在物理页中读出 4 字节 共访问了 12 个字节(如果跨页可能更多)。 2-9-9-12 分页: 找到 PDPTE:8 字节 找到 PDE:8 字节 找到 PTE:8 字节 在物理页中读出 4 字节 共访问了 28 个字节(如果跨页可能更多)。 为了提高效率,CPU 内部有一张表来记录线性地址与物理地址的对应关系,效率和寄存器一样快,这就是 TLB。由于效率极高,TLB 的容量不能太大,少则几十条,多则上百条。 思考:一个进程有 4GB 的线性地址空间,但 TLB 最多只能记录上百条记...
12
avatar
Pemic
个人技术博客
文章
16
标签
8
分类
1
Follow Me
公告
分享技术与生活
最新文章
进程与线程(五)| 线程优先级、进程挂靠与跨进程读写2026-02-10
进程与线程(四)| 线程切换与时钟中断2026-02-10
进程与线程(三)| 等待链表、调度链表与线程切换模拟2026-02-09
进程与线程(二)| 线程结构体与 KPCR2026-02-09
进程与线程(一)| 进程结构体2026-02-09
分类
  • Windows 逆向16
标签
进程与线程Windows 内核逆向工程保护模式x86分页TLB系统调用
归档
  • 二月 2026 16
网站信息
文章数目 :
16
本站总字数 :
34.2k
本站访客数 :
本站总浏览量 :
最后更新时间 :
© 2025 - 2026 By Pemic框架 Hexo 8.1.1|主题 Butterfly 5.5.4
浙ICP备2025216280号-1
搜索
数据加载中