#ifndef CXX_PROTECTPROCESSX64_H
# include "ProtectProcessx64.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ntstrsafe.h>
#define TRACE ATLTRACE
//进程保护CallBackHandle
PVOID processCallBackHandle = NULL; //定义一个void*类型的变量,它将会作为ObRegisterCallbacks函数的第二个参数。
PEPROCESS parentsProtectedProcess; //被保护进程的父进程(来自该进程的处理,被排外)
//文件保护
PVOID fileCallBackHandle = NULL;
//驱动入口
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString)
{
DbgPrint("begin to load driver...\n");
KdPrint(("begin to load driver...\n"));
//OutputDebugString("begin to load driver...\n");
NTSTATUS status = STATUS_SUCCESS;
PLDR_DATA_TABLE_ENTRY64 ldr;
pDriverObj->DriverUnload = DriverUnload;
// 绕过MmVerifyCallbackFunction
ldr = (PLDR_DATA_TABLE_ENTRY64)pDriverObj->DriverSection;
ldr->Flags |= 0x20;
DbgPrint("begin to ProtectProcess...\n");
//保护线程回调
ProtectProcess(TRUE);
//保护文件
ProtectFileByObRegisterCallbacks();
return STATUS_SUCCESS;
}
#define MY_MAX_PATH 256
BOOLEAN UnicodeStringToChar(char* DestinationString, PUNICODE_STRING SourceString)
{
ANSI_STRING v1;
NTSTATUS Status;
char* v2 = NULL;
__try
{
Status = RtlUnicodeStringToAnsiString(&v1, SourceString, TRUE);
if (v1.Length < MY_MAX_PATH)
{
v2 = (PCHAR)v1.Buffer;
strcpy(DestinationString, _strupr(v2));
}
RtlFreeAnsiString(&v1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return FALSE;
}
return TRUE;
}
void MyUpper(char *s)
{
while((*s)!=0){
if((*s)>='a'&&(*s)<='z')
(*s)+=('A'-'a');
s++;
}
}
OB_PREOP_CALLBACK_STATUS FilePreCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
UNICODE_STRING uniDosName;
uniDosName.Length = 0;
ACCESS_MASK oldCreateDesiredAccess = 0;
ACCESS_MASK oldDuplicateDesiredAccess = 0;
//参数检查
if(NULL == OperationInformation)
return OB_PREOP_SUCCESS;
PFILE_OBJECT FileObject = (PFILE_OBJECT)OperationInformation->Object;
HANDLE CurrentProcessId = PsGetCurrentProcessId();
UNREFERENCED_PARAMETER(RegistrationContext);
//有效性检查
if(NULL == FileObject)
return OB_PREOP_SUCCESS;
//(1)屏蔽非IoFileObjectType类型的处理
if( OperationInformation->ObjectType!=*IoFileObjectType)
{
return OB_PREOP_SUCCESS;
}
//(2)过滤无效指针
if( FileObject->FileName.Buffer==NULL ||
!MmIsAddressValid(FileObject->FileName.Buffer) ||
FileObject->DeviceObject==NULL ||
!MmIsAddressValid(FileObject->DeviceObject) )
{
return OB_PREOP_SUCCESS;
}
//(3)过滤无效路径, 否则使用RtlVolumeDeviceToDosName获取盘符会蓝屏
/**/
if( !_wcsicmp(FileObject->FileName.Buffer,L"\\Endpoint") ||
!_wcsicmp(FileObject->FileName.Buffer,L"?") ||
!_wcsicmp(FileObject->FileName.Buffer,L"\\.\\.") ||
!_wcsicmp(FileObject->FileName.Buffer,L"\\"))
return OB_PREOP_SUCCESS;
//被保护的4个文件
UNICODE_STRING UnicodeString1;
RtlInitUnicodeString(&UnicodeString1, L"audit_auth.conf");
UNICODE_STRING UnicodeString2;
RtlInitUnicodeString(&UnicodeString2, L"ignsql.cfg");
UNICODE_STRING UnicodeString3;
RtlInitUnicodeString(&UnicodeString3, L"auditflow.ini");
UNICODE_STRING UnicodeString4;
RtlInitUnicodeString(&UnicodeString4, L"DBLocalInfo.ini");
//获取操作文件char*名称
char cbFileName[1024] = {0};
UnicodeStringToChar(cbFileName, &FileObject->FileName);
MyUpper(cbFileName);
//(4)禁止删除下列文件, 经验证到这一步是有效的(非长时间,但区分了大小写)
/* wcsstr容易造成蓝屏,应该使用RtlEqualUnicodeString
if(wcsstr(_wcslwr(FileObject->FileName.Buffer),L"audit_auth.conf") || wcsstr(_wcslwr(FileObject->FileName.Buffer),L"ignsql.cfg") ||
wcsstr(_wcslwr(FileObject->FileName.Buffer),L"auditflow.ini") || wcsstr(_wcslwr(FileObject->FileName.Buffer),L"DBLocalInfo.ini"))
*/
/* StrStrIW就是款字符的、StrStrIA是非宽字符的忽略大小写查找 不能用相等
if(RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString1,1) || RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString2, 1) ||
RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString3,1) || RtlEqualUnicodeString(&FileObject->FileName, &UnicodeString4, 1))
*/
if(strstr(cbFileName, "AUDIT_AUTH.CONF") || strstr(cbFileName, "IGNSQL.CFG") ||
strstr(cbFileName, "AUDITFLOW.INI") || strstr(cbFileName, "DBLOCALINFO.INI"))
{
oldCreateDesiredAccess = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
oldDuplicateDesiredAccess = OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess;
if (FileObject->DeleteAccess==TRUE/*||FileObject->WriteAccess==TRUE*/)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess=0;
}
if(OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
{
//OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess=0;
}
/*
RtlVolumeDeviceToDosName(FileObject->DeviceObject, &uniDosName);
DbgPrint("PID : %ld Drive: %wZ, Path: %wZ, fullPath: %wZ\r\n", (ULONG64)CurrentProcessId, &uniDosName, FileObject->FileName, &uniFilePath);
//PID : 996 Drive: C:, Path: \Windows\System32\net1.exe, fullPath: C:\Windows\System32\net1.exe
DbgPrint("Operation=%d, DeleteAccess=%d, WriteAccess=%d, oldCreateDesiredAccess=%d, newCreateDesiredAcces=%d, oldDuplicateDesiredAccess=%d, newDuplicateDesiredAcces=%d\r\n",
OperationInformation->Operation, FileObject->DeleteAccess, FileObject->WriteAccess,
oldCreateDesiredAccess, OperationInformation->Parameters->CreateHandleInformation.DesiredAccess,
oldDuplicateDesiredAccess, OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess);
*/
}
}
return OB_PREOP_SUCCESS;
}
VOID EnableObType(POBJECT_TYPE ObjectType)
{
POBJECT_TYPE_TEMP ObjectTypeTemp = (POBJECT_TYPE_TEMP)ObjectType;
ObjectTypeTemp->TypeInfo.SupportsObjectCallbacks = 1; //只适用于Win7 x86,不适用于Win8否则会触发PatchGuard
}
NTSTATUS ProtectFileByObRegisterCallbacks()
{
OB_CALLBACK_REGISTRATION CallBackReg;
OB_OPERATION_REGISTRATION OperationReg;
NTSTATUS Status;
DbgPrint("ProtectFileByObRegisterCallbacks begin");
EnableObType(*IoFileObjectType); //开启文件对象回调,必须执行
memset(&CallBackReg, 0, sizeof(OB_CALLBACK_REGISTRATION));
CallBackReg.Version = ObGetFilterVersion();
CallBackReg.OperationRegistrationCount = 1;
CallBackReg.RegistrationContext = NULL;
RtlInitUnicodeString(&CallBackReg.Altitude, L"321000");
memset(&OperationReg, 0, sizeof(OB_OPERATION_REGISTRATION)); //初始化结构体变量
OperationReg.ObjectType = IoFileObjectType;
OperationReg.Operations = OB_OPERATION_HANDLE_CREATE|OB_OPERATION_HANDLE_DUPLICATE;
OperationReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&FilePreCallBack; //在这里注册一个回调函数指针
CallBackReg.OperationRegistration = &OperationReg; //注意这一条语句 将结构体信息放入大结构体
Status = ObRegisterCallbacks(&CallBackReg, &fileCallBackHandle);
if (!NT_SUCCESS(Status))
{
Status = STATUS_UNSUCCESSFUL;
}
else
{
Status = STATUS_SUCCESS;
}
return Status;
}
NTSTATUS ProtectProcess(BOOLEAN Enable)
{
OB_CALLBACK_REGISTRATION obReg;
OB_OPERATION_REGISTRATION opReg;
memset(&obReg, 0, sizeof(obReg));
obReg.Version = ObGetFilterVersion();
obReg.OperationRegistrationCount = 1;
obReg.RegistrationContext = NULL;
RtlInitUnicodeString(&obReg.Altitude, L