日常中,我们用一些anti-virus的时候可能发现这样一个问题,几乎有点意思的病毒+木马你都无法成功把他清除掉.不是因为杀毒软件产商没能力,而是这个方案对于一个产品来讲实在有些烂了,今天我的这篇blog要讲的就是这个话题.
先看一下ring3的方法吧
void Cxxx::FileDelete(CString FilePath)
{
BOOL bRet = SetFileAttributes(FilePath,FILE_ATTRIBUTE_ARCHIVE);// 设置目标程序为存档属性
// 在临时目录产生产生两个随机的文件
CString strReplaceFile[2];
char szWinDir[256] = {0};
::GetTempPath(256,szWinDir);
szWinDir[strlen(szWinDir)] = '\\';
for(int i = 0; i < 2; i ++)
{
char szTemp[256] = {0};
GetTempFileName(szWinDir,_T ("♂"),0,szTemp);
strReplaceFile[i] = szTemp;
HANDLE hFile = CreateFile(strReplaceFile[i],GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY,NULL);
if(hFile == (HANDLE)-1)
{
MessageBox(NULL,"文件粉碎失败!","文件操作",MB_OK);
return ;
}
::CloseHandle(hFile);
}
// 替换目标文件
typedef BOOL (__stdcall *PREPLACEFILE)(LPCTSTR lpReplacedFileName,LPCTSTR lpReplacementFileName,LPCTSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved);
HMODULE hKernel32 = GetModuleHandle("kernel32.dll");
ASSERT(hKernel32);
PREPLACEFILE pFnReplacefile = (PREPLACEFILE)GetProcAddress(hKernel32,"ReplaceFileA");
if(pFnReplacefile == NULL)
{
MessageBox(NULL,"您的系统不支持删除正在执行的文件!","文件操作",MB_OK);
// MessageBox(NULL,"删除文件失败!","文件操作",MB_OK);
return;
}
bRet = pFnReplacefile(FilePath,strReplaceFile[0],strReplaceFile[1],3,0,0);
if(!bRet)
{
// CString strError;
// strError.Format("%d删除文件失败",GetLastError());
// PrintLog(strError);
// MessageBox(NULL,strError,"文件操作",MB_OK);
return;
}
bRet = DeleteFile(FilePath);
if(!bRet)
{
MessageBox(NULL,"删除正在执行的文件失败!","文件操作",MB_OK);
return;
}
}
下面是ring0的方法.
BOOLEAN SKillDeleteFile(IN HANDLE FileHandle)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PFILE_OBJECT fileObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
KEVENT event;
FILE_DISPOSITION_INFORMATION FileInformation;
IO_STATUS_BLOCK ioStatus;
PIO_STACK_LOCATION irpSp;
ntStatus = ObReferenceObjectByHandle(FileHandle,
DELETE,
*IoFileObjectType,
KernelMode,
&fileObject,
NULL);
if (!NT_SUCCESS(ntStatus))
{
return FALSE;
}
DeviceObject = IoGetRelatedDeviceObject(fileObject);
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (Irp == NULL)
{
ObDereferenceObject(fileObject);
return FALSE;
}
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
FileInformation.DeleteFile = TRUE;
Irp->AssociatedIrp.SystemBuffer = &FileInformation;
Irp->UserEvent = &event;
Irp->UserIosb = &ioStatus;
Irp->Tail.Overlay.OriginalFileObject = fileObject;
Irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
Irp->RequestorMode = KernelMode;
irpSp = IoGetNextIrpStackLocation(Irp);
irpSp->MajorFunction = IRP_MJ_SET_INFORMATION;
irpSp->DeviceObject = DeviceObject;
irpSp->FileObject = fileObject;
irpSp->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
irpSp->Parameters.SetFile.FileInformationClass = FileDispositionInformation;
irpSp->Parameters.SetFile.FileObject = fileObject;
IoSetCompletionRoutine(
Irp,
SkillSetFileCompletion,
&event,
TRUE,
TRUE,
TRUE);
IoCallDriver(DeviceObject, Irp);
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
ObDereferenceObject(fileObject);
return TRUE;
}