Windows内核实验004 API调用
文章目录
- 完善代码
- 内核API调用
- 修复一个潜在问题
- 复现问题
- 完整代码
前面几次实验我们已经完成了一个三环的程序调用零环API的必要条件。
- 提升到零环权限
- 使fs指向KPCR
完善代码
这次我们去掉之前的死循环代码,并且将函数地址写入到IDT表项,在虚拟机中运行一下程序,看看会有什么结果。
这里他抛出了一个内存访问异常。原因在于我们修改了fs寄存器之后,在iretd指令返回三环的时候,系统不会自动帮我们将FS寄存器还原。
所以我们在返回三环之前还需要将fs还原回去。代码如下:
__asm{push 0x30;pop fs;sti;push 0x3B;pop fs;iretd;}
再次运行我们的程序,
此时程序完全正常运行。
内核API调用
接下来我们在自己的代码中调用一个内核的API函数ExAllocatePool来分配一块内存。
首先在PC Hunter中将ntkrnlpa.exe拷贝出来,然后用IDA分析,接着设置基址和驱动模块的基地址一致。
在IDA中找到ExAllocatePool这个函数,并且记录下函数地址。
然后按Y键可以复制出函数原型,然后定义函数指针,并且将函数地址赋值给函数指针变量
typedef DWORD (__stdcall *EX_ALLOCATE)(DWORD PoolType, DWORD NumberOfBytes);
EX_ALLOCATE ExAllocatePool= (EX_ALLOCATE)0x83E51976;
接着编写调用代码如下:
void __declspec(naked) IdtEntry()
{__asm{push 0x30;pop fs;sti;}g_pool=ExAllocatePool(0, 4096);__asm{push 0x3B;pop fs;iretd;}
}
运行程序
看到这里将我们申请的内存首地址打印出来了,而且是一个内核的地址,符合我们的预期
然后我们可以尝试调用一下DbgPrint,同样的方法找到函数地址和原型进行调用
typedef DWORD ( __cdecl *DBGPRINT)(char* Format, ...);
DBGPRINT MyDbgPrint=(DBGPRINT)0x83E5541F;
char str[] = "Hello GuiShou!";void __declspec(naked) IdtEntry()
{__asm{push 0x30;pop fs;sti;}//g_pool=ExAllocatePool(0, 4096);MyDbgPrint(str);__asm{push 0x3B;pop fs;iretd;}
}
运行程序以后
在windbg窗口打印出了我们设置好的字符串,说明API调用成功
修复一个潜在问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bD6wu6Cl-1573908064431)(assets/1573905826474.png)]
仔细观察我们写的这几句还原FS段选择子返回三环的代码,实际上是有问题的。
在pop fs这句代码执行完成之后,iretd执行之前;依然是开启中断的状态,那么意味着这两行汇编指令之间CPU有可能收到时钟中断,造成线程切换。
而线程切换需要用的FS寄存器的值,然而FS这个时候是一个三环的段选择子,而我们现在却处在一个零环的环境下,FS需要指向KPCR,但是却没有指向那个位置。
就是说如果在指向这两句代码之间发生了线程切换,就会发生蓝屏。尽管产生这个问题的几率很小,但是依然不能忽视。
复现问题
接下来我们稍微修改一下代码,就能复现这个问题:
void go()
{while(1)__asm int 0x20;
}
我们在int 0x20指令加上一条死循环。当CPU产生int 20异常时,会进入到我们设置好的IdtEntry函数提权到零环,然后IdtEntry函数会重新返回到三环。接着由于int 0x20这条指令是在死循环里面。所以这个程序就会一直在三环和零环之前往返。这就会大大增加在push 0x2B;pop fs这两句代码之间发生线程切换的几率。
运行程序,在不连接调试器的情况下会直接蓝屏,如果连接上调试器则虚拟机会出现卡死现象。
解决的方法很简单,就是让CPU在执行这两句代码时不接收硬件中断
在恢复FS寄存器之前关闭中断,即可解决问题,事实上KiFastCallEntry也是这么做的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CHN5izUD-1573908064445)(assets/1573907354519.png)]
再次运行程序,此时依然是死循环,但是因为已经关闭了中断,所以循环往返三环和零环都是安全的,不会发生蓝屏和卡死的现象。
完整代码
最后附上完整的实验代码
#include "pch.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>typedef DWORD (__stdcall *EX_ALLOCATE)(DWORD PoolType, DWORD NumberOfBytes);
EX_ALLOCATE ExAllocatePool= (EX_ALLOCATE)0x83E51976;
DWORD g_pool;typedef DWORD ( __cdecl *DBGPRINT)(char* Format, ...);
DBGPRINT MyDbgPrint=(DBGPRINT)0x83E5541F;
char str[] = "Hello GuiShou!";void __declspec(naked) IdtEntry()
{__asm{push 0x30;pop fs;sti;}//g_pool=ExAllocatePool(0, 4096);//MyDbgPrint(str);__asm cli;__asm{push 0x3B;pop fs;iretd;}
} void go()
{while(1)__asm int 0x20;
}//eq 80b95500 0040ee00`00081040
int main()
{if ((DWORD)IdtEntry != 0x401040){printf("wrong addr:%p", IdtEntry);exit(-1);}go();//printf("%p\n", g_pool);system("pause");
}
Windows内核实验004 API调用相关推荐
- Windows内核--Rtl字符串API “不同IRQL“(3.2)
本文将从最简单的rtl例程函数讲解不同IRQL的真正原因,其他IRQL类似. RtlCopyUnicodeString和RtlEqualUnicodeString看起来同属于rtl支持字符串例程,实际 ...
- Windows内核实验001 中断提权
文章目录 实验环境 内核提权 IDT的基本知识 什么是中断 什么是IDT表 在PC Hunter中查看IDT表 中断提权的基本原理 写一个三环的小程序 修改IDT表 提权测试 本篇文章基于周壑老师的讲 ...
- Windows内核实验003 再次回到中断
文章目录 两个实验 死循环 开启中断后的死循环 KiFastCallEntry 调用零环API的两个条件 分析KiFastCallEntry 什么是KPCR 完善代码 完整代码 之前的实验我们已经实现 ...
- Windows内核实验005 Inline Hook
文章目录 准备工作 寻找Inline Hook的返回地址 编写代码 动态变化的返回地址 JmpTargetAddr Inline Hook基本框架 示例代码 实战HOOK KiTrap01 无需计算偏 ...
- Windows内核实验002 中断现场
文章目录 如何获取中断现场环境 中段现场环境 观察中断现场堆栈环境 观察中断现场的寄存器环境 段选择子 段寄存器结构 变化的段寄存器的具体含义 遗留问题:SS段寄存器和栈顶指针来自于哪? 什么是TSS ...
- Windows 内核之双机调试与windbg命令大全
在今后会有相当的实验环节,对于windows内核实验,调试环境是必不可少的,本章讲解双机调试的环境搭建与常见的WINDBG指令. 准备材料: VMware workstation : [https:/ ...
- Windows内核API HOOK 之 Inline Hook
来源:CSDN 作者:daiwen 名字起得好,Inline hook,乍一听,似乎很高深.此处的Inline,我以为,意指将汇编代码直接写入内核API的内存区域.Inline Hook不像用户态 ...
- Windows恶意软件API调用特征分析
本文讲的是Windows恶意软件API调用特征分析, 1.背景 目标: 1)找到病毒调用概率高的API 2)找到病毒调用概率不高,但是当调用频次高的时候,是病毒概率高的API. 通常对病毒使用API的 ...
- Tensorflow C++ API调用Keras模型实现RGB图像语义分割
我的实验是基于PSPNet模型实现二维图像的语义分割,下面的代码直接从得到的h5文件开始往下做... 也不知道是自己的检索能力出现了问题还是咋回事,搜遍全网都没有可以直接拿来用的语义分割代码,东拼西凑 ...
最新文章
- HDU 5115 Dire Wolf 区间dp
- java蛮力法背包问题_[算法课]五种蛮力法解决01背包问题
- 使用Spring-hadoop小结
- html代码type,HTML中type是什么意思
- (王道408考研操作系统)第一章计算机系统概述-第一节3:操作系统的运行机制与体系结构
- 分布式训练PyTorch 源码解读
- JS 继承各种方法的优劣比较 ----JS 学习笔记(五)
- Python数据结构与算法(3.1)——栈
- html全屏代码怎么写,JS实现全屏的四种写法
- 连表查询 mysql实例_mysql中各种常见join连表查询实例总结
- 如何优化微信小程序排名?
- 机电一体化综合实训考核设备
- 熊猫头唱unravel——如何使图片人物表情动起来
- Python uniform() 函数
- PaddleClas预训练模型ResNet50_vd_ssld精度突破84%
- 李开复给大学生的第四封信---大学四年应是这样度过
- 剑网3 插件 取得服务器信息,剑网3服务器监控插件
- 虚拟服务器建网站苹果cms,苹果CMS系统建站安装步骤
- 第一章 程序设计与C语言
- 2021年广东省安全员C证第三批(专职安全生产管理人员)复审考试及广东省安全员C证第三批(专职安全生产管理人员)模拟考试
热门文章
- log4j.properties
- Appium录制脚本520-2
- JavaScript---事件详解
- 使用visualvm远程监控LINUX服务器JVM
- jQuery $.ajax传递数组的traditional参数传递必须true 对象的序列化
- POJ 1577 Falling Leaves (子母二叉树,给出叶子节点的删除序列,求前序遍历)
- C#---HTML 转文本及HTML内容提取
- Cordiality ERP MVC 3 测试作品
- C++成员函数在内存中的存储方式
- VC里的集合类、链表类、映射类