美文网首页
Win7 x64下进程保护与文件保护(ObRegisterCal

Win7 x64下进程保护与文件保护(ObRegisterCal

作者: Bug2Coder | 来源:发表于2019-09-17 09:48 被阅读0次

C驱动:进程保护与文件保护

编译步骤

1、编译工具:Visual Studio、DDK
2、建立一个空白驱动项目
适配平台:
任务管理器进程保护:Win7
文件保护:Win7,Win10

1、任务管理器进程保护

#ifndef CXX_PROTECTPROCESSX64_H
#define CXX_PROTECTPROCESSX64_H

#include <ntifs.h>

#define PROCESS_TERMINATE         0x0001  
#define PROCESS_VM_OPERATION      0x0008  
#define PROCESS_VM_READ           0x0010  
#define PROCESS_VM_WRITE          0x0020  

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString);

VOID DriverUnload(IN PDRIVER_OBJECT pDriverObj);

typedef struct _LDR_DATA_TABLE_ENTRY64
{
    LIST_ENTRY64    InLoadOrderLinks;
    LIST_ENTRY64    InMemoryOrderLinks;
    LIST_ENTRY64    InInitializationOrderLinks;
    PVOID            DllBase;
    PVOID            EntryPoint;
    ULONG            SizeOfImage;
    UNICODE_STRING    FullDllName;
    UNICODE_STRING     BaseDllName;
    ULONG            Flags;
    USHORT            LoadCount;
    USHORT            TlsIndex;
    PVOID            SectionPointer;
    ULONG            CheckSum;
    PVOID            LoadedImports;
    PVOID            EntryPointActivationContext;
    PVOID            PatchInformation;
    LIST_ENTRY64    ForwarderLinks;
    LIST_ENTRY64    ServiceTagLinks;
    LIST_ENTRY64    StaticLinks;
    PVOID            ContextInformation;
    ULONG64            OriginalBase;
    LARGE_INTEGER    LoadTime;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;

extern 
    UCHAR *
    PsGetProcessImageFileName(
    __in PEPROCESS Process
    );
char*
    GetProcessImageNameByProcessID(ULONG ulProcessID);

NTSTATUS ProtectProcess(BOOLEAN Enable);

OB_PREOP_CALLBACK_STATUS 
    preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation);

#endif    







#ifndef CXX_PROTECTPROCESSX64_H
#    include "ProtectProcessx64.h"
#endif


PVOID obHandle;//定义一个void*类型的变量,它将会作为ObRegisterCallbacks函数的第二个参数。

NTSTATUS
DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString)
{
    NTSTATUS status = STATUS_SUCCESS;
    PLDR_DATA_TABLE_ENTRY64 ldr;

    pDriverObj->DriverUnload = DriverUnload;
    // 绕过MmVerifyCallbackFunction。
    ldr = (PLDR_DATA_TABLE_ENTRY64)pDriverObj->DriverSection;
    ldr->Flags |= 0x20;

    ProtectProcess(TRUE);

    return STATUS_SUCCESS;
}



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"321000");
    memset(&opReg, 0, sizeof(opReg)); //初始化结构体变量

    //下面请注意这个结构体的成员字段的设置
    opReg.ObjectType = PsProcessType;
    opReg.Operations = OB_OPERATION_HANDLE_CREATE|OB_OPERATION_HANDLE_DUPLICATE; 

    opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall; //在这里注册一个回调函数指针

    obReg.OperationRegistration = &opReg; //注意这一条语句

    return ObRegisterCallbacks(&obReg, &obHandle); //在这里注册回调函数
}


OB_PREOP_CALLBACK_STATUS 
    preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation)
{
    HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object);
    char szProcName[16]={0};
    UNREFERENCED_PARAMETER(RegistrationContext);
    strcpy(szProcName,GetProcessImageNameByProcessID((ULONG)pid));
    if( !_stricmp(szProcName,"calc.exe") )
    {
        if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
        {
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE) == PROCESS_TERMINATE)
            {
                //Terminate the process, such as by calling the user-mode TerminateProcess routine..
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
            }
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_OPERATION) == PROCESS_VM_OPERATION)
            {
                //Modify the address space of the process, such as by calling the user-mode WriteProcessMemory and VirtualProtectEx routines.
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION;
            }
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_READ) == PROCESS_VM_READ)
            {
                //Read to the address space of the process, such as by calling the user-mode ReadProcessMemory routine.
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ;
            }
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_WRITE) == PROCESS_VM_WRITE)
            {
                //Write to the address space of the process, such as by calling the user-mode WriteProcessMemory routine.
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_WRITE;
            }
        }
    }
    return OB_PREOP_SUCCESS;
}


