Inline Hook IofCallDriver 截获所有IRP

Hook与IoCallDriver与IofCallDriver 用途之一:从内核层保护文件不被删除 IoCallDriver:一个内核例程,过滤所有的系统请求 NTSTATUS IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ); IofCallDriver:在IoCallDriver中调用的一个例程,几乎所有的内核驱动都调用了IofCallDr 阅读详情
前段时间搞了一些Inline HOOK API的demo,例如对NtQueryDirectoryFile Inline HOOK 进行文件的隐藏,(恰好NtQueryDirectoryFile 在SSDT有导出,也可以采用改SSDT来实现HOOK.,只不过Inline HOOK 隐蔽性好点).而NtQueryDirectoryFile是调用IofCallDriver的(我猜的),那么HOOK IofCallDriver过滤掉关于MajorFunction == IRP_MJ_QUERY_INFORMATION的IO包就应该能隐藏文件的(我猜的,到底是不是这个MajorFunction咧,不知道),一开始就说明了我是个菜鸟,所以怎么过滤掉特定的IO包没写出来,只写了HOOK IofCallDriver的方法.流氓作者们有本事你就A,能A是你们的本事,反正我不怕流氓.
因为在SSDT里面是不存在这个函数的,那么就要Inline HOOK IofCallDriver, 我上网找了好久都没有现成的代码(或许是我愚笨找不到),So自己动手.
这里说明一下IoCallDriver不是函数,是一个宏指向IofCallDriver的.恰好IofCallDriver已经导出,我们不用MmGetSystemRoutineAddress来去IofCallDriver的地址了.
要用WinDbg来看下IofCallDriver的入口是什么东西:
由于微软对单核和多核的CPU编写了不同的内核, ntoskrnl.exe用于单核CPU的机器,而ntkrnlpa.exe则为多核,由于我的VPC是虚拟出单核的,所以本文主要围绕ntoskrnl.exe的IofCallDriver来写.(如果现实中的机器有两台就好了,可以调试ntkrnlpa.exe的IofCallDriver.)
    
The beginning of the IofCallDriver function
     ---------------------------------------------------------------------------------------
     nt!IoCallDriver: if ntoskrnl.exe
     804e47c5 ff2500395580    jmp     dword ptr [nt!KeTickCount+0x1480 (80553900)]<-Detour here
     804e47cb 90              nop
     804e47cc 90              nop
     804e47cd 90              nop
     804e47ce 90              nop
     804e47cf 90              nop
     804e47d0 fe4a23          dec     byte ptr [edx+23h]     I try to detour here yet,and work.
     804e47d3 8a4223          mov     al,byte ptr [edx+23h] But I think is not well.
     804e47d6 84c0            test    al,al
     804e47d8 0f8e40840300    jle     nt!IoSetFileOrigin+0x3ce2 (8051cc1e)
     804e47de 8b4260          mov     eax,dword ptr [edx+60h]
     804e47e1 83e824          sub     eax,24h
     804e47e4 56              push    esi
     804e47e5 894260          mov     dword ptr [edx+60h],eax
     804e47e8 894814          mov     dword ptr [eax+14h],ecx
     804e47eb 0fb600          movzx   eax,byte ptr [eax]
     804e47ee 8b7108          mov     esi,dword ptr [ecx+8]
     804e47f1 52              push    edx
     804e47f2 51              push    ecx
     804e47f3 ff548638        call    dword ptr [esi+eax*4+38h]
     ---------------------------------------------------------------------------------------
     nt!IofCallDriver: if ntkrnlpa.exe
     804ef09c ff2580475580    jmp     dword ptr [nt!KeTickCount+0x1780 (80554780)]<-Detour here
     804ef0a2 cc             int     3
     804ef0a3 cc              int     3
     804ef0a4 cc              int     3
     804ef0a5 cc              int     3
     804ef0a6 cc              int     3
     804ef0a7 cc              int     3
 
