zoukankan      html  css  js  c++  java
  • object hook实现禁止创建文件

    object hook实现禁止创建文件

    原理不说了,大伙都懂得..

    要解决的问题:
    1. 怎么在windbg中看到_OBJECT_TYPE和_OBJECT_TYPE_INITIALIZER结构的内容。
    2. 怎样得到pOldParseProcedure的地址
    3. 怎样改写((POBJECT_TYPE)*IoDeviceObjectType)->TypeInfo.ParseProcedure=pNewProcedure

    对于第一个问题:

    nt!_OBJECT_HEADER
       +0x000 PointerCount     : Int4B
       +0x004 HandleCount      : Int4B
       +0x004 NextToFree       : Ptr32 Void
       +0x008 Type             : Ptr32 _OBJECT_TYPE
       +0x00c NameInfoOffset   : UChar
       +0x00d HandleInfoOffset : UChar
       +0x00e QuotaInfoOffset  : UChar
       +0x00f Flags            : UChar
       +0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
       +0x010 QuotaBlockCharged : Ptr32 Void
       +0x014 SecurityDescriptor : Ptr32 Void
       +0x018 Body             : _QUAD

    lkd> dt _OBJECT_TYPE
    nt!_OBJECT_TYPE
       +0x000 Mutex            : _ERESOURCE
       +0x038 TypeList         : _LIST_ENTRY
       +0x040 Name             : _UNICODE_STRING
       +0x048 DefaultObject    : Ptr32 Void
       +0x04c Index            : Uint4B
       +0x050 TotalNumberOfObjects : Uint4B
       +0x054 TotalNumberOfHandles : Uint4B
       +0x058 HighWaterNumberOfObjects : Uint4B
       +0x05c HighWaterNumberOfHandles : Uint4B
       +0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
       +0x0ac Key              : Uint4B
       +0x0b0 ObjectLocks      : [4] _ERESOURCE

    lkd> dt _OBJECT_TYPE_INITIALIZER
    nt!_OBJECT_TYPE_INITIALIZER
       +0x000 Length           : Uint2B
       +0x002 UseDefaultObject : UChar
       +0x003 CaseInsensitive  : UChar
       +0x004 InvalidAttributes : Uint4B
       +0x008 GenericMapping   : _GENERIC_MAPPING
       +0x018 ValidAccessMask  : Uint4B
       +0x01c SecurityRequired : UChar
       +0x01d MaintainHandleCount : UChar
       +0x01e MaintainTypeList : UChar
       +0x020 PoolType         : _POOL_TYPE
       +0x024 DefaultPagedPoolCharge : Uint4B
       +0x028 DefaultNonPagedPoolCharge : Uint4B
       +0x02c DumpProcedure    : Ptr32     void 
       +0x030 OpenProcedure    : Ptr32     long 
       +0x034 CloseProcedure   : Ptr32     void 
       +0x038 DeleteProcedure  : Ptr32     void 
       +0x03c ParseProcedure   : Ptr32     long 
       +0x040 SecurityProcedure : Ptr32     long 
       +0x044 QueryNameProcedure : Ptr32     long 
       +0x048 OkayToCloseProcedure : Ptr32     unsigned char 

    对于第二个问题:
    2. 怎样得到pOldParseProcedure的地址
    1. 打开一个文件得到文件句柄 ZwOpenFile
    2. 依据文件句柄得到文件 ObReferenceObjectByHandle得到pObject
    3. pObject是_OBJECT_HEADER 结构中Body的数值,如今要得到_OBJECT_HEADER 的地址,用宏CONTAINING_RECORD((o),OBJECT_HEADER,Body)
    4. POBJECT_HEADER结构的Type指向了一个OBJECT_TYPE( pType)
    4. OldParseProcedure = pType->TypeInfo.ParseProcedure就是要的结果

    整理一下结构间的关系:

    1. #define OBJECT_TO_OBJECT_HEADER(o) CONTAINING_RECORD((o),OBJECT_HEADER,Body)
    2. POBJECT_HEADER addrs=NULL;
    3. POBJECT_TYPE pType= NULL;

    1. addrs=OBJECT_TO_OBJECT_HEADER(pObject);//获取对象头

    1. pType=addrs->Type;//获取对象类型结构 object-10h
    2. OldParseProcedure = pType->TypeInfo.ParseProcedure;//获取服务函数原始地址OBJECT_TYPE+9C位置为打开

     typedef struct _OBJECT_HEADER {
    LONG PointerCount;
    union {
    LONG HandleCount;
    PSINGLE_LIST_ENTRY SEntry;
    };
    POBJECT_TYPE Type;
    UCHAR NameInfoOffset;
    UCHAR HandleInfoOffset;
    UCHAR QuotaInfoOffset;
    UCHAR Flags;
    union
    {
    POBJECT_CREATE_INFORMATION ObjectCreateInfo;
    PVOID QuotaBlockCharged;
    };
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    QUAD Body;
    } OBJECT_HEADER, *POBJECT_HEADER;

    pType的值为0x821ebe70
    lkd> dt _object_type 0x821ebe70
    nt!_OBJECT_TYPE
       +0x000 Mutex            : _ERESOURCE
       +0x038 TypeList         : _LIST_ENTRY [ 0x821ebea8 - 0x821ebea8 ]
       +0x040 Name             : _UNICODE_STRING "File"
       +0x048 DefaultObject    : 0x0000005c 
       +0x04c Index            : 0x1c
       +0x050 TotalNumberOfObjects : 0xcd6
       +0x054 TotalNumberOfHandles : 0x316
       +0x058 HighWaterNumberOfObjects : 0xd6e
       +0x05c HighWaterNumberOfHandles : 0x3ad
       +0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
       +0x0ac Key              : 0x656c6946
       +0x0b0 ObjectLocks      : [4] _ERESOURCE

    3. 怎样改写((POBJECT_TYPE)*IoDeviceObjectType)->TypeInfo.ParseProcedure=pNewProcedure
    关闭写保护
    HOOK
    打开写保护
    函数定义方法:
    NTSTATUS (*oldParseProcedure)(IN PVOID ParseObject,
        IN PVOID ObjectType,
        IN OUT PACCESS_STATE AccessState,
        IN KPROCESSOR_MODE AccessMode,
        IN ULONG Attributes,
        IN OUT PUNICODE_STRING CompleteName,
        IN OUT PUNICODE_STRING RemainingName,
        IN OUT PVOID Context OPTIONAL,
        IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
        OUT PVOID *Object);

    此时,就已经HOOK成功了


    解决完上面的困难,真正的代码来了
    .c
    //PVOID oldParseProcedure;
    //typedef int (*FP_CALC)(int, int);
    NTSTATUS (*oldParseProcedure)(IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object);
    VOID MyObjectHook()
    {
    UNICODE_STRING uFileName;
    OBJECT_ATTRIBUTES ob;
    NTSTATUS status;
    HANDLE hFile;
    IO_STATUS_BLOCK ioStaBlock;
    PVOID pObject;
    POBJECT_HEADER addr;
    POBJECT_TYPE pType;
    OBJECT_TYPE_INITIALIZER obTypeInit;
    KIRQL irql;
    dprintf("enter myObjectHook... ");
    DbgBreakPoint();
    RtlInitUnicodeString(&uFileName,L"\Device\HarddiskVolume1\123.txt");//这个文件必需存在
    InitializeObjectAttributes(&ob,&uFileName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,NULL, NULL);
    status = ZwOpenFile(&hFile,GENERIC_ALL,&ob,&ioStaBlock,0,FILE_NON_DIRECTORY_FILE);
    if (!NT_SUCCESS(status))
    {
    dprintf("ZwOpenFile error.. ");
    return ;
    }
    status = ObReferenceObjectByHandle(hFile,GENERIC_ALL,NULL,KernelMode,&pObject,NULL);
    if (!NT_SUCCESS(status))
    {
    dprintf("ObReferenceObjectByHandle:Object is Null ");
    return ;
    }
    dprintf("pObject is 0x%08X ",pObject);
    addr = OBJECT_TO_OBJECT_HEADER(pObject);
    dprintf("addr is 0x%08X ",addr); //这里是pObject-0x18的位置
    pType = addr->Type;
    dprintf("pType is 0x%08X ",pType);
    //oldParseProcedure = (PVOID)(pType->TypeInfo.ParseProcedure);
    oldParseProcedure = pType->TypeInfo.ParseProcedure;
    dprintf("OldParseProcedure addrs is %08X ",oldParseProcedure);
    //HOOK 一下下
    irql = WPOFF();
    pType->TypeInfo.ParseProcedure = NewParseProcedure;//hook
    WPON(irql);
    //关闭句柄
    ZwClose(hFile);
    }
    //OBJECT HOOK 函数
    NTSTATUS NewParseProcedure(IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object)
    {
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PVOID namePool;
    if (RemainingName->Buffer)
    {
    namePool = ExAllocatePool(NonPagedPool, RemainingName->Buffer+2);
    RtlZeroMemory(namePool, RemainingName->Buffer+2);
    if (namePool)
    {
    RtlCopyMemory(namePool, RemainingName->Buffer,RemainingName->Length);
    _wcsupr((wchar_t*)namePool);
    if (wcsstr(namePool, L"TEST.TXT"))
    {
    ExFreePool(namePool);
    return STATUS_ACCESS_DENIED;
    }
    }
    }
    return oldParseProcedure(ParseObject,
    ObjectType,
    AccessState,
    AccessMode,
    Attributes,
    CompleteName,
    RemainingName,
    Context,
    SecurityQos,
    *Object);
    }
    .h
    //object hook
    VOID MyObjectHook();
    #define OBJECT_TO_OBJECT_HEADER(o)
    CONTAINING_RECORD((o),OBJECT_HEADER,Body)
    typedef struct _OBJECT_HEADER {
    LONG PointerCount;
    union {
    LONG HandleCount;
    PSINGLE_LIST_ENTRY SEntry;
    };
    POBJECT_TYPE Type;
    UCHAR NameInfoOffset;
    UCHAR HandleInfoOffset;
    UCHAR QuotaInfoOffset;
    UCHAR Flags;
    union
    {
    PVOID ObjectCreateInfo;
    PVOID QuotaBlockCharged;
    };
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    QUAD Body;
    } OBJECT_HEADER, *POBJECT_HEADER;
    NTSTATUS NewParseProcedure(IN PVOID ParseObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING CompleteName,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *Object);
  • 相关阅读:
    DP -- 递推
    二分查找题
    动态规划
    二分专题
    并查集
    三分法
    二分法
    插入排序
    排序小结
    Go go.mod入门
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7262310.html
Copyright © 2011-2022 走看看