SSDT HOOK 保护文件

         现在手头上的其中一件事情就是帮同学做一个文件保护的毕业设计,考虑再三还是使用SSDT HOOK,因为这个最简单,而且比较稳定,也容易理解。

  提到文件保护,无非就是文件隐藏、文件打开、读写、删除保护等。

  一、文件隐藏

  文件隐藏可以通过HOOK NtQueryDirectoryFile函数来实现,这样可以使得受保护的文件无法在资源管理器之类的文件列表中显示出来。

  这种方法比较困难,一是难以稳定地获得目标文件的完整路径,二是难以稳定地将指定文件从返回的信息链表中删除。

  实际上,如果是需要实现文件保护,我们并不一定需要将文件进行隐藏,因为SSDT HOOK的隐藏效果并不十分理想,无法绕过调用文件系统驱动或磁盘驱动的程序,例如使用冰刃之类的ARK就可以一目了然地看到需要被隐藏的文件。

  综上所述,我们决定放弃对文件的隐藏,专注对文件进行保护。

  二、文件打开保护

  对文件打开主要有两个函数,NtCreateFile和NtOpenFile,通过WRK或反汇编可以看到这两个函数都是直接调用了下层的IoCreateFile,而NtOpenFile并未调用NtCreateFile,因此为了实现文件打开保护,我们必须同时HOOK NtCreateFile、NtOpenFile这两个函数。

  需要注意的是,这两个函数中的FileHandle是传出参数,函数被调用后句柄中才有目标文件的路径信息,但这时候文件已经被打开了,我们已经失去了拦截的时机。

  实际上,在这两个函数中,我们可以不通过句柄获取文件路径信息,而是通过参数中的ObjectAttributes->RootDirectory和ObjectAttributes->ObjectName来获得。如果ObjectAttributes->RootDirectory不为空,则ObjectAttributes->ObjectName表示的是相对路径,否则为完整路径。

  在大多数情况下,ObjectAttributes->RootDirectory都是为空,即ObjectAttributes->ObjectName包含了请求文件的完整路径。

  三、文件读写保护

  一般地,如果我们通过HOOK文件打开函数,应用程序将无法获得受保护文件的句柄,也就无法进行后续的文件读写、文件删除等操作。

  但实际情况并非如此,在系统的system进程中拥有所有的句柄信息,因此用户可以通过调用NtDuplicateObject之类的函数复制获得句柄,因此我们仍然需要HOOK文件读写函数。

  文件读写函数主要有两个,即NtReadFile和NtWriteFile。在这两个函数中我们可以通过FileHandle获得请求文件的路径信息,判断是否需要保护。

  四、文件删除保护

  通过反汇编DeleteFileW可以看到,它们都是调用NtSetInformationFile删除文件的,当函数NtSetInformationFile的参数FileInformationClass值为FileDispositionInformation时,则它将对目标文件设置一个删除标记,这样等该文件的所有句柄被关闭后文件将会被删除。

  因此通过HOOK NtSetInformationFile便可以拦截大多数删除文件过程,但这并不是说NtDeleteFile就没有用处,我们在《The Undocumented Functions》一书中可以看到它对NtDeleteFile的解释如下:

  It's very interesting NT System Call... Normally, file deletion is realised as FileDispositionInformation class in a call to NtSetInformationFile. When you use NtDeleteFile, file will be deleted immediatly after call (system isn't waiting for close last HANDLE to file).

  从上述说明可以看出,如果我们直接调用NtD

eleteFile,目标文件将会被立即删除而不会等到所有句柄都被关闭。通过这个说明我们可以知道,直接调用NtDeleteFile将会绕过对NtSetInformationFile的挂钩,因此我们需要同时HOOK NtDeleteFile。

  这里需要说明一点,有人可能会想要通过HOOK NtDuplicateObject而无需HOOK后面这些众多函数以达到目的,我没试过这种情况,假定它是可行的,但即使在这种情况下同样需要HOOK NtDeleteFile。

  这是因为NtDeleteFile仅有一个POBJECT_ATTRIBUTES参数,它并不像其它函数那样需要一个FileHandle参数,也就是说它不需要句柄,因此我们必须直接挂钩该函数,虽然ring3的API没有调用它,但并不能排除直接调用NtDeleteFile的可能性存在。

  五、总结

  现在总结一下,为了实现文件保护,我们必须HOOK NtCreateFile、NtOpenFile、NtReadFile、NtWriteFile、NtSetInformationFile、NtDeleteFile这几个函数。考虑不周之处还望见谅!

 比较值得学习的

我测试了一下真的可以保护文件就做了一个NtOpenFile真的成功了

其中off(),On()等函数我已经在第一章说了,在这里我不在重复。

typedef NTSTATUS(__stdcall *NewNtCreateFile)(
__out PHANDLE FileHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__out PIO_STATUS_BLOCK IoStatusBlock,
__in_opt PLARGE_INTEGER AllocationSize,
__in ULONG FileAttributes,
__in ULONG ShareAccess,
__in ULONG CreateDisposition,
__in ULONG CreateOptions,
__in_bcount_opt(EaLength) PVOID EaBuffer,
__in ULONG EaLength
);
ULONG oldaddr;
NewNtCreateFile _NewNtCreateFile;
NTSTATUS MyNtOpenFile(
__out PHANDLE FileHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__out PIO_STATUS_BLOCK IoStatusBlock,
__in_opt PLARGE_INTEGER AllocationSize,
__in ULONG FileAttributes,
__in ULONG ShareAccess,
__in ULONG CreateDisposition,
__in ULONG CreateOptions,
__in_bcount_opt(EaLength) PVOID EaBuffer,
__in ULONG EaLength
)
{
wchar_t *pathname;
pathname=ObjectAttributes->ObjectName->Buffer;
wchar_t *cmpname=L"\\??\\D:\\123";
/*DbgPrint("%S",cmpname);*/
if (wcsstr(pathname,cmpname)!=NULL)
{
DbgPrint("%S",pathname);
return STATUS_ACCESS_DENIED;
}
return _NewNtCreateFile(
FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength
);
}
void HookNtOpenFile()
{
oldaddr=GetSSDTAddr(37);
_NewNtCreateFile=(NewNtCreateFile)oldaddr;
off();
KeServiceDescriptorTable->Base[37]=(ULONG)MyNtOpenFile;
    on();
}
void UnHook()
{  
off();
KeServiceDescriptorTable->Base[37]=oldaddr;
on();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值