这里要用WinDbg来跟踪IofCallDriver的走向,我也是刚刚学会这么做,不会的朋友可以参考 “使用VPC进行Windows内核调试”这篇文章,在这里
804e47c5 ff2500395580    jmp     dword ptr [nt!KeTickCount+0x1480 (80553900)]
设置断点,并单步跟进,这时发现运行流程是这样的:
V-- 804e47c5 ff2500395580    jmp     dword ptr [nt!KeTickCount+0x1480 (80553900)]
|    804e47cb 90              nop
|    804e47cc 90              nop
|    804e47cd 90              nop
|    804e47ce 90              nop
|    804e47cf 90              nop
--> 804e47d0 fe4a23          dec     byte ptr [edx+23h]
     804e47d3 8a4223          mov     al,byte ptr [edx+23h]
     804e47d6 84c0            test    al,al
     804e47d8 0f8e40840300    jle     nt!IoSetFileOrigin+0x3ce2 (8051cc1e)
     804e47de 8b4260          mov     eax,dword ptr [edx+60h]
我尝试过两种做法都可行,这里假设0xFFFFFFFF是自己函数的地址(最后给出的代码将会实现第二种做法):
l          804e47d0 fe4a23          dec     byte ptr [edx+23h]
     804e47d3 8a4223          mov     al,byte ptr [edx+23h]
     804e47d6 84c0            test    al,al
     改成: 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x90 刚好8个字节
l          804e47c5 ff2500395580    jmp     dword ptr [nt!KeTickCount+0x1480 (80553900)]
804e47cb 90              nop
改成:0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x00 刚好7个字节
然后在自己的函数中回跳到 804e47d7 或 804e47cc :
_emit 0xEA
_emit 0xd7 or cc
_emit 0x47
_emit 0x4e
_emit 0x80
_emit 0x80
_emit 0x00
好,至此思路和原理已经有了,下面是实现Inline Hook IofCallDriver的代码(实现上面第二种方法)
////////////inline_hook_IofCallDriver.c///////////////
#include <ntddk.h>
 
#define SystemModuleInformation 11
 
typedef struct _SYSTEM_MODULE_INFORMATION {//Information Class 11
     ULONG    Reserved[2];
     PVOID    Base;
     ULONG    Size;
     ULONG    Flags;
     USHORT   Index;
     USHORT   Unknown;
     USHORT   LoadCount;
     USHORT   ModuleNameOffset;
     CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;
 
typedef struct _MODULES{
     ULONG                            dwNumberOfModules;
     SYSTEM_MODULE_INFORMATION   smi;
} MODULES, *PMODULES;
 
NTSYSAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
     IN ULONG SysInfoClass,
     IN OUT PVOID SystemInformation,
     IN ULONG SystemInformationLength,
     OUT PULONG RetLen
     );
 
ULONG nCountCPU;
PDEVICE_OBJECT _DeviceObject;
PIRP _Irp;
PIO_STACK_LOCATION _Iosl;
ANSI_STRING Ansi;
 
// assembles to jmp far 0008:FFFFFFFF where FFFFFFFF is address of
// our detour function, plus one NOP to align up the patch
char DetourCode[] = { 0xEA, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x00 };
char BackupCode[] = { 0xFF, 0x25, 0x00, 0x39, 0x55, 0x80, 0x90 };
 
__declspec(naked) NTSTATUS __fastcall
Detour_IofCallDriver(IN PDEVICE_OBJECT DeviceObject,
                        IN OUT PIRP Irp)
{
     __asm
     {
         pushad
         pushfd
     }
 
     __asm
     {
         push ecx
         pop dword ptr _DeviceObject
         push edx
         pop dword ptr _Irp
     }
 
     _Iosl = IoGetNextIrpStackLocation(_Irp);
     RtlUnicodeStringToAnsiString(&Ansi,&_DeviceObject->DriverObject->DriverName,TRUE);
     DbgPrint("Irp: 0x%02X - Driver: %s/n", _Iosl->MajorFunction, Ansi.Buffer);
     RtlFreeAnsiString(&Ansi);
 
     __asm
     {
         popfd
         popad
     }
 
     __asm
     {
         cmp nCountCPU, 2
         jae MoreCPU
         // jmp FAR 0x08:FFFFFFFF
         _emit 0xEA
         _emit 0xFF
         _emit 0xFF
         _emit 0xFF
         _emit 0xFF
         _emit 0x08
         _emit 0x00
MoreCPU:
         // 由于不会调试,所以ntkrnlpa.exe的IofCallDriver的hook就放在这里先啦
         _emit 0xEA
         _emit 0xFF
         _emit 0xFF
         _emit 0xFF
         _emit 0xFF
         _emit 0x08
         _emit 0x00
     }
}
 
