说明下,技术比较古老,适合我等小菜...
中秋的时候看了关于内核对象的内容, 为了加深理解, 就想试下文件的强制删除,只要把文件对象的引用计数改为0就可以了嘛... 不过郁闷的是根本就找不到那个文件对象, 那个啊,然后就去网上找资料,怎么才能实现文件的强制删除呢?MJ说有两种方法
1.你可以使用自己给fsd发送irp请求来删除文件,或者用HOOK MmFlushImageSection等方法,详细见xikug等人逆向的360FileKill的驱动代码
2.使用DeviceIoControl调用驱动文件,或使用事件、共享内存等方法亦可
然后就去看文件过滤驱动,也就是想给文件系统发IRP实现,看那个寒江独钓,好不容易看懂了,不过纠结的是他没有提供读写的源码,郁闷ing... 接下来就是HOOK MmFlushImageSection函数了,终于找到了一篇代码了,使用hook MmFlushImageSection实现文件保护... 作者liuke_blue,非常感谢,O(∩_∩)O哈哈~
于是开始编写自己的文件强制删除机...
代码:
//自己的处理函数 BOOLEAN NTAPI Fake_MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer,IN MMFLUSH_TYPE FlushType) { PFILE_OBJECT pfile; WCHAR *pwsz=NULL; if (FlushType == MmFlushForDelete) { if(SectionObjectPointer->DataSectionObject!=NULL) { //这里取得文件对象 pfile=(PFILE_OBJECT)( *(ULONG*)((ULONG)SectionObjectPointer->DataSectionObject + 0x24) ); __try { pwsz=wcsrchr(pfile->FileName.Buffer,L'\\'); if (pwsz!=NULL) { pwsz++; } //比较文件名是否相同,如果是,则删除 if (strcmp(outBuf.Buffer, pwsz) == 0) { DbgPrint("FileName=%ws",pwsz); return TRUE; } } except(1) { return FALSE; } } } return MmFlushImageSection(SectionObjectPointer,FlushType); }
代码:
BOOLEAN _DeleteFileNormal(PUNICODE_STRING filename) { HANDLE hfile; NTSTATUS ntstatus; ACCESS_MASK acmask; OBJECT_ATTRIBUTES oa; IO_STATUS_BLOCK iostatus; ULONG shareAccess; ULONG openOptions; FILE_STANDARD_INFORMATION filestandardinfo; FILE_DISPOSITION_INFORMATION filedisposition; InitializeObjectAttributes(&oa, filename, OBJ_CASE_INSENSITIVE , NULL, NULL); //方法1:调用ZwDeleteFile函数删除 ZwDeleteFile(&oa); /* //方法2:根据DeleteFile函数逆向出来的, 如果文件没在使用中可以删除,如果在使用中则ZwOpenFile函数失败,自然也不会调用MmFlushImageSection函数了,所以文件删除失败 ntstatus = ZwOpenFile(&hfile, GENERIC_READ | GENERIC_WRITE, &oa, &iostatus, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(ntstatus)) { KdPrint(("ZwOpenFile failed\n")); return FALSE; } ntstatus = ZwQueryInformationFile(hfile, &iostatus, &filestandardinfo, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); if (!NT_SUCCESS(ntstatus)) { KdPrint(("Query FileStandardInformation failed..\n")); return FALSE; } if (filestandardinfo.DeletePending == FALSE) { filedisposition.DeleteFile = TRUE; ntstatus = ZwSetInformationFile(hfile, &iostatus, &filedisposition, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation); if (!NT_SUCCESS(ntstatus)) { KdPrint(("ZwSetInformationFile failed\n")); return FALSE; } } ZwClose(hfile); */ return TRUE; }