首页
社区
课程
招聘
[原创]从内核层保护文件不被删除
发表于: 2007-5-27 17:20 26612

[原创]从内核层保护文件不被删除

2007-5-27 17:20
26612

前几天发了一篇删除正在运行的程序文件的代码片,其实都平常写demo留下的东西,如果大家有兴趣,我会找时间慢慢整理一些出来和大家分享。同样是块demo代码,前面有兄弟问为什么不整完整一些,在这里解释一下:
1. 因为要分享是一种思路或技巧,不想被一些有心人不劳而获的A走(虽然我也是A别人的,呵呵)
2. 关键的,如果发完整的领导就该找我喝茶了,希望能理解

好了,回到正题是来,保护文件不被删除的方法有很多,例如:FSD Dispatch Hook、文件过滤驱动、在内核层打开文件占用等等,这里要介绍的是另一种方法,Inline Hook IofCallDriver大法,用这个方法来保护文件确实有点大材小用(它可以做的事情实在太多了,充分发挥想像力吧),并且在性能上可能会有点问题,但它有个优势是可以躲过一些工具的查杀。
它保护文件的基本原理是:
当系统要删除一个文件时,它会向ntfs或fastfat驱动发送一个MajorFunction为IRP_MJ_SET_INFORMATION的IRP,而用来传递Irp的函数是IoCallDriver,该函数是一个宏,它再调用IofCallDriver,所以我们只要Inline Hook IofCallDriver函数就可以拦截删除文件请求。大概步骤如下:
1.Inline Hook IofCallDriver函数
2.判断sp->MajorFunction == IRP_MJ_SET_INFORMATION 如果不相等,则跳出
3.判断sp->Parameters.SetFile.FileInformationClass == FileDispositionInformation,如果不相等,则跳出。
4.判断DeviceObject->DriverObject.DriverName是否为\FileSystem\ntfs或\FileSystem\fastfat,因为我们要拦截的是发往ntfs和fastfat驱动的Irp请求,所以如果不相等,则跳出。
5.判断sp->FileObject.FileName是否是我们要保护的文件(注意:这里取到的不是全路径,需要全路径要另作处理),如果不相等,则跳出
6.上面所有条件都符合时,设置Irp->IoStatus.Information = 0;Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;并调用IoCompleteRequest完成Irp,Irp不再往下传了。

IofCallDriver函数的原型
NTSTATUS
         __fastcall
         IofCallDriver(
         IN PDEVICE_OBJECT DeviceObject,
         IN OUT PIRP Irp
         );
这是一个fastcall函数,取参数的时候要注意一下。
下面是代码片段:
#define PROLOG __asm { pushad } __asm { pushfd }
#define RETURN __asm { popfd } __asm { popad } __asm { pop eax } __asm{ mov eax, 0xC000000D } __asm{ ret }
#define EPILOG __asm { popfd } __asm { popad } __asm { ret }

_declspec( naked )
NTSTATUS
__fastcall
IofCallDriver_Hook(
                          IN PDEVICE_OBJECT DeviceObject,
                          IN OUT PIRP Irp
                          )
{
        PROLOG
        __asm
        {
                push ecx
                pop dword ptr g_HookParam.DeviceObject
                push edx
                pop dword ptr g_HookParam.Irp
        }
        if (IsNeedProtect(g_HookParam.DeviceObject, g_HookParam.Irp))
        {
                dprintf("Protect start...\n");
                RETURN
        }
       
Exit0:
        EPILOG

}

int IsNeedProtect(DEVICE_OBJECT *DeviceObject, PIRP Irp)
{
        NTSTATUS status = STATUS_INVALID_PARAMETER;
        int nResult = FALSE;
        DRIVER_OBJECT        *DriverObject = DeviceObject->DriverObject;
        WCHAR                        *pwsz = NULL;
        IO_STACK_LOCATION *sp;
        FILE_OBJECT                *FileObject = NULL;

        sp = IoGetNextIrpStackLocation(Irp);
        PROCESS_ERROR(sp);
       
        if (sp->MajorFunction != IRP_MJ_SET_INFORMATION)
        {
                goto Exit0;
        }

        if (sp->Parameters.SetFile.FileInformationClass != FileDispositionInformation)
        {
                goto Exit0;
        }

        FileObject = sp->FileObject;
        __try
        {       
                pwsz = wcsrchr(DriverObject->DriverName.Buffer, L'\\');
                PROCESS_ERROR(pwsz);
                pwsz ++;

                if (_wcsnicmp(pwsz, L"ntfs", 4) &&
                        _wcsnicmp(pwsz, L"fastfat", 7))
                {
                        goto Exit0;
                }

                dprintf("IofCallDriver: Delete file %ws\n", FileObject->FileName.Buffer);

                pwsz = wcsrchr(FileObject->FileName.Buffer, L'\\');
                if (pwsz)
                {
                        pwsz ++;
                }
                else
                {
                        pwsz = FileObject->FileName.Buffer;
                }

                if (!_wcsnicmp(pwsz, L"test.exe", 8))
                {
                        Irp->IoStatus.Information = 0;
                        Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;

                        IoCompleteRequest(Irp, IO_NO_INCREMENT);
                        nResult = TRUE;
                        goto Exit0;
                }

        }
        __except(1)
        {
                goto Exit0;
        }

Exit0:
        return nResult;
}