VOID InterruptEnable()
{
     __asm
     {
         MOV EAX, CR0 //move CR0 register into EAX
         OR EAX, 10000H     //enable WP bit
         MOV CR0, EAX //write register back
         STI                //enable interrupt
     }
}
 
VOID InterruptDisable()
{
     __asm
     {
         CLI                    //dissable interrupt
         MOV EAX, CR0       //move CR0 register into EAX
         AND EAX, NOT 10000H    //disable WP bit
         MOV CR0, EAX       //write register back
     }
}
 
NTSTATUS DetourFunctionIofCallDriver()
{
     int i = 0;
     MODULES pModules;
     //Get kernel filename,ntoskrnl.exe if single CPU,else ntkrnlpa.exe
     NtQuerySystemInformation(SystemModuleInformation, &pModules, sizeof(MODULES), NULL);
     if(memcmp(pModules.smi.ModuleNameOffset+pModules.smi.ImageName, "ntoskrnl.exe", sizeof("ntoskrnl.exe")) == 0)
         nCountCPU = 1;
     else if(memcmp(pModules.smi.ModuleNameOffset+pModules.smi.ImageName, "ntkrnlpa.exe", sizeof("ntkrnlpa.exe")) == 0)
         nCountCPU = 2;
     else return STATUS_UNSUCCESSFUL;
 
     // now, stamp in the return jmp into our detour function
     while(++i)
     {
         // we found the address 0xFFFFFFFF stamp it w/ the correct address
         if(!memcmp((unsigned char *)Detour_IofCallDriver + i, &DetourCode[1], 4))
         {
              *( (unsigned long *)((unsigned char *)Detour_IofCallDriver + i) ) = (unsigned long)IofCallDriver + 0x0B;
              break;
         }
     }
 
     // stamp in the target address of the far jmp
     *( (unsigned long *)(&DetourCode[1]) ) = (unsigned long)Detour_IofCallDriver;
 
     //overwrite the bytes in the kernel function
     //to apply the detour jmp
     InterruptDisable();
     memcpy(BackupCode, IofCallDriver, 7);
     memcpy(IofCallDriver, DetourCode, 7);
     InterruptEnable();
     return STATUS_SUCCESS;
}
 
VOID UnDetourFunctionIofCallDriver()
{
     //recovery kernel function
     InterruptDisable();
     memcpy(IofCallDriver, BackupCode, 7);
     InterruptEnable();
}
 
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
    UnDetourFunctionIofCallDriver();
}
 
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
     DriverObject->DriverUnload = OnUnload;
    if(STATUS_SUCCESS != DetourFunctionIofCallDriver())
     {
        DbgPrint("Detour Failure on IofCallDriver!/n");
        return STATUS_UNSUCCESSFUL;
    }   
    else return STATUS_SUCCESS;
}
         至此,文章都写完了,其实都没什么高深的知识,只是我觉得难而已^_^.在hook这个函数的过程中遇到了好多困难,也去提过问题,这里要感谢hopy大哥.也参考了一些文章,例如:“IRP 乱杂谈”“【原创】从内核层保护文件不被删除- 看雪软件安全论坛”“使用VPC进行Windows内核调试”“天书夜读(完整版)”等.非常感谢作者们的技术共享精神,同时我也鄙视那些怕人A你代码而不公开代码的人,技术不共享是不能进步的,同时就算有流氓利用的话,杀软的查杀也会进步的,相反没公开的技术被小部分人利用,后果好恐怖.
原来用Word写可以写得好漂亮的.
 
在内核驱动中检测隐藏进程 在安全检测工具 中.一般都 比较重视 隐藏 进程的检测 。道理很简单 .正常 的进程 没有必 要去 隐藏 自己.毕竟隐藏进程花费的代价还是 很 高 的。为什 么这 么说呢 ? 系统 中安 装 了钩 子 .运 行效 率 自然不 会 很高 人 正 不怕 影子 歪 .所 以说没 有必要去 隐藏 自己。当然也有 一 些例 外的网游 .为 了保护 自己从 而隐藏进程 . 常见的有韩国nProtect公司的跑跑卡丁车 .就存 在隐藏进程GameMon.des的运行 立即下载