char*
    GetProcessImageNameByProcessID(ULONG ulProcessID)
{
    NTSTATUS  Status;
    PEPROCESS  EProcess = NULL;

    
    Status = PsLookupProcessByProcessId((HANDLE)ulProcessID,&EProcess);    //EPROCESS

    //通过句柄获取EProcess
    if (!NT_SUCCESS(Status))
    {
        return FALSE;
    }
    ObDereferenceObject(EProcess);
    //通过EProcess获得进程名称
    return (char*)PsGetProcessImageFileName(EProcess);     

}



VOID
DriverUnload(IN PDRIVER_OBJECT pDriverObj)
{    
    UNREFERENCED_PARAMETER(pDriverObj);
    DbgPrint("driver unloading...\n");

    ObUnRegisterCallbacks(obHandle); //obHandle是上面定义的 PVOID obHandle;
}

2、文件保护

#ifndef CXX_FILEPROTECTX64_H
#define CXX_FILEPROTECTX64_H
#include <ntifs.h>
#include <devioctl.h>
NTSTATUS
    DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath);
VOID UnloadDriver(PDRIVER_OBJECT  DriverObject);
typedef struct _LDR_DATA_TABLE_ENTRY64
{
    LIST_ENTRY64    InLoadOrderLinks;
    LIST_ENTRY64    InMemoryOrderLinks;
    LIST_ENTRY64    InInitializationOrderLinks;
    PVOID            DllBase;
    PVOID            EntryPoint;
    ULONG            SizeOfImage;
    UNICODE_STRING    FullDllName;
    UNICODE_STRING     BaseDllName;
    ULONG            Flags;
    USHORT            LoadCount;
    USHORT            TlsIndex;
    PVOID            SectionPointer;
    ULONG            CheckSum;
    PVOID            LoadedImports;
    PVOID            EntryPointActivationContext;
    PVOID            PatchInformation;
    LIST_ENTRY64    ForwarderLinks;
    LIST_ENTRY64    ServiceTagLinks;
    LIST_ENTRY64    StaticLinks;
    PVOID            ContextInformation;
    ULONG64            OriginalBase;
    LARGE_INTEGER    LoadTime;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;

typedef struct _OBJECT_TYPE_INITIALIZER                                                                                                                                        
{
    UINT16       Length;
    union                                                                                                                                                                       
    {
        UINT8        ObjectTypeFlags;
        struct                                                                                                                                                                
        {
            UINT8        CaseInsensitive : 1;                                                                                     UINT8        UnnamedObjectsOnly : 1;                                                                                  UINT8        UseDefaultObject : 1;                                                                                    UINT8        SecurityRequired : 1;                                                                                    UINT8        MaintainHandleCount : 1;                                                                                 UINT8        MaintainTypeList : 1;                                                                                    UINT8        SupportsObjectCallbacks : 1;                                                                                                                         
        };
    };
    ULONG32      ObjectTypeCode;
    ULONG32      InvalidAttributes;
    struct _GENERIC_MAPPING GenericMapping;                                                                                                                                     
    ULONG32      ValidAccessMask;
    ULONG32      RetainAccess;
    enum _POOL_TYPE PoolType;
    ULONG32      DefaultPagedPoolCharge;
    ULONG32      DefaultNonPagedPoolCharge;
    PVOID        DumpProcedure;
    PVOID        OpenProcedure;
    PVOID         CloseProcedure;
    PVOID         DeleteProcedure;
    PVOID         ParseProcedure;
    PVOID        SecurityProcedure;
    PVOID         QueryNameProcedure;
    PVOID         OkayToCloseProcedure;
}OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

typedef struct _OBJECT_TYPE_TEMP                   
{
    struct _LIST_ENTRY TypeList;             
    struct _UNICODE_STRING Name;             
    VOID*        DefaultObject;
    UINT8        Index;
    UINT8        _PADDING0_[0x3];
    ULONG32      TotalNumberOfObjects;
    ULONG32      TotalNumberOfHandles;
    ULONG32      HighWaterNumberOfObjects;
    ULONG32      HighWaterNumberOfHandles;
    UINT8        _PADDING1_[0x4];
    struct _OBJECT_TYPE_INITIALIZER TypeInfo; 
    ULONG64 TypeLock;          
    ULONG32      Key;
    UINT8        _PADDING2_[0x4];
    struct _LIST_ENTRY CallbackList;        
}OBJECT_TYPE_TEMP, *POBJECT_TYPE_TEMP;

VOID EnableObType(POBJECT_TYPE ObjectType);
UNICODE_STRING  GetFilePathByFileObject(PVOID FileObject);
OB_PREOP_CALLBACK_STATUS PreCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation);
NTSTATUS ProtectFileByObRegisterCallbacks();
#endif    


