删除运行中程序

标 题: 【分享】发一块代码段(删除正在运行的程序文件)
作 者: 老Y
时 间: 2007-05-25,16:59:36
链 接: http://bbs.pediy.com/showthread.php?t=45233

先声明一下,本文的代码其实也是从别人的工具里A出来的(A=逆向+还原),所以也不敢称是原创,有同好的朋友自然知道是哪个工具里的:),另外,由于本人不太会写文章,看不明白的地方还请大家多多谅解。

回到正题,通过分析得知,删除正在运行的程序文件的关键在于hook MmFlushImageSection这个函数,该函数原型BOOLEAN MmFlushImageSection(
                 PSECTION_OBJECT_POINTERS SectionObjectPointer,
                 MMFLUSH_TYPE FlushType),其流程大概如下:
1.打开要删除的文件,如:调用IoCreateFile
2.把要删除的文件属性设为Normal
3.Hook ntfs和fatfast内的引入函数MmFlushImageSection
4.发送删除IRP

大概代码如下(比较简单的一个Demo): void ForceDeleteFile(PVOID ThreadContext) { int krResult = FALSE; int krRetCode = FALSE; //NTSTATUS rc; HANDLE hFile = NULL, hFileSystem = NULL, SectionHandle = NULL; CHAR *FileName = (CHAR*)ThreadContext; CHAR szFileSystem[MAX_PATH_LEN]; PUCHAR pMap = NULL; ULONG uMapSize = 0; PVOID OrgFunc = NULL, OrgFunc_Ptr = NULL; KFile ntfs, fastfat, del; //UNICODE_STRING usFileName; //PFILE_OBJECT pFileObject = NULL; //OBJECT_ATTRIBUTES ob; DEBUG_BREAK; krRetCode = del.OpenFile(FileName, GENERIC_READ); PROCESS_ERROR(krRetCode); dprintf("Open %s successful./n", FileName); krResult = del.SetFileAttributeToNormal(); PROCESS_ERROR(krResult); strcpy(szFileSystem, DRIVERS_PATH); strcat(szFileSystem, "ntfs.sys"); krRetCode = ntfs.OpenFile(szFileSystem, GENERIC_READ); PROCESS_ERROR(krRetCode); g_Deleted = TRUE; krRetCode = ntfs.MapFile(&pMap, &uMapSize); PROCESS_ERROR(krRetCode); krRetCode = HookIAT( "MmFlushImageSection", "ntfs.sys", pMap, uMapSize, (PVOID)MmFlushImageSection_New, (PVOID*)&_MmFlushImageSection, &OrgFunc_Ptr ); PROCESS_ERROR(krRetCode); krRetCode = ntfs.UnMapFile(); PROCESS_ERROR(krRetCode); strcpy(szFileSystem, DRIVERS_PATH); strcat(szFileSystem, "fastfat.sys"); krRetCode = fastfat.OpenFile(szFileSystem, GENERIC_READ); PROCESS_ERROR(hFileSystem); krRetCode = fastfat.MapFile( &pMap, &uMapSize); PROCESS_ERROR(krRetCode); krRetCode = HookIAT( "MmFlushImageSection", "fastfat.sys", pMap, uMapSize, (PVOID)MmFlushImageSection_New, (PVOID*)&_MmFlushImageSection, &OrgFunc_Ptr ); PROCESS_ERROR(krRetCode); krRetCode = ntfs.UnMapFile(); PROCESS_ERROR(krRetCode); krResult = Rd_DeleteFile(del.GetFileHandle()); PROCESS_ERROR(krResult); krResult = TRUE; Exit0: g_Deleted = FALSE; if (OrgFunc && OrgFunc_Ptr) { UnHookIAT(_MmFlushImageSection, OrgFunc_Ptr); } ntfs.Close(); fastfat.Close(); del.Close(); return; } Rd_DeleteFile代码如下: int Rd_DeleteFile(HANDLE hFile) { int krResult = FALSE; DEVICE_OBJECT *pRealObject = NULL; DEVICE_OBJECT *pDeviceObject = NULL; PIRP irp; NTSTATUS rc; KEVENT event; PIO_STACK_LOCATION irpSp; IO_STATUS_BLOCK localIoStatus; PFILE_OBJECT pFileObject = NULL; FILE_DISPOSITION_INFORMATION disp; ULONG Length = sizeof(FILE_DISPOSITION_INFORMATION); disp.DeleteFile = TRUE; rc = ObReferenceObjectByHandle( hFile, 0, *IoFileObjectType, 0, (PVOID*)&pFileObject, 0); PROCESS_DDK_ERROR(rc); pDeviceObject = GetRealDeviceObject(pFileObject, &pRealObject); PROCESS_ERROR(pDeviceObject); KeInitializeEvent(&event, SynchronizationEvent, FALSE); irp = IoAllocateIrp(pDeviceObject->StackSize, 0); if (!irp) { goto Exit0; } irp->UserEvent = &event; irp->UserIosb = &localIoStatus; irp->Overlay.AsynchronousParameters.UserApcRoutine= (PIO_APC_ROUTINE) NULL; irp->RequestorMode = 0; irp->Tail.Overlay.Thread = PsGetCurrentThread(); irp->Tail.Overlay.OriginalFileObject = pFileObject; irp->Flags = IRP_BUFFERED_IO; irpSp = IoGetNextIrpStackLocation( irp ); irpSp->MajorFunction = IRP_MJ_SET_INFORMATION; irpSp->FileObject = pFileObject; irpSp->DeviceObject = pDeviceObject; irp->UserBuffer = NULL; irp->AssociatedIrp.SystemBuffer = NULL; irp->MdlAddress = (PMDL) NULL; __try { irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithQuota( NonPagedPool, Length ); RtlCopyMemory( irp->AssociatedIrp.SystemBuffer, &disp, Length ); } __except(EXCEPTION_EXECUTE_HANDLER) { // // An exception was incurred while allocating the intermediary // system buffer or while copying the caller's data into the // buffer. Cleanup and return an appropriate error status code. // IopExceptionCleanup( pFileObject, irp, (PKEVENT) NULL, &event ); return GetExceptionCode(); } irp->Flags |= IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_DEFER_IO_COMPLETION; irpSp->Parameters.SetFile.DeleteHandle = hFile; irpSp->Parameters.SetFile.Length = Length; irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation; irpSp->Control = 0xE0; irpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)Io_Completion_Routine; if (rc == STATUS_PENDING) { rc = KeWaitForSingleObject( &event, Executive, 0, 1, 0); } krResult = TRUE; Exit0: return krResult; } 

原理:
该IRP最后会调用Ntfs内的NtfsSetDispositionInfo函数或Fastfat内的FatSetPositionInfo函数(这区别于你的硬盘分区是什么文件系统),而这两个函数都会调用Ntoskrnl内的MmFlushImageSection函数,由于我们 hook了这两驱动内的MmFlushImageSection调用,所以当它自己发送IRP时,Hook_MmFlushImageSection就能截获请求,然后在该函数内判断SectionObjectPointer参数是否等于需要删除文件的SectionObjectPointer,如果相等则调用原来的MmFlushImageSection并返回True(返回True表示正在被操作的FileObject的Section不存在或没有被Map进内存),如果不相等,则返回原来的MmFlushImageSection的调用结果。
                
后记:
    自己构造IRP直接与FSD通信已经是老生常谈的话题了,有兴趣的朋友可以网上找找。

你可能感兴趣的:(删除运行中程序)