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 必须实现 ...
随机推荐
- 钻石diamaund外语
Whenever I fail as a father or husband... a toy and a diamond always works. I never worry about diet ...
- 移动应用开发中AppID、AppKey、AppSecret
ppID:应用的唯一标识AppKey:公匙(相当于账号)AppSecret:私匙(相当于密码) token:令牌(过期失效) 使用方法 1. 向第三方服务器请求授权时,带上AppKey和AppSecr ...
- Hive Lateral View
一.简介 1.Lateral View 用于和UDTF函数[explode,split]结合来使用. 2.首先通过UDTF函数将数据拆分成多行,再将多行结果组合成一个支持别名的虚拟表. 3.主要解决在 ...
- Linux理论小结
1.Linux是什么 2.Linux的种类 3.Linux的软件安装方法 4.Linux的软卸载方法 5.Linux的目录功能 1.Linux是什么 2.Linux的种类 3.Linux的软件安装方法 ...
- Linux文本处理三剑客之grep及正则表达式详解
Linux文本处理三剑客之grep及正则表达式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux文本处理三剑客概述 grep: 全称:"Global se ...
- centos7最小安装后无法联网解决方法
1 进入目录 cd /etc/sysconfig/network-scripts/ # 编辑网卡的配置文件 # 多网卡会对应多个配置文件,均以ifcfg-enp开头 # 新环境配置可任意选择,建议按一 ...
- Codeforces C. Jzzhu and Cities(dijkstra最短路)
题目描述: Jzzhu and Cities time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- python coding style guide 的快速落地实践——业内python 编码风格就pep8和谷歌可以认作标准
python coding style guide 的快速落地实践 机器和人各有所长,如coding style检查这种可自动化的工作理应交给机器去完成,故发此文帮助你在几分钟内实现coding st ...
- steam游戏存档迁移
之前玩的盗版guacamelee等着打折入正,今天入了,不想重新打了,就把存档从盗版迁移了一下. 盗版的目录是F:\Guacamelee\Profile\ALI213\Saves,该目录下又一个SAV ...
- root用户ssh可以登录,xftp通过sftp不能登录链接CentOS解决办法
xftp显示无法连接到xx.xx.xx(服务器地址) 解决办法: 把/etc/ssh/sshd_config文件中的Subsystem sftp /usr/libexec/openssh/sftp-s ...