APC 篇——初识 APC
写在前面
此系列是本人一个字一个字码出来的,包括示例和实验截图。由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我。
你如果是从中间插过来看的,请仔细阅读 羽夏看Win系统内核——简述 ,方便学习本教程。
看此教程之前,问几个问题,基础知识储备好了吗?保护模式篇学会了吗?练习做完了吗?没有的话就不要继续了。
华丽的分割线
APC 结构
上一篇我们简单介绍了APC
的概念。有些人可能对为什么线程不能被“杀掉”、“挂起”和“恢复”还是有些疑问,我们举个极端的例子:如果不调用API,屏蔽中断,并保证代码不出现异常,线程将永久占用CPU,何谈控制呢?所以说线程如果想“死”,一定是自己执行代码把自己杀死,不存在“他杀”这种情况。我们可以画个简单的示意图:
下面我们来看看存储APC
的结构体:
kd> dt _KAPC
ntdll!_KAPC
+0x000 Type : Int2B
+0x002 Size : Int2B
+0x004 Spare0 : Uint4B
+0x008 Thread : Ptr32 _KTHREAD
+0x00c ApcListEntry : _LIST_ENTRY
+0x014 KernelRoutine : Ptr32 void
+0x018 RundownRoutine : Ptr32 void
+0x01c NormalRoutine : Ptr32 void
+0x020 NormalContext : Ptr32 Void
+0x024 SystemArgument1 : Ptr32 Void
+0x028 SystemArgument2 : Ptr32 Void
+0x02c ApcStateIndex : Char
+0x02d ApcMode : Char
+0x02e Inserted : UChar
存在于KTHREAD
结构体的0x34
偏移的位置有一个ApcState
,如下所示:
kd> dt _KTHREAD
nt!_KTHREAD
...
+0x034 ApcState : _KAPC_STATE
...
我们看到这个存着一个结构体,如下所示:
kd> dt _KAPC_STATE
ntdll!_KAPC_STATE
+0x000 ApcListHead : [2] _LIST_ENTRY
+0x010 Process : Ptr32 _KPROCESS
+0x014 KernelApcInProgress : UChar
+0x015 KernelApcPending : UChar
+0x016 UserApcPending : UChar
ApcListHead
第一个成员ApcListHead
是个双向链表的数组,一共有两个成员,所谓的APC
就是插入到里面的,给个示意图如下:
ApcListHead
一个成员存储着用户APC
,用户APC
的函数地址位于用户空间,在用户空间执行;另一个成员存储着内核APC
,内核APC
函数地址位于内核空间,在内核空间执行。
Process
线程线程所属或者所挂靠的进程,这个在逆向线程切换的时候我们就用过。具体细节都在进程线程篇的总结与提升讲过,就不再赘述了。
KernelApcInProgress
指示内核APC
是否正在执行。
KernelApcPending
指示是否有正在等待执行的内核APC
。
UserApcPending
指示是否有正在等待执行的用户APC
。
小结
上面的介绍仅仅是对APC
的初步讲解,里面所有的详细细节将在后面的教程讲解。后面会详细介绍KAPC
这个结构体,并研究APC
是谁插入的、插入到哪里、谁执行APC
和什么时候执行APC
。本篇是对后面学习的铺垫。
本节练习
本节的答案将会在下一节进行讲解,务必把本节练习做完后看下一个讲解内容。不要偷懒,实验是学习本教程的捷径。
俗话说得好,光说不练假把式,如下是本节相关的练习。如果练习没做好,就不要看下一节教程了,越到后面,不做练习的话容易夹生了,开始还明白,后来就真的一点都不明白了。本节练习不多,请保质保量的完成。
1️⃣ 使用现成提供的API
,自己编写代码向某个线程插入一个用户APC
。
2️⃣ 分析TerminateThread
和SuspendThread
是如何实现的(从3环开始分析)。(要求:只需逆向分析到别的进程是如何控制目标进程行为,其他细节暂时不需分析,本题参考将会在正文给出。)
下一篇
最新文章
- CSS3与页面布局学习总结(三)——BFC、定位、浮动、7种垂直居中方法
- Orchard中codegen相关命令
- Web Api中的get传值和post传值
- Entity Framework6 with Oracle
- c# 调用 CRFs应用程序
- gulpfile的结构
- mssql定时执行作业。
- 谈论multistage text input(中国输入法)下一个UITextView内容长度的限制
- apk当安装程序将文件复制到手机自带的指定文件夹
- php 后台权限例子 (mysql 数据表)
- python利用selenium和safari浏览器驱动实现新浪微博自动点赞 Demo
- AJAX结合PHP整理复习
- 『BUG』Android Studio 64位 始终提示 JVM 启动不了,JDK配置失败,error code -1
- 一秒钟带你走进P图世界-----(python)PIL库的使用
- PAT Basic 1032
- date.getTime()
- 【arc102E】Stop. Otherwise...
- 利用CSS 修改input=radio的默认样式(改成选择框)
- dataTables.js 响应式/package-lock.json 作用/eclipse 目录和工作区建立连接/navcat 导出数据库/vscode 快速进入方法
- erl_0015 《硝烟中的erlang》 读书笔记002 “为过载做计划”
热门文章
- Browser Events 常用浏览器事件
- JavaScript交互式网页设计 • 【第3章 JavaScript浏览器对象模型】
- Pytest_配置文件-pytest.ini(4)
- 初识python:time 模版
- win10 防火墙配置 允许局域网其他设备访问本地工程
- spring security +MySQL + BCryptPasswordEncoder 单向加密验证 + 权限拦截 --- 心得
- hyperf 如何对AMQP消息进行手动消费?
- Jekyll + NexT + GitHub Pages 主题深度优化
- List转换Map的三种方式
- 在字节,A/B 实验是这么做的!