首页
社区
课程
招聘
[原创]【很有时间系列】如何优雅地在内核做dll加载拦截
发表于: 2018-5-4 19:57 20909

[原创]【很有时间系列】如何优雅地在内核做dll加载拦截

2018-5-4 19:57
20909

拦截dll加载有两种思路,一种是从文件入手:minifilter、sfilter...反正都是对LdrLoadDll过程中可能出现的IRP进行拦截

比如

还有一种是从dll本身入手,比如把dll的入口点给patch了,这个等下再讲

先讲第一种,最简单的方法当然是拦截CreateFileMapping/CreateSection,它对应的IRP是IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION

注册minifilter就不提了
	{
		IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION,
		FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
		PreCreateSection,
		NULL
	},
FLT_PREOP_CALLBACK_STATUS FLTAPI PreCreateSection(
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
){
	if(FltGetRequestorProcessId(Data) == 你要拦截dll加载的进程的PID){
		if (Data->Iopb->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection){
			PFLT_FILE_NAME_INFORMATION pNameInfo = NULL;
			if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pNameInfo))){

还有一种是从dll本身入手,比如把dll的入口点给patch了,这个等下再讲

先讲第一种,最简单的方法当然是拦截CreateFileMapping/CreateSection,它对应的IRP是IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION

注册minifilter就不提了
	{
		IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION,
		FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
		PreCreateSection,
		NULL
	},
FLT_PREOP_CALLBACK_STATUS FLTAPI PreCreateSection(
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
){
	if(FltGetRequestorProcessId(Data) == 你要拦截dll加载的进程的PID){
		if (Data->Iopb->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection){
			PFLT_FILE_NAME_INFORMATION pNameInfo = NULL;
			if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pNameInfo))){

	{
		IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION,
		FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO,
		PreCreateSection,
		NULL
	},
FLT_PREOP_CALLBACK_STATUS FLTAPI PreCreateSection(
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
){
	if(FltGetRequestorProcessId(Data) == 你要拦截dll加载的进程的PID){
		if (Data->Iopb->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection){
			PFLT_FILE_NAME_INFORMATION pNameInfo = NULL;
			if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pNameInfo))){

FLT_PREOP_CALLBACK_STATUS FLTAPI PreCreateSection(
	__inout PFLT_CALLBACK_DATA Data,
	__in PCFLT_RELATED_OBJECTS FltObjects,
	__deref_out_opt PVOID *CompletionContext
){
	if(FltGetRequestorProcessId(Data) == 你要拦截dll加载的进程的PID){
		if (Data->Iopb->Parameters.AcquireForSectionSynchronization.SyncType == SyncTypeCreateSection){
			PFLT_FILE_NAME_INFORMATION pNameInfo = NULL;
			if (NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &pNameInfo))){

这时候你已经有了dll路径和FileObject。你可以根据具体需要判断是否需要拦截这个dll
if(需要拦截DLL( ProcessId, Data->Iopb->TargetFileObject, pNameInfo)){
  Data->IoStatus.Status = STATUS_ACCESS_DENIED;
  result = FLT_PREOP_COMPLETE;
}
。。。。
return result;

if(需要拦截DLL( ProcessId, Data->Iopb->TargetFileObject, pNameInfo)){
  Data->IoStatus.Status = STATUS_ACCESS_DENIED;
  result = FLT_PREOP_COMPLETE;
}
。。。。
return result;

你以为这样就完事了?
然鹅每次dll被拦截都会提示这个
那么怎么去掉这个提示呢

你需要来自BattlEye的神秘力量,返回值给INSUFFICIENT RESOURCES才能没有错误提示


if(需要拦截DLL( ProcessId, Data->Iopb->TargetFileObject, pNameInfo)){
  Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;//←这样才能没有错误提示
  result = FLT_PREOP_COMPLETE;
}
。。。。
return result;

if(需要拦截DLL( ProcessId, Data->Iopb->TargetFileObject, pNameInfo)){
  Data->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;//←这样才能没有错误提示
  result = FLT_PREOP_COMPLETE;
}
。。。。
return result;

你以为这样就完事了?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 10
支持
分享
最新回复 (23)
雪    币: 914
活跃值: (2463)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
2
今天的很有时间系列由hzqst主持,大家没意见吧
2018-5-4 20:07
0
雪    币: 775
活跃值: (2292)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
顶  ,感谢分享
2018-5-4 20:09
0
雪    币: 70
活跃值: (1352)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
IsValidImage 
2018-5-4 20:11
0
雪    币: 2435
活跃值: (745)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
前排卖瓜子
2018-5-4 20:17
0
雪    币: 6124
活跃值: (4656)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
6
今天的很有时间系列由hzqst主持,大家没意见吧
2018-5-4 22:20
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
7
然而MapView发生时的IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION并不是必要的,有一些高权重miniflt会直接完成这个Acquire,后面的filter全部收不到了,比如BE就会收不到。比如某至高权重的驱动( 某驱动435500 ,一个正规LDP系统里的



BEDaisy.sys的权重是363220,甚至不如我的372100

最后于 2018-5-5 11:07 被cvcvxk编辑 ,原因:
2018-5-5 11:02
0
雪    币: 16
活跃值: (527)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
BattlEye是什么
2018-5-5 11:06
0
雪    币: 405
活跃值: (2280)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
不错,比在loadimage  CALLBACK  里做PATCH  要好。
2018-5-5 17:15
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
大表哥和老V是约好了吗?
2018-5-7 00:04
0
雪    币: 231
活跃值: (2631)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
谢谢分享
2018-5-8 03:30
0
雪    币: 7
活跃值: (283)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
STATUS_INSUFFICIENT_RESOURCES    就很魔性了    之前写minifilter的时候为了不提示  先返回挂起再在挂起回调里面阻止 
2018-5-8 17:29
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
13
其实一些风骚的pe文件的e_lfanew可能大于0x1000,比如某文件的e_lfanew是0x30000
于是只读0x1000的判断pe就统统升天
有大于0x1000自然有还有小于0的e_lfanew(dosheader里这玩意是LONG)

最后于 2018-5-8 18:07 被cvcvxk编辑 ,原因:
2018-5-8 17:54
0
雪    币: 197
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
谢谢分享
2018-5-10 16:08
0
雪    币: 523
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
拦截杀毒软件蓝屏
2019-3-30 18:47
0
雪    币: 523
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
拦截杀毒软件dll蓝屏  哈哈哈
2019-3-30 18:47
0
雪    币: 41
活跃值: (234)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
没有看懂。
2019-3-30 22:59
0
雪    币: 132
活跃值: (162)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
老哥 这个分析的是什么工具啊,
2019-10-1 21:27
0
雪    币: 83
活跃值: (1087)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
20
good
2019-10-4 15:42
0
雪    币: 2674
活跃值: (2304)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
21
以前在Sfilter框架下做过类似的功能,就相当于: FsRtlRegisterFileSystemFilterCallbacks时,指定Callbacks->PreAcquireForSectionSynchronization, 这里就可以对nt!NtCreateSection作拦截。只是FltMgr.sys在DriverEntry里面就注册了这样的回调,相当于对MiniFilter作了封装。
我空了再仔细逆向FltMgr.sys然后和Sfilter作个对比!感谢前辈分享!
2020-12-16 23:07
0
雪    币: 288
活跃值: (282)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
explorer 返回这个值 也会有提示。
2021-12-15 18:47
0
雪    币: 1570
活跃值: (1875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
从dll本身入手,比如把dll的入口点给patch 这个讲讲?
2023-2-1 18:23
0
雪    币: 1862
活跃值: (4146)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
 mark~~
2023-2-1 19:39
0
游客
登录 | 注册 方可回帖
返回
//