#ifndef CXX_FILEPROTECTX64_H
#    include "FileProtectX64.h"
#endif
PVOID  CallBackHandle = NULL;
NTSTATUS
    DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath)
{    

    PLDR_DATA_TABLE_ENTRY64 ldr;
    DriverObject->DriverUnload = UnloadDriver;
    ldr = (PLDR_DATA_TABLE_ENTRY64)DriverObject->DriverSection;
    ldr->Flags |= 0x20;
    ProtectFileByObRegisterCallbacks();
    return STATUS_SUCCESS;
}
NTSTATUS ProtectFileByObRegisterCallbacks()
{
    OB_CALLBACK_REGISTRATION  CallBackReg;
    OB_OPERATION_REGISTRATION OperationReg;
    NTSTATUS  Status;
    
    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)&PreCallBack; //在这里注册一个回调函数指针
    CallBackReg.OperationRegistration = &OperationReg; //注意这一条语句   将结构体信息放入大结构体
    Status = ObRegisterCallbacks(&CallBackReg, &CallBackHandle);     
    if (!NT_SUCCESS(Status)) 
    {
        Status = STATUS_UNSUCCESSFUL;
    } 
    else
    {
        Status = STATUS_SUCCESS;
    }
    return Status; 
}

OB_PREOP_CALLBACK_STATUS PreCallBack(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
    UNICODE_STRING uniDosName;
    UNICODE_STRING uniFilePath;
    PFILE_OBJECT FileObject = (PFILE_OBJECT)OperationInformation->Object;
    HANDLE CurrentProcessId = PsGetCurrentProcessId();
    if( OperationInformation->ObjectType!=*IoFileObjectType)
    {
        return OB_PREOP_SUCCESS;
    }
    //过滤无效指针
    if(    FileObject->FileName.Buffer==NULL                || 
        !MmIsAddressValid(FileObject->FileName.Buffer)    ||
        FileObject->DeviceObject==NULL                    ||
        !MmIsAddressValid(FileObject->DeviceObject)        )
    {
        return OB_PREOP_SUCCESS;
    }
    uniFilePath = GetFilePathByFileObject(FileObject);
    if (uniFilePath.Buffer==NULL||uniFilePath.Length==0)
    {
        return OB_PREOP_SUCCESS;
    }
    if(wcsstr(uniFilePath.Buffer,L"D:\\Test.txt"))
    {
        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 File : %wZ  %wZ\r\n", (ULONG64)CurrentProcessId, &uniDosName, &uniFilePath);
    return OB_PREOP_SUCCESS;
}
UNICODE_STRING  GetFilePathByFileObject(PVOID FileObject)
{
    POBJECT_NAME_INFORMATION ObjetNameInfor;  
    if (NT_SUCCESS(IoQueryFileDosDeviceName((PFILE_OBJECT)FileObject, &ObjetNameInfor)))  
    {  
        return ObjetNameInfor->Name;  
    }  
}
VOID EnableObType(POBJECT_TYPE ObjectType)  
{
    POBJECT_TYPE_TEMP  ObjectTypeTemp = (POBJECT_TYPE_TEMP)ObjectType;
    ObjectTypeTemp->TypeInfo.SupportsObjectCallbacks = 1;
}
VOID UnloadDriver(PDRIVER_OBJECT  DriverObject)
{
    if (CallBackHandle!=NULL)
    {
        ObUnRegisterCallbacks(CallBackHandle);
    }
    DbgPrint("UnloadDriver\r\n");
}

相关文章

网友评论

      本文标题:Win7 x64下进程保护与文件保护(ObRegisterCal

      本文链接:https://www.haomeiwen.com/subject/brbqyctx.html