0x00前言
本人大一小菜鸡一枚,想把平时玩的东西记录一下,第一次写博客,有不对的地方望各位大牛斧正(轻点喷,轻点喷)。
0x01 三环部分
-
几个重要的 API
Kernel32.dll:最核心的功能模块,比如管理内存、进程和线程相关的函数等.
User32.dll:是 Windows 用户界面相关应用程序接口,如创建窗口和发送消息等.
GDI32.dll:全称是 Graphical Device Interface(图形设备接口),包含用于画图和显示文本的函 数.比如要显示一个程序窗口,就调用了其中的函数来画这个窗口.
Ntdll.dll:大多数 API 都会通过这个 DLL 进入内核(0 环). -
分析 ReadProcessMemory 用 IDA 载入 Kernel32.dll
为 NtReadVirtualMemory 传参(在 ntdll 里) 如果返回值小于 0,调用失败,返回 0; 如果返回值不小于 0,调用成功,返回 1; (其实没干什么).
接下来看看 NtReadVirtualMemory,载入 ntdll
这个 0Bah 是一个系统服务表的编号 这个函数同样没做什么,把编号传到了 eax 里 然后调用 7ffe0300 指向的函数
0x02 三环进 0 环
1._KUSER_SHARED_DATA
-
在 User 层和 Kernel 层分别定义了一个 _KUSER_SHARED_DATA 结构区域,用于 User 层和 Kernel 层共享某些数据 .
-
它们使用固定的地址值映射,_KUSER_SHARED_DATA 结构区域在 User 和 Kernel 层地 址分别为:
User 层地址为:0x7ffe0000
Kernnel 层地址为:0xffdf0000
注意:虽然指向的是同一个物理页,但在 User 层是只读的,在 Kernnel 层是可写的
所以说 NtReadVirtualMemory 里 7ffe0300 地址就是_KUSER_SHARED_DATA+0x300 的 地方用
windbg 查一下
kd> dt _KUSER_SHARED_DATA
0x7FFE0300 的 systemcall 有两种:一种是快速调用,另一种通过中断门
那么问题来了
怎么判断是否支持快速调用?
当通过 eax=1 来执行 cpuid 指令时,处理器的特征信息被放在 ecx 和 edx 寄存器 中,其中 edx 包含了一个 SEP 位(11 位),该位指明了当前处理器知否支持 sysenter/sysexit 指令
如果支持: ntdll.dll!KiFastSystemCall()
如果不支持:ntdll.dll!KiIntSystemCall()
这两个函数都是 ntdll 里的函数 需要用 x32dbg 测试一下 随便托个 exe 进去
1)把 eax 改成 1,edx 和 ecx 改成 0
2)修改汇编:改为 cupid,执行看结果
1010 1111 1111
SEP 位(11)为 1,所以说我的 cpu 支持快速调用, 是 ntdll.dll!KiFastSystemCall()
虽然是快速调用但为了学习还是主要说ntdll.dll!KiIntSystemCall()
(掐会儿腰,可把我闲坏了)
ntdll.dll!KiIntSystemCall(不支持快速调用)
依然在 ntdll 里
其中系统编号存在 eax 里(见上部分) edx 里存的是刚刚传入的参数在哪里
Int 2Eh //通过编号为 2E 的中断门调用
从中断门进 0 环需要查 IDT 来确定 cs 和 eip,还要查内存通过 TSS 来找 ss 和 esp, 所以说相对于快速调用会比较慢
接下来 windbg 找 IDT,确定中断门
Cs 是 0008,偏移是 8040f631,通过 cs 找到的基地址是 0000 0000,所以就是 8040f631
通过地址找到 nt!KiSystemService
*ps:因为当时对应的符号文件没有导入IDA里,所以我接下来就用windbg看了。
*
在分析代码之前需要先了解几个结构体
1. _Ktrap_frame
(这个图我是嫖的(手动滑稽))
简而言之,这个结构体就是保存3环到0环时3环的环境
2. _ETHREAD 结构体
各位看官用windbg看一下吧,简而言之,是储存线程信息的
3. KPCR 结构体
还是,用windbg看一下,简而言之,是储存CPU信息的,
我们需要用到最后一个成员中的 CurrentThread 来获取当前线程的_KTHREAD 结构体。
0x03 0环
正式开始分析 nt!KiSystemService(有点小激动)
Okk,总得来说就是把Ktrap_frame结构体的信息填好,然后将[KTHREAD+0x128]处旧的TRAPFRAME切换为这个新的KTRAPFRAME然后调用内核函数。如果是快速调用最后也会跳到nt!KiFastCallEntry+0x8d(804df781) 这个地址
接下来需要系统服务表的知识
原理如下图所示:(没错,下面这个图我也是嫖的,实在不知道从哪来的了)
0x04 总结
第一次写博客,着实不太会用(是我菜了),虽然写的都是很老的东西,但对与我这样的小白还是想总结总结。