相关推荐

termux 安装 rockylinux

往找最新的文件目录,选择ARM版本的image。或者直接查看目录或者国内阿里云镜像,按照cpu架构(安卓9手机一般是aarch64arm最新架构),获取镜像地址,以及checksum里的SHA256信息更新到以下rocky9.sh脚本,如果不需要直接使用即可。

欢迎来到别往的博客 984

windows内核情景分析---设备驱动

设备驱动 设备栈:从上层到下层的顺序依次是:过滤设备、类设备、过滤设备、小端口设备【过、类、过滤、小端口】 驱动栈:因设备堆栈原因而建立起来的一种堆栈  老式驱动:指不提供AddDevice的驱动,又叫NT式驱动 Wdm驱动:指提供了AddDevice的驱动 驱动初始化:指IO管理器加载驱动后,调用驱动的DriverEntry、AddDevice函数 设备栈中上层设备与下层设备的绑定关

maomao171314的专栏 2055

2024“华为杯”中国研究生数学建模竞赛(A题)深度剖析_数学建模完整过程+详细思路+代码全解析

目标是优化风力涡轮机的功率调度,使其在给定的实时风速数据下,最小化涡轮机关键组件(如塔架和主轴)的疲劳损伤。问题的挑战在于,考虑通信延迟和测量噪声的同时,要确保功率输出与风速变化的响应快速且准确。

2401_82549447的博客 6632

nt!IopSynchronousServiceTail函数分析到调用IopfCallDriver函数

nt!IopSynchronousServiceTail函数分析到调用IopfCallDriver函数

linux-0.11调试教程 617

STM32F103RC学习(一)

STM32F103RC学习(一)

Cat_South_North的博客 6058

MFC下使用C++操作Word文档

由于项目需求,在MFC环境下操作将数据和图片写入word文档,之前没有接触过,网上查阅了很多资料,终于把任务完成。理解的不是很透彻,但是这些东西应该够用了,写篇博客记录一下,以便以后再用到。 (1)VS环境下创建一个MFC应用程序,然后在项目上单击右键,选择 类向导-----添加类----类型库中的MFC类。在弹出的对话框中选择文件,位置选择office安装目录下的...

GIS_yuhua的博客 7582

IoCallDriver()简析

NTSTATUS IofCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp) { if(*pIofCallDriver)//je 0x1d { return pIofCallDriver(DeviceObject,Irp); } Irp->Cu

pureman_mega的博客 1799

【SemiDrive源码分析】【X9芯片启动流程】11 - freertos_safetyos目录Cortex-R5 DIL2.bin 引导程序源代码分析

【SemiDrive源码分析】【X9芯片启动流程】11 - freertos_safetyos目录Cortex-R5 DIL2.bin 引导程序源代码分析

|~~~热爱生活、努力学习的小伙汁~~~| 2112

Hook IofCallDriver 代码收集

Inline Hook IofCallDriver 截获所有IRP 首先声明这个是菜鸟—我的学习日记,不是什么高深文章,高手们慎看. 前段时间搞了一些Inline HOOK API的demo,例如对NtQueryDirectoryFile Inline HOOK 进行文件的隐藏,(恰好NtQueryDirectoryFile 在SSDT有导出,也可以采用改SSDT来实现HOOK....

weixin_30411997的博客 188

IP-Guard分类管理详解

大家都知道在配置IPGUARD策略前需要做分类库进行设置和分类。 1、应用程序:可以分类,例如上班时间只能用OFFICE和WPS,记事本等办公软件,可以在分类里设置一个类 ;办公软件,在未分类里找到OFFICE,WPS等拖入心建的分类里就可以在配置策略里调用。 2、网站分类也不一样,可以按照自己方式自定义。也可以导入厂家已经收集到的网站分类。 3、邮箱分类:可以提前定义好一个或...

IP-Guard专栏 591

数据处理和分析之数据聚类:层次聚类(Hierarchical Clustering):单链接层次聚类方法

单链接层次聚类(Single-Linkage Hierarchical Clustering)是凝聚型层次聚类的一种,它基于数据点之间的最小距离来定义聚类间的相似性。在单链接层次聚类中,两个聚类之间的距离定义为这两个聚类中任意两个数据点之间的最短距离。这种聚类方法倾向于形成链状或线性的聚类,因为聚类的边界是由最远的数据点决定的,而不是聚类的平均或中心位置。单链接层次聚类通过计算簇间最近点的距离来决定簇的合并,这种方法简单直观,但可能导致簇的形状不规则,尤其是在数据点分布不均匀的情况下。

2401_87715305的博客 1443

inline hook IofCallDriver 调用ntfs时保护文件访问

#include #include NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject); int IsNeedProtect(DEVICE_OBJECT *DeviceObject, PIRP Irp); ULONG GetFunctionAddr(IN PCWSTR FunctionName); VOID InlineHook();

125096 820

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

rootkit技术之IoCallDriver介绍

IoCallDriver是一个非常重要的内核例程,利用它可以过滤所有的系统请求,在IoCallDriver中调用IofCallDriver例程,几乎所有的内核驱动都调用了IofCallDriver。IoCallDriver的原型如下: NTSTATUS    IoCallDriver(     IN PDEVICE_OBJECT  DeviceObject,     IN OUT PIRP

软件调试的变革 3369

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ring3下Hook NtQueryDirectoryFile隐藏文件

NTSTATUS WINAPI Hook_NtQueryDirectoryFile(IN HANDLE FileHandle,IN HANDLE Event OPTIONAL,IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,IN PVOID ApcContext OPTIONAL,OUT PIO_STATUS_BLOCK IoStatusBlock,OUT PVOI...

weixin_33860528的博客 298

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IoCallDriver源码剖析

IoCallDriver是一个宏: #define IoCallDriver(a,b) \ IofCallDriver(a,b) 显然用的是IofCallDriver(); IofCallDriver()代码如下: NTSTATUS FASTCALL IofCallDriver( IN PDEVICE_OBJECT DeviceObje...

weixin_34256074的博客 186

Overlapped I/O 和 完成端口等异步IO在内核中的通知方式

By Fanxiushu  2013, 引用和转载请注明原作者 写这篇文章的动机:是因为最近在应用程序中调用DeviceIoControl读写自己做的一个驱动程序的数据,传输的数据包很多。 老的处理方式只是简单的采用多线程阻塞读写数据,这几天突然想到了完成端口,于是换成 完成端口后, 只用一个线程,投递上百个Overlapped读写操作,效率比原来高了许多, 因此就想从windows内核层

fanxiushu的专栏 3007

IoCallDriver源码

 以下是IoCallDriver接口的源码(基于WRK1.2)  NTSTATUS IoCallDriver(     IN PDEVICE_OBJECT DeviceObject,     IN OUT PIRP Irp     ) {     return IofCallDriver (DeviceObject, Irp); }  而IofCallDriver的源码如下

wing的专栏 993

Windows内核学习笔记(二)-- IoCallDriver函数与PoCallDriver函数

      今天看书的时候看到了这两个函数,开始还没在意,以为是同一个,功能应该一样。后来想想一样的干嘛还弄两个呢,于是就查了一下,发现这两个函数差别还蛮大的。首先来看这两个函数的原型:NTSTATUS IoCallDriver( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );NTSTATU

iT2afL0rd's Blog 8664

浅析"新时代"下的病毒隐藏技术

      浅析"新时代"下的病毒隐藏技术vxk 隐藏一直是病毒编写者的主要话题之一,在Syn,Mcafee公司相继推出各自的奇怪的反毒技术和探测技术的今天。我们作为新时代下的vxer,对隐藏这个话题也逐渐进入一个误区————就是总认为EPO+poly+mute的结构可以搞定大多数的杀软,其实非也——在如今虚拟机型为分析技术猖獗被应用于anti-virus software,壳分析也进入当年d

3214
上一篇: ZwSetSystemInformation的使用
下一篇: VC实现查找纯真数据库
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值