R3 HOOK NtDeleteFile 做文件保护

原创
2012/11/30 17:02
阅读数 682

   下面的程序保护了 所有路径中带 log 的文件 。。。。

   允许在沙盘 sandboxie 中的 。。

 

#include <windows.h>
typedef unsigned long * ULONG_PTR;
typedef LONG NTSTATUS, *PNTSTATUS;
#define STATUS_CANNOT_DELETE             ((NTSTATUS)0xC0000121L)
#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004L)

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 enum _OBJECT_INFORMATION_CLASS {
	ObjectBasicInformation, 
		ObjectNameInformation,
		ObjectTypeInformation,
		ObjectAllInformation,
		ObjectDataInformation	
} OBJECT_INFORMATION_CLASS, *POBJECT_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;

typedef struct _OBJECT_NAME_INFORMATION {
	UNICODE_STRING Name;
	WCHAR NameBuffer[0];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;

void *(__stdcall *pf_SbieDll_Hook)(const char *ApiName, void *ApiFunc, void *NewFunc);

NTSTATUS (__stdcall *pf_NtQueryObject)(
									   IN HANDLE ObjectHandle,
									   IN OBJECT_INFORMATION_CLASS ObjectInformationClass, 
									   OUT PVOID ObjectInformation, 
									   IN ULONG Length, 
									   OUT PULONG ResultLength ); 

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)
{
	OBJECT_NAME_INFORMATION *pinfo = NULL;
	ULONG  nRetSize;
	ULONG  len;
	NTSTATUS ret = 0;
	WCHAR *buff;
	int i = 0;

	if(ObjectAttributes->ObjectName && ObjectAttributes->ObjectName->Length > 1)
	{
		//伤不起 ~~~
		buff = (WCHAR *)malloc(ObjectAttributes->ObjectName->Length+1);
		memcpy(buff,ObjectAttributes->ObjectName->Buffer,ObjectAttributes->ObjectName->Length);
		buff[ObjectAttributes->ObjectName->Length] = 0;
		if(wcsstr(pinfo->Name.Buffer,L"log"))
		{
			free(buff);
			return STATUS_CANNOT_DELETE;  //拒绝访问 
		}
		free(buff);
	}
	else
	{
		//使用的是文件的句柄
		ret = pf_NtQueryObject(ObjectAttributes->RootDirectory,ObjectNameInformation,pinfo,0,&nRetSize);
		if ( STATUS_INFO_LENGTH_MISMATCH == ret )
		{
			for (i = 0 ;i< 10;i++)//try 10 times
			{
				pinfo = (OBJECT_NAME_INFORMATION *)malloc(nRetSize);
				ret = pf_NtQueryObject(ObjectAttributes->RootDirectory,ObjectNameInformation,pinfo,nRetSize,&nRetSize);
				if(STATUS_SUCCESS == ret)
				{
					if(pinfo->Name.Buffer)
					{
						if(wcsstr(pinfo->Name.Buffer,L"log"))
						{
							free(pinfo);
							return STATUS_CANNOT_DELETE;  //拒绝访问 
						}
					}
					break;
				}
				if(STATUS_INFO_LENGTH_MISMATCH == ret)
				{
					free(pinfo);
					pinfo = NULL;
                }
				else
					break;
			}
			if(pinfo)
			{
				free(pinfo);
				pinfo = NULL;
			}
		}
	}
	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_NtQueryObject = (NTSTATUS (__stdcall *)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG))GetProcAddress(LoadLibrary("ntdll.dll"),"NtQueryObject");
	pf_SbieDll_Hook = (void *(__stdcall *)(const char *, void *, void *)) GetProcAddress(hSbieDll, "SbieDll_Hook");
	if(NULL == Real_NtDeleteFile || NULL == Real_NtSetInformationFile || NULL == pf_SbieDll_Hook || NULL == pf_NtQueryObject)
	{
		// 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;
}

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部