Ps回调函数.拦截驱动模块原理+实现.
一丶简介
主要是讲解.内核中如何拦截模块加载的. 需要熟悉.内核回调的设置
PE知识. ShellCode
二丶原理
1.原理
原理是通过回调函数. 回调函数中有 ImageBase. 使用PE解析ImageBase 得到OEP. OEP位置写入 ret等ShellCode
如何判断 是加载DLL 还是加载Sys. 可以看回调的第二个参数.(ProcessId) 如果ProcessId == 0. 则是加载Sys
PS: 在内核中解析PE需要用到 ntImage.h头文件来进行解析.
2.代码实现
#include <ntimage.h>
#include <ntddk.h>
#include <wdm.h>
ULONG_PTR g_LoadPtr = 0;
void WPONx64(KIRQL irql)
{
UINT64 cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
KIRQL WPOFFx64()
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return irql;
}
BOOLEAN Fuck(PVOID pOep)
{
KIRQL kirql;
if (NULL == pOep)
return FALSE;
//写入字节.
UCHAR FuckCode[] = { "\xB8\x22\x00\x00\xC0\xC3" };
kirql = WPOFFx64();
KdBreakPoint();
memcpy(pOep, FuckCode, sizeof(FuckCode) / sizeof(FuckCode[0])); //开头写入拒绝访问错误码让其无法加载即可.
WPONx64(kirql);
return TRUE;
}
//根据ImageBase来获取加载模块的入口点
PVOID GetImageOep(PVOID ImageBase)
{
PVOID pAddressOfEntryPoint = NULL;
PIMAGE_DOS_HEADER pDosHead = NULL;
PIMAGE_NT_HEADERS pNtHead = NULL;
PIMAGE_FILE_HEADER pFileHead = NULL;
PIMAGE_OPTIONAL_HEADER pOptHead = NULL;
//开始解析
if (ImageBase == NULL)
return NULL;
pDosHead = (PIMAGE_DOS_HEADER)ImageBase;
pNtHead = (PIMAGE_NT_HEADERS)(pDosHead->e_lfanew + (char *)ImageBase);
pFileHead = (PIMAGE_FILE_HEADER)&pNtHead->FileHeader;
pOptHead = (PIMAGE_OPTIONAL_HEADER)&pNtHead->OptionalHeader;
//判断是否是PE头
if (pDosHead->e_magic != 0x5A4D && pNtHead->Signature != 0x5045)
return NULL;
pAddressOfEntryPoint = pOptHead->AddressOfEntryPoint + (char *)ImageBase;
return pAddressOfEntryPoint;
}
char * MyWideUnicodeStringToMutilString(PUNICODE_STRING uString)
{
ANSI_STRING asStr;
char *Buffer = NULL; ;
RtlUnicodeStringToAnsiString(&asStr, uString, TRUE);
Buffer = ExAllocatePoolWithTag(NonPagedPool, uString->MaximumLength * sizeof(wchar_t), 0);
if (Buffer == NULL)
return NULL;
RtlCopyMemory(Buffer, asStr.Buffer, asStr.Length);
return Buffer;
}
VOID pSfFilterModule(
_In_opt_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId, // pid into which image is being mapped
_In_ PIMAGE_INFO ImageInfo
)
{
/*
模块拦截思路:
1.通过 PIMAGE_INFO->ImageBase 得到模块的ImageBase
2.解析PE头.
3.可选头的OEP + ImageBase = 程序运行位置
4.在程序开头写入 ret.
5.通过参数一,判断是不是我们想要拦截的模块.然后进行1 2 3 4步
6.如何判断加载驱动模块还是DLL 根据参数2.ProcessId高低位判断即可. == 0加载驱动模块.否则加载DLL
*/
PVOID pDriverOep = NULL;
char *ComPareString = NULL;
if (MmIsAddressValid(FullImageName))
{
if (ProcessId == 0)
{
//代表拦截驱动模块
//判断名字是否是你想要拦截的.
KdBreakPoint();
ComPareString = MyWideUnicodeStringToMutilString(FullImageName);
if (ComPareString == NULL)
return;
if (strstr(ComPareString,"1.sys"))
{
KdBreakPoint();
KdPrint(("你要拦截的驱动模块名字为: %wZ \r\n", FullImageName));
pDriverOep = GetImageOep(ImageInfo->ImageBase);
//判断拦截的名字是否是你想要拦截的
if (pDriverOep != NULL)
{
Fuck(pDriverOep);
}
}
}
//输出调试
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
ULONG iCount = 0;
NTSTATUS ntStatus;
pDriverObj->DriverUnload = DriverUnLoad;
ntStatus = InitDeviceAnSybolicLinkName(pDriverObj);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
ntStatus = InitDisPatchFunction(pDriverObj);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}
PsSetLoadImageNotifyRoutine(pSfFilterModule);
return STATUS_SUCCESS;
}
3.效果
win7 64 sp1 下测试.
Ps回调函数.拦截驱动模块原理+实现.的更多相关文章
- url 上回调函数(JSONP原理)
1.JSONP原理:就是跨域的 js程序(get请求对应url,获取到文本数据,在script标签中,就是按照 js 程序执行,)执行时 调用 当前程序中写好的函数,并且把跨域的数据(即参数),传 ...
- 再谈Delphi关机消息拦截 -- 之控制台程序 SetConsoleCtrlHandler(控制台使用回调函数拦截,比较有意思)
这里补充一下第一篇文章中提到的拦截关机消息 Delphi消息拦截:http://blog.csdn.net/cwpoint/archive/2011/04/05/6302314.aspx 下面我再介绍 ...
- 回调函数及数组中sort()方法实现排序的原理
1.回调函数:把一个方法A当一个参数值传递到另外一个函数B中,在B执行的过程当中我们随时根据需求让A方法执行: 什么是回调 :它是异步编程基本的方法,需要异步处理的时候一般采用后续传递的方式,将后 ...
- Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!
开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...
- 回调函数的原理及PHP实例
背景:在最近的一个开发项目中,用户要先调用服务才能开始进行一系列的查询活动,想了好久,经同事提醒, 用回调函数即可解决该问题.在这里,对PHP下回调函数的原理及实现分别做一下讲解. 1 什么是回调 软 ...
- php回调函数原理和实例
原理 自己调用自己 称之为“递归”,而不是回调 你也知道回调的关键是这个回既然是回,那么就有一个谁是主体的问题,因为回调是往回调用的意思我调用了函数A,而函数A在执行过程中调用了我提供的函数B,这个函 ...
- 《逆向工程核心原理》——TLS回调函数
pe中TLS(thread local storage)中函数的执行时机早于入口函数(entry point), 相关结构: // // Thread Local Storage // typedef ...
- 通过修改i8042prt端口驱动中类驱动Kbdclass的回调函数地址,达到过滤键盘操作的例子
同样也是寒江独钓的例子,但只给了思路,现贴出实现代码 原理是通过改变端口驱动中本该调用类驱动回调函数的地方下手 //替换分发函数 来实现过滤 #include <wdm.h> #inclu ...
- struts2 javaweb 过滤器、监听器 拦截器 原理
转: 过滤器.监听器 拦截器 过滤器 创建一个 Filter 只需两个步骤: (1)创建 Filter 处理类: (2)在 web.xml 文件中配置 Filter . 创建 Filter 必须实现 ...
随机推荐
- 使用poi调整字体格式、添加单元格注释、自动调整列宽
1 创建新的工作铺 import java.io.FileOutputStream; import org.apache.poi.hssf.usermodel.HSSFCell; import org ...
- dump net core lldb 分析
原文https://www.cnblogs.com/calvinK/p/9274239.html centos7 lldb 调试netcore应用的内存泄漏和死循环示例(dump文件调试) 写个dem ...
- feign.FeignException: status 400 reading
feign.FeignException: status 400 reading : 请求方调用报错: 服务方被调用报错: 用fegin给redis设置缓存时报错,刚好 卡到8k这个临界点 ,就一直报 ...
- 最全的 pip 使用指南,50% 你可能没用过
所有的 Python 开发者都清楚,Python 之所以如此受欢迎,能够在众多高级语言中,脱颖而出,除了语法简单,上手容易之外,更多还要归功于 Python 生态的完备,有数以万计的 Python 爱 ...
- aria config
aria2c --conf-path=aria2.conf mine: max-concurrent-downloads=5 continue=true max-overall-download-li ...
- fileinput 配置项大全,从源码中翻出了很多属性,没那么多时间一一验证,特发出来给大家参考参考
fileinput 配置项大全,从源码中翻出了很多属性,没那么多时间一一验证,特发出来给大家参考参考 fileinput 配置项大全 option 属性名 属性类型 描述说明 默认值 language ...
- GitHub Java项目推荐|功能丰富的 Java 工具包|提高开发效率
GitHub Java项目推荐|功能丰富的 Java 工具包|提高开发效率 功能丰富的 Java 工具包.它帮助我们实现了常用的工具方法,从而减少代码的体积,提高开发效率.该项目最初是作者工作项目中的 ...
- 应用在App Store上被拒重新提交审核流程指南
1. 打开地址: https://itunesconnect.apple.com 2. 输入APPID和密码后,再输入绑定手机后的验证码. 3. 查看“”我的APP“”,如果显示拒绝,可能需打开Mac ...
- MySQL删除语句
删除数据(DELETE) 使用前需注意:删除(DELETE),是删除一(条)行数据.假如我们有四条(行)数据,换句话说,你要删除其中一条(行) 名字为“xx”的用户,那么关于他的 i所有数据都会被删除 ...
- option触发及获取当前选中的option值
#标签 #<select id="city" class="select"> #JavaScript #$("#city").c ...