结束。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (37)
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
2
应该还有很多碎片,支持大牛挖掘出来
2007-5-27 17:30
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
3
方法太多...不过大致都是Hook或过滤...
有没有不hook的呢?
2007-5-27 18:01
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
4
hook还是非hook都只是一种方法,只要能达到目的,又有什么关系呢
2007-5-27 19:20
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
5
完全不懂 只能说学习
2007-5-27 19:22
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
6
HOOK比较容易被检测到
2007-5-27 19:40
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我的目标偶像在这呢...一起顶大牛!!!
2007-5-27 19:42
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
8
Hook IofCallDriver也算是rootkit惯用的手法了...
某些HIPS系统和anti-rootkit会检测这个点
2007-5-27 19:43
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
9
检测到不怕,只要够无赖就行,就是赖在系统里不走
2007-5-27 20:32
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
10
谁比谁无赖还不一定呢...
2007-5-27 20:39
0
雪    币: 220
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
一些软件压根不调IofCallDriver怎搞
2007-5-27 21:16
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
12
矛与盾的问题,逆向一下,再想对策吧
2007-5-27 22:06
0
雪    币: 1593
活跃值: (806)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
13
呵呵,还漏了CreateFile()的时候dwDesiredAccess里有DELETE属性的情况(FSD hook的时候注意不要重入,最好用shadow device来解决重入问题)。另外,“修改文件内容”在某些情况下也可以等同于“删除文件”,例如把文件内容清0(但文件还在),因此,hardlink也必须考虑进去。总之只通过文件名来保护的话要考虑的问题有很多,要做到稳定、高效的话还是不容易的。
2007-5-27 22:33
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
14
支持老Y,懂这方面的牛人不少,但是肯拿出来的不多!
2007-5-28 08:51
0
雪    币: 234
活跃值: (1659)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
15
真的不懂,只能支持!
2007-5-28 09:06
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
16
本质上来说这种方法跟文件过滤, FSDHook,SSDTHook是一样的。。。只能对应用层和标准的方法进行防范,对直接绕过文件系统的方法无效。。。
见过磁盘级的保护。。。再底层就没见过了。。。
2007-5-28 09:10
0
雪    币: 200
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
再底层就是电路级了.
我见过.
2007-5-28 09:51
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
18
luocong同学考虑得真周到,这里只是一个demo而以,要做成产品的话,还有太多的东西要考虑
2007-5-28 10:59
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
19
西裤哥总是这么一针见血
2007-5-28 11:00
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
20
牛人们,都把你们的东西拿出来秀一秀吧,呵呵(悄悄的说:我的目的就达到了)
2007-5-28 11:01
0
雪    币: 263
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
21
再再底层就是电源级了,
我见过
2007-5-28 11:22
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
22
可以恢复,前几天搞一个恢复iofCompleteXXX对付了某人的某玩意~

前面那个删除文件,还可以,不过技术很老套,另外只要inline hook MmXXX区分一下谁调用的就可以啦——何必hook在fastfat和ntfs里呢~另外hook MmXXX不是很好,最好还是修改FileObject让他可以在MmXXX里返回True~
2007-5-28 13:43
0
雪    币: 163
活跃值: (60)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
23
Hook在fastfat和ntfs里只是为了原样再现而以
2007-5-28 13:51
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
24
大牛里面爱打~~~~~~~~~~的印象中只有一个,一看id,明白了。
摸拜:D
2007-5-28 14:02
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
25
原样再现,明白是啥了~~

~~~~符号是我的习惯而已啊~
2007-5-28 15:14
0
游客
登录 | 注册 方可回帖
返回
//