ObjectHook

转载自:http://mzf2008.blog.163.com/blog/static/35599786201152045341614/


其实这东西很多大牛多玩腻了的东西,看下论坛上比较少这类的,就来献献丑,科普一下 大牛们直接

可以飘过,这东西主要是自我复习一下OBJECT的一些知识,技术这东西久了不弄容易忘记,所以
拿出来跟和我一样菜的菜鸟们分享一下。如果有不对的地方欢迎大家指正,这样对于自己也进步得
快点,多多交流,互相学习,水平才能提高得快。
   第一我们先看下OBJECT的组成 主要是3部分 如下图
              
         |---------| 
         | 附加信息| --->  主要的几个结构是 OBJECT_HEADER_CREATOR_INFO 创建信息 
                              OBJECT_HEADER_NAME_INFO 这里面有对象名等主要信息 
                              OBJECT_HEADER_HANDLE_INFO 一些句柄信息          
         |_________|                 
         |         | 
         | 对象头  |---->     一个重要的结构   OBJECT_HEADER              
         |_________|  
         |         | 
         | OBJECT  | --->       对象                
         |_________|  
   我们主要看下OBJECT_HEADER这个数据结构几个重要我成员我注释出来

typedef struct _OBJECT_HEADER { 
  LONG PointerCount; 
  union { 
    LONG HandleCount; 
    PSINGLE_LIST_ENTRY SEntry; 
  }; 
  POBJECT_TYPE Type; //这个很重要HOOK就靠它,对象类型结构也是一个对象,TYPE它是系统第一个创建出来的对象类型 
  UCHAR NameInfoOffset; //OBJECT_HEADER_NAME_INFO 偏移
  UCHAR HandleInfoOffset; //OBJECT_HEADER_HANDLE_INFO 偏移
  UCHAR QuotaInfoOffset; 
  UCHAR Flags; 
  union 
  { 
    POBJECT_CREATE_INFORMATION ObjectCreateInfo; 
    PVOID QuotaBlockCharged; 
  };
  
  PSECURITY_DESCRIPTOR SecurityDescriptor; 
  QUAD Body;//对象本身 
} OBJECT_HEADER, *POBJECT_HEADER; 
对象类型结构
typedef struct _OBJECT_TYPE { 
  ERESOURCE Mutex; 
  LIST_ENTRY TypeList; //队列
  UNICODE_STRING Name; 
  PVOID DefaultObject; 
  ULONG Index; 
  ULONG TotalNumberOfObjects; 
  ULONG TotalNumberOfHandles; 
  ULONG HighWaterNumberOfObjects; 
  ULONG HighWaterNumberOfHandles; 
  OBJECT_TYPE_INITIALIZER TypeInfo; //这个很重要,下面讲这个结构
#ifdef POOL_TAGGING 
  ULONG Key; 
#endif 
} OBJECT_TYPE, *POBJECT_TYPE;
对象类型结构主要是创建对象类型比如*IoFileObjectType,*PsProcessType,*PsThreadType这些类型
系统初始化的时候第一个创建的对象类型结构就是TYPE类型结构生成对象目录\ObjectTypes 其它后面的
比如文件对象类型就挂在\ObjectTypes\File 再比如\ObjectTypes\Device
说白点就是你要生成对象就会创建(指定)相对应的对象类型结构
 最重要的一个数据结构
typedef struct _OBJECT_TYPE_INITIALIZER {
  USHORT Length;
  BOOLEAN UseDefaultObject;
  BOOLEAN CaseInsensitive;
  ULONG InvalidAttributes;
  GENERIC_MAPPING GenericMapping;
  ULONG ValidAccessMask;
  BOOLEAN SecurityRequired;
  BOOLEAN MaintainHandleCount;
  BOOLEAN MaintainTypeList;
  POOL_TYPE PoolType;
  ULONG DefaultPagedPoolCharge;
  ULONG DefaultNonPagedPoolCharge;
  PVOID DumpProcedure;/*
  PVOID OpenProcedure;        这几个函数指针就是我们最需要的
  PVOID CloseProcedure;       这些函数都是决定你的对象的的一些
  PVOID DeleteProcedure;      操作或者叫方法,比如打开 创建 删除
  PVOID ParseProcedure;       不同的对象类型(OBJECT_TYPE)操作也不同
  PVOID SecurityProcedure;    所以要清楚的知道(OBJECT_TYPE)对象是什么类型
  PVOID QueryNameProcedure;   如果没有配置系统调用的对象类型 都是用NtOpenFile
  PVOID OkayToCloseProcedure;*/
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;


这些方法何时被调用呢,我举个例子
当你调用NtCreateFile->IoCreateFile->ObOpenObjectByName->ObpLookupObjectName->IopParseFile->IopParseDevice
IopParseFile最终也会调用IopParseDevice
ObjectHook其实就是比如你要HOOK 创建打开就是OBJECT_TYPE_INITIALIZER->ParseProcedure

说了一大堆废话 上段代码。
#include <ntddk.h>


#define OBJECT_TO_OBJECT_HEADER(o)\
      CONTAINING_RECORD((o),OBJECT_HEADER,Body)

typedef struct _OBJECT_TYPE_INITIALIZER {
  USHORT Length;
  BOOLEAN UseDefaultObject;
  BOOLEAN CaseInsensitive;
  ULONG InvalidAttributes;
  GENERIC_MAPPING GenericMapping;
  ULONG ValidAccessMask;
  BOOLEAN SecurityRequired;
  BOOLEAN MaintainHandleCount;
  BOOLEAN MaintainTypeList;
  POOL_TYPE PoolType;
  ULONG DefaultPagedPoolCharge;
  ULONG 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 { 
  ERESOURCE Mutex; 
  LIST_ENTRY TypeList; 
  UNICODE_STRING Name; 
  PVOID DefaultObject; 
  ULONG Index; 
  ULONG TotalNumberOfObjects; 
  ULONG TotalNumberOfHandles; 
  ULONG HighWaterNumberOfObjects; 
  ULONG HighWaterNumberOfHandles; 
  OBJECT_TYPE_INITIALIZER TypeInfo; 
#ifdef POOL_TAGGING 
  ULONG Key; 
#endif 
} OBJECT_TYPE, *POBJECT_TYPE;

typedef struct _OBJECT_CREATE_INFORMATION { 
  ULONG Attributes; 
  HANDLE RootDirectory; 
  PVOID ParseContext; 
  KPROCESSOR_MODE ProbeMode; 
  ULONG PagedPoolCharge; 
  ULONG NonPagedPoolCharge; 
  ULONG SecurityDescriptorCharge; 
  PSECURITY_DESCRIPTOR SecurityDescriptor; 
  PSECURITY_QUALITY_OF_SERVICE SecurityQos; 
  SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; 
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;

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;

POBJECT_TYPE pType= NULL;
POBJECT_HEADER addrs=NULL;
PVOID OldParseProcedure = NULL;


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;
    KdPrint(("object is hook\n"));
    __asm
    {
        push eax
        push Object
        push SecurityQos
        push Context
        push RemainingName
        push CompleteName
        push Attributes
        movzx eax, AccessMode
        push eax
        push AccessState
        push ObjectType
        push ParseObject
        call OldParseProcedure
        mov Status, eax
        pop eax   
    }
    
    return Status;
}

NTSTATUS Hook()
{
    NTSTATUS  Status;
    HANDLE hFile;
    UNICODE_STRING Name;
    OBJECT_ATTRIBUTES Attr;
    IO_STATUS_BLOCK ioStaBlock;
    PVOID pObject = NULL;
    
    RtlInitUnicodeString(&Name,L"\\Device\\HarddiskVolume1\\1.txt");
    InitializeObjectAttributes(&Attr,&Name,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,0,NULL);
    Status = ZwOpenFile(&hFile,GENERIC_ALL,&Attr,&ioStaBlock,0,FILE_NON_DIRECTORY_FILE);
    if (!NT_SUCCESS(Status))
    {
        KdPrint(("File is Null\n"));
        return Status;
    }
    
    Status = ObReferenceObjectByHandle(hFile,GENERIC_ALL,NULL,KernelMode,&pObject,NULL);
    if (!NT_SUCCESS(Status))
    {
        KdPrint(("Object is Null\n"));
        return Status;
    }
    
    KdPrint(("pobject is 0x%08X\n",pObject));
    
    addrs=OBJECT_TO_OBJECT_HEADER(pObject);//获取对象头
        
    pType=addrs->Type;//获取对象类型结构 object-10h
    
    KdPrint(("pType is 0x%08X\n",pType));
    OldParseProcedure = pType->TypeInfo.ParseProcedure;//获取服务函数原始地址OBJECT_TYPE+9C位置为打开
    KdPrint(("OldParseProcedure addrs is 0x%08X\n",OldParseProcedure));
    KdPrint(("addrs is 0x%08X\n",addrs));
    if (!MmIsAddressValid(OldParseProcedure))
    {
        ObDereferenceObject(pObject);
        ZwClose(hFile);
        return STATUS_SUCCESS;
    }

    pType->TypeInfo.ParseProcedure = NewParseProcedure;//hook

    ObDereferenceObject(pObject);
    Status = ZwClose(hFile);

    return Status;
}

VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
    KdPrint(("Unload!\n"));
    pType->TypeInfo.ParseProcedure = OldParseProcedure;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
    NTSTATUS Status = STATUS_SUCCESS;
    DriverObject->DriverUnload = Unload;
    Status = Hook();
    return Status;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值