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 必须实现 ...
随机推荐
- 接口的鉴权cookie、session和token
1.HTTP是无状态协议 什么是无状态?就是说这一次的请求和上一次的请求是没有任何关系的,无法共享信息.好处就是速度快. 2.cookie.session的加入 HTTP请求是无状态的,所以解决共享信 ...
- Mybatis中使用association及collection进行自关联示例(含XML版与注解版)
XML版本: 实体类: @Data @ToString @NoArgsConstructor public class Dept { private Integer id; private Strin ...
- PHP防止SQL注入攻击和XSS攻击
代码如下: /** * 防SQL注入和XSS攻击 * @param $arr */ function SafeFilter (&$arr) { $ra=Array('/([\x00-\x08, ...
- vue+element 按钮来回切换
需求很简单,实现很容易,日常记录一下 templace代码: data数据声明: me'thods方法:
- nginx-1.12.0安装
1.配置相关环境: yum install -y gcc glibc gcc-c++ zlib pcre-devel openssl-devel rewrite模块需要pcre库 ssl功能需要ope ...
- css 和常用快捷键
一.css概述: 1.规则:CSS 规则由选择器,以及一条或多条声明两个部分构成. 2.选择器:选择器通常是您需要改变样式的 HTML 元素. 3.声明:声明是您要设置的样式(每条声明由一个属性和一个 ...
- idea上maven打包
首先要实现maven打包,pom需要引入依赖 pom.xml <project> <dependencies> …… </dependencies> <bui ...
- Gtest:源码解析
转自:玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest 一.前言 “深入解析”对我来说的确有些难度,所以我尽量将我学习到和观察到的gtest内 ...
- UML——从类图到C++
简易软件开发流程 实践中,use case and description.class diagram与sequence diagram三者搭配,几乎是UML项目的基本类型,所以在分工或外包的设计文档 ...
- 计算机网络基础之TCP/IP 协议栈
计算机网络基础之TCP/IP 协议栈 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.TCP/IP 协议栈概述 1>.什么是TCP/IP协议栈 Transmission C ...