说说为什么能过主防
做过拦截都应该知道,一般如果这个操作来着内核的话就会放过
我希望你明白上面这点
那么开始我们今天的话题
学过minifilter的应该知道,我们可以通过inf文件来安装驱动,这个inf文件中有一项我们是写
SERVICE_FILE_SYSTEM_DRIVER
这一项代表的意义应该都知道的
其实这个我们是可以改的,我们改成我们NT驱动,普通内核文件
SERVICE_KERNEL_DRIVER
这有什么问题吗?--没有问题 !
了解minifilter加载的人是没有问题的!
提示:加载Minifilter时跟普通加载有什么不同?
只不过是一个键的问题
上面明白了,就可以继续走了
在文件系统中有一个加载驱动的函数
摘自:WDK帮助手册
FilterLoad和FilterUnload可用于在用户态程序控制minifilter驱动的加载和卸载。
我们来看看FilterLoad是怎么实现
HRESULT
WINAPI
FilterLoad(
IN LPCWSTR lpFilterName
);
__int64 __fastcall FilterLoad(void *Src) { const void *v1; // r13@1 __int64 v2; // r12@1 HANDLE v3; // rsi@1 DWORD v4; // eax@2 unsigned int v5; // edi@2 signed __int64 v6; // rcx@5 const void *v7; // rdi@5 bool v8; // zf@7 __int64 v9; // rax@8 HANDLE v11; // [sp+48h] [bp-30h]@1 __int64 v12; // [sp+50h] [bp-28h]@1 unsigned __int16 v13; // [sp+88h] [bp+10h]@8 signed int v14; // [sp+90h] [bp+18h]@4 int v15; // [sp+98h] [bp+20h]@8 v1 = Src; v2 = 0i64; v12 = 0i64; v3 = CreateFileW(L"\\\\.\\FltMgr", 0x40000000u, 2u, 0i64, 3u, 0x80u, 0i64); v11 = v3; if ( v3 == (HANDLE)-1 ) { v4 = GetLastError(); v5 = (unsigned __int16)v4 | 0x80070000; if ( (signed int)v4 <= 0 ) v5 = v4; v14 = v5; } else { v6 = -1i64; v7 = v1; do { if ( !v6 ) break; v8 = *(_WORD *)v7 == 0; v7 = (char *)v7 + 2; --v6; } while ( !v8 ); v13 = 2 * (~(_WORD)v6 - 1); v15 = v13 + 2; LODWORD(v9) = RtlAllocateHeap( *(_QWORD *)(*(_QWORD *)(*MK_FP(__GS__, 48i64) + 96i64) + 48i64), 0i64, (unsigned int)v15); v2 = v9; v12 = v9; if ( v9 ) { *(_WORD *)v9 = v13; memcpy((void *)(v9 + 2), v1, v13); v3 = v11; v5 = FilterpDeviceIoControl((__int64)v11, 557060, v2, (unsigned int)v15, 0i64);//注意这句 v14 = v5; } else { v5 = -2147024882; v14 = -2147024882; v3 = v11; } } if ( v3 != (HANDLE)-1 ) CloseHandle(v3); if ( v2 ) { RtlFreeHeap(*(_QWORD *)(*(_QWORD *)(*MK_FP(__GS__, 48i64) + 96i64) + 48i64), 0i64, v12); v5 = v14; } return v5; }
__int64 __fastcall FilterpDeviceIoControl(__int64 a1, int a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8) { __int64 v8; // r12@1 int v9; // edi@1 char v10; // r10@1 __int64 v11; // rdx@5 __int64 v12; // r9@5 int v13; // er11@7 __int64 v14; // rdx@8 __int64 v15; // r9@8 int v17; // [sp+58h] [bp-30h]@20 int v18; // [sp+60h] [bp-28h]@21 v8 = a1; v9 = 0; v10 = 1; if ( (a2 & 0xFFFF0000) == 589824 ) v10 = 0; if ( a8 ) { *(_QWORD *)a8 = 259i64; if ( v10 ) { v11 = *(_QWORD *)(a8 + 24); v12 = a8; if ( v11 & 1 ) v12 = 0i64; v13 = NtDeviceIoControlFile(a1, v11, 0i64, v12); } else { v14 = *(_QWORD *)(a8 + 24); v15 = a8; if ( v14 & 1 ) v15 = 0i64; v13 = NtFsControlFile(a1, v14, 0i64, v15); } if ( (v13 & 0xC0000000) != -1073741824 && a7 ) *(_DWORD *)a7 = *(_DWORD *)(a8 + 8); } else { if ( v10 ) v13 = NtDeviceIoControlFile(a1, 0i64, 0i64, 0i64); else v13 = NtFsControlFile(a1, 0i64, 0i64, 0i64); if ( v13 == 259 ) { v13 = NtWaitForSingleObject(v8, 0i64, 0i64); if ( v13 >= 0 ) v13 = v17; } *(_DWORD *)a7 = v18; } if ( v13 ) v9 = FilterHResultFromNtStatus((unsigned int)v13); return (unsigned int)v9; }
现在应该知道了吧
用这个来加载,是下发请求,这不是在使用ZwLoadDriver 或者服务等来加载驱动
需要注意的是,虽然这样来说是时内核来加载驱动,但这相对的,如果某些杀软拦截来着内核的话就没有办法了
可以这么说,使用这种方法来加载驱动,不是使用了ZwloadDriver,而是使用了比这个底层一点的lopLoadDriver(不确定)
虽然这么过了,但在加载模块回调中还是有的
这样加载普通驱动有个不好的地方,就是不好卸载,理应我们可以使用FilterUnload来卸载驱动
来看看FilterUnload的MSDN说明
FilterUnload searches for a registered minifilter whose service name matches the given lpFilterName and calls that minifilter's FilterUnloadCallback (PFLT_FILTER_UNLOAD_CALLBACK) routine. If the minifilter did not register a FilterUnloadCallback routine, the call to FilterUnload fails. Callers of FilterUnload must have SeLoadDriverPrivilege (the LUID of SE_LOAD_DRIVER_PRIVILEGE) to load or unload a minifilter driver. This privilege is named by the SE_LOAD_DRIVER_NAME name constant. (Privileges are described in the Microsoft Windows Software Development Kit (SDK) for Windows 7 and .NET Framework 4.0 documentation.)
那么卸载就不能这么卸载了
方法也很简单要么就是停止服务(无论是使用inf或者创建注册表(其实这两个一样的性质))
要么手动net stop xxxx
或者编程关闭服务
都是可行的
代码:无非就是原来加载普通驱动的函数(不是ZwLoadDriver,是创建服务的)
1.编程安装inf文件(改变加载的服务类型 文件系统驱动程序->普通内核文件) 然后调用FilterLoad
2.编程创建服务 增加和设置instance的键和子键 服务类型为普通内核文件 然后调用FilterLoad
会的人2分钟搞定
另外一个方法就是打印机驱动
使用AddPrintfDriver
不过我测试时函数已经成功了,驱动并没有加载起来,待我再研究研究