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 必须实现 ...
随机推荐
- IIS7 URL重写如何针对二级域名重写
二级域名与站点主域名是绑在同一目录下,想实现访问二级域名重写至站点下的某个目录. 如: 访问so.abc.cn 实际访问的是站点根目录下的search目录下的文件 相当于so.abc.cn绑定至s ...
- docker下安装mysql数据库
因为用了.net core 所以想学习下使用docker: 项目中刚好要用到mysql数据库,所用用docker来安装一次,我使用的是5.6版本: 1.拉取官方镜像 docker pull mysql ...
- C# vb .net实现负片特效滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的负片特效呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...
- ServiceStack JWT 准备
ServiceStack JWT设置 ServcieStack 自带的验证授权模块使用 sql server存储,所以我们第一步需要配置数据库的一些选项 container.Register<I ...
- 使用Filezilla Server配置FTP服务器
一.下载Filezilla Server 官网网址:https://filezilla-project.org 二.安装Filezilla Server Filezilla Server的安 ...
- 洛谷【P1048 采药】题解
题目链接 分析:典型的01背包问题,设dp[i][j]为空间(也就是题面中的时间)是j的背包在装前i个物品(草药)所得的最大价值,v[i]为第i个物品的重量(采药的时间),w[i]为第i个物品(草药) ...
- Shallow copy and Deep copy
Shallow copy and Deep copy 第一部分: 一.来自wikipidia的解释: Shallow copy One method of copying an object is t ...
- springcloud中gateway的实际应用
之前我一直用的是Zuul网关,用过gateway以后感觉比Zuul功能还是强大很多. Spring Cloud Gateway是基于Spring5.0,Spring Boot2.0和Project R ...
- Windows下MongoDB的下载安装、环境配置
下载MongoDB 1.进入MongoDB官网,Products -> 选择SOFTWARE下的MongoDB Server 2.选择下载最新版 3.选择对应的版本下载 msi安装包形式安装Mo ...
- php环境Unknown column '*' in 'field list'解决方案
在使用pymysql 做网站往数据库插入数据时发现如下错误:pymysql.err.InternalError: (1054, "Unknown column '*' in 'field l ...