DeleteFile 到底层是调用的 NtSetInformationFile 但是实际测试发现调用完了这个紧接着又会调用 NtDeleteFile 来删除文件 。。。
所以 HOOk 掉这个函数就行了。。。
我的程序是运行在沙盘里的 不知道外面什么情况。。
#include <windows.h> typedef unsigned long * ULONG_PTR; typedef LONG NTSTATUS, *PNTSTATUS; #define STATUS_CANNOT_DELETE ((NTSTATUS)0xC0000121L) typedef enum _FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, FileFullDirectoryInformation, FileBothDirectoryInformation, FileBasicInformation, FileStandardInformation, FileInternalInformation, FileEaInformation, FileAccessInformation, FileNameInformation, FileRenameInformation, FileLinkInformation, FileNamesInformation, FileDispositionInformation, FilePositionInformation, FileFullEaInformation, FileModeInformation, FileAlignmentInformation, FileAllInformation, FileAllocationInformation, FileEndOfFileInformation, FileAlternateNameInformation, FileStreamInformation, FilePipeInformation, FilePipeLocalInformation, FilePipeRemoteInformation, FileMailslotQueryInformation, FileMailslotSetInformation, FileCompressionInformation, FileObjectIdInformation, FileCompletionInformation, FileMoveClusterInformation, FileQuotaInformation, FileReparsePointInformation, FileNetworkOpenInformation, FileAttributeTagInformation, FileTrackingInformation, FileIdBothDirectoryInformation, FileIdFullDirectoryInformation, FileValidDataLengthInformation, FileShortNameInformation, FileIoCompletionNotificationInformation, FileIoStatusBlockRangeInformation, FileIoPriorityHintInformation, FileSfioReserveInformation, FileSfioVolumeInformation, FileHardLinkInformation, FileProcessIdsUsingFileInformation, FileNormalizedNameInformation, FileNetworkPhysicalNameInformation, FileIdGlobalTxDirectoryInformation, FileIsRemoteDeviceInformation, FileAttributeCacheInformation, FileNumaNodeInformation, FileStandardLinkInformation, FileRemoteProtocolInformation, FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; typedef struct _FILE_DISPOSITION_INFORMATION { BOOLEAN DeleteFile; } FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING; // // Valid values for the Attributes field // #define OBJ_INHERIT 0x00000002L #define OBJ_PERMANENT 0x00000010L #define OBJ_EXCLUSIVE 0x00000020L #define OBJ_CASE_INSENSITIVE 0x00000040L #define OBJ_OPENIF 0x00000080L #define OBJ_OPENLINK 0x00000100L #define OBJ_KERNEL_HANDLE 0x00000200L #define OBJ_FORCE_ACCESS_CHECK 0x00000400L #define OBJ_VALID_ATTRIBUTES 0x000007F2L typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; void *(__stdcall *pf_SbieDll_Hook)(const char *ApiName, void *ApiFunc, void *NewFunc); NTSTATUS (__stdcall *Real_NtSetInformationFile)( HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass ); NTSTATUS (__stdcall *Real_NtDeleteFile)(POBJECT_ATTRIBUTES ObjectAttributes); NTSTATUS __stdcall Hook_NtSetInformationFile( HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass ) { if(FileInformationClass == FileDispositionInformation && *(unsigned char *)FileInformation == 1) { //尝试删除文件 OutputDebugStringA("--> Hook_NtSetInformationFile"); } return Real_NtSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass); } NTSTATUS __stdcall Hook_NtDeleteFile(POBJECT_ATTRIBUTES ObjectAttributes) { return STATUS_CANNOT_DELETE; // return Real_NtDeleteFile(ObjectAttributes); } __declspec(dllexport) void __stdcall InjectDllMain(HINSTANCE hSbieDll, ULONG_PTR UnusedParameter) { Real_NtSetInformationFile = (NTSTATUS (__stdcall *)(HANDLE ,PIO_STATUS_BLOCK ,PVOID ,ULONG ,FILE_INFORMATION_CLASS ))GetProcAddress(LoadLibrary("ntdll.dll"),"NtSetInformationFile"); Real_NtDeleteFile = (NTSTATUS (__stdcall *)(POBJECT_ATTRIBUTES)) GetProcAddress(LoadLibrary("ntdll.dll"),"NtDeleteFile"); pf_SbieDll_Hook = (void *(__stdcall *)(const char *, void *, void *)) GetProcAddress(hSbieDll, "SbieDll_Hook"); if(NULL == Real_NtDeleteFile || NULL == Real_NtSetInformationFile || NULL == pf_SbieDll_Hook) { // failed ... } else { //start hook Real_NtSetInformationFile = pf_SbieDll_Hook("NtSetInformationFile",Real_NtSetInformationFile,Hook_NtSetInformationFile); Real_NtDeleteFile = pf_SbieDll_Hook("NtDeleteFile",Real_NtDeleteFile,Hook_NtDeleteFile); } } BOOL __stdcall DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: { } break; case DLL_PROCESS_DETACH: { } break; default: break; } return TRUE; }