一個簡單的Object Hook的例子(win7 32bit)


Object Hook簡單的來說就是Hook對象,這里拿看雪上的一個例子,因為是在win7 32位上的,有些地方做了些修改。

_OBJECT_HEADER:

kd> dt _OBJECT_HEADER
nt!_OBJECT_HEADER
   +0×000 PointerCount     : Int4B
   +0×004 HandleCount      : Int4B
   +0×004 NextToFree       : Ptr32 Void
   +0×008 Lock             : _EX_PUSH_LOCK
   +0x00c TypeIndex        : UChar
   +0x00d TraceFlags       : UChar
   +0x00e InfoMask         : UChar
   +0x00f Flags            : UChar
   +0×010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
   +0×010 QuotaBlockCharged : Ptr32 Void
   +0×014 SecurityDescriptor : Ptr32 Void
   +0×018 Body             : _QUAD

Win7 Object_Header之TypeIndex解析已經說了怎么通過TypeIndex得到對象類型:

_OBJECT_TYPE:

kd> dt _OBJECT_TYPE
nt!_OBJECT_TYPE
   +0×000 TypeList         : _LIST_ENTRY
   +0×008 Name             : _UNICODE_STRING
   +0×010 DefaultObject    : Ptr32 Void
   +0×014 Index            : UChar
   +0×018 TotalNumberOfObjects : Uint4B
   +0x01c TotalNumberOfHandles : Uint4B
   +0×020 HighWaterNumberOfObjects : Uint4B
   +0×024 HighWaterNumberOfHandles : Uint4B
   +0×028 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0×078 TypeLock         : _EX_PUSH_LOCK
   +0x07c Key              : Uint4B
   +0×080 CallbackList     : _LIST_ENTRY

對象類型結構主要是創建對象類型,比如*IoFileObjectType, *PsProcessType, *PsThreadType 這些。

系統初始化的時候第一個創建的對象類型結構就是TYPE結構,生成對象目錄\ObjectTypes 其后面的對象類型直接掛在這個目錄上

比如對象類型 \ObjectTypes\File 或者設備類型 \ObjectTypes\Device

最重要的是下面這個結構:

kd> dt _OBJECT_TYPE_INITIALIZER
nt!_OBJECT_TYPE_INITIALIZER
   +0×000 Length           : Uint2B
   +0×002 ObjectTypeFlags  : UChar
   +0×002 CaseInsensitive  : Pos 0, 1 Bit
   +0×002 UnnamedObjectsOnly : Pos 1, 1 Bit
   +0×002 UseDefaultObject : Pos 2, 1 Bit
   +0×002 SecurityRequired : Pos 3, 1 Bit
   +0×002 MaintainHandleCount : Pos 4, 1 Bit
   +0×002 MaintainTypeList : Pos 5, 1 Bit
   +0×002 SupportsObjectCallbacks : Pos 6, 1 Bit
   +0×004 ObjectTypeCode   : Uint4B
   +0×008 InvalidAttributes : Uint4B
   +0x00c GenericMapping   : _GENERIC_MAPPING
   +0x01c ValidAccessMask  : Uint4B
   +0×020 RetainAccess     : Uint4B
   +0×024 PoolType         : _POOL_TYPE
   +0×028 DefaultPagedPoolCharge : Uint4B
   +0x02c DefaultNonPagedPoolCharge : Uint4B
   +0×030 DumpProcedure    : Ptr32     void
   +0×034 OpenProcedure    : Ptr32     long
   +0×038 CloseProcedure   : Ptr32     void
   +0x03c DeleteProcedure  : Ptr32     void
   +0×040 ParseProcedure   : Ptr32     long
   +0×044 SecurityProcedure : Ptr32     long
   +0×048 QueryNameProcedure : Ptr32     long
   +0x04c OkayToCloseProcedure : Ptr32     unsigned char

后面這幾個函數決定對象的一些操作,例如 打開、創建、刪除,不同對象類型(OBJECT_TYPE)的操作也不同,所以要清楚知道對象是什么類型。

當你調用NtCreateFile->IoCreateFile->ObOpenObjectByName->ObpLookupObjectName->IopParseFile->IopParseDevice
IopParseFile最終也會調用IopParseDevice
ObjectHook其實就是比如你要HOOK 創建打開就是OBJECT_TYPE_INITIALIZER->ParseProcedure。

代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <ntddk.h>

typedef PULONG (NTAPI *OBGETOBJECTTYPE ) (PVOID ) ;
OBGETOBJECTTYPE OBGetObjectType ;

typedef struct _OBJECT_TYPE_INITIALIZER {
        USHORT Length   ;
        UCHAR ObjectTypeFlags ;
        UCHAR CaseInsensitive   ;
        UCHAR UnnamedObjectsOnly ;
        UCHAR  UseDefaultObject ;
        UCHAR  SecurityRequired ;
        UCHAR MaintainHandleCount ;
        UCHAR MaintainTypeList ;
        UCHAR SupportsObjectCallbacks ;
        UCHAR CacheAligned   ;
        ULONG ObjectTypeCode   ;
        BOOLEAN InvalidAttributes ;
        GENERIC_MAPPING GenericMapping   ;
        BOOLEAN   ValidAccessMask   ;
        BOOLEAN   RetainAccess     ;
        POOL_TYPE PoolType         ;
        BOOLEAN DefaultPagedPoolCharge ;
        BOOLEAN DefaultNonPagedPoolCharge ;
        PVOID DumpProcedure   ;
        ULONG OpenProcedure     ;
        PVOID CloseProcedure   ;
        PVOID DeleteProcedure ;
        ULONG ParseProcedure   ;
        ULONG SecurityProcedure ;
        ULONG QueryNameProcedure ;
        UCHAR OkayToCloseProcedure ;
} OBJECT_TYPE_INITIALIZER , *POBJECT_TYPE_INITIALIZER ;
typedef struct _OBJECT_TYPE {
    LIST_ENTRY TypeList ;
    UNICODE_STRING Name ;
    PVOID DefaultObject ;
    ULONG Index ;
    ULONG TotalNumberOfObjects ;
    ULONG TotalNumberOfHandles ;
    ULONG HighWaterNumberOfObjects ;
    ULONG HighWaterNumberOfHandles ;
    OBJECT_TYPE_INITIALIZER TypeInfo   ;
    ULONG  TypeLock ;
    ULONG   Key ;
    LIST_ENTRY   CallbackList ;
} OBJECT_TYPE , *POBJECT_TYPE ;

POBJECT_TYPE   pType = 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 ;
}
VOID GetObGetObjectTypeAddress ( )
{
    PUCHAR addr ;
    UNICODE_STRING pslookup ;
    RtlInitUnicodeString ( &pslookup ,L "ObGetObjectType" ) ;
    addr = (PUCHAR )MmGetSystemRoutineAddress ( &pslookup ) ;
    OBGetObjectType = (OBGETOBJECTTYPE )addr ;
}
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" ) ;   //C:\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 %08X\n" ,pObject ) ) ;
//win7 獲取objecttype更加方便了。。。
 pType = (POBJECT_TYPE )OBGetObjectType (pObject ) ;

KdPrint ( ( "pType is %08X\n" ,pType ) ) ;
OldParseProcedure = pType ->TypeInfo. ParseProcedure ;
KdPrint ( ( "OldParseProcedure addrs is %08X\n" ,OldParseProcedure ) ) ;
//這里最好檢查一下OldParseProcedure,是否為0

pType ->TypeInfo. ParseProcedure = NewParseProcedure ; //hook 因為object原本就是是可寫的,所以不用特意去除內存保護
 Status = ZwClose (hFile ) ;
  return Status ;
}

NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject ,PUNICODE_STRING RegistryPath )
{
  NTSTATUS Status = STATUS_SUCCESS ;
  GetObGetObjectTypeAddress ( ) ;
  Status =Hook ( ) ;
  return Status ;
}

效果:

DOY)]23HX{SA7GI{FF@{$4L{}$D6}(GSQT}6T[9)[RP[2K

本文鏈接:http://www.blogfshare.com/object-hook.html

object_header地址=_EPROCESS地址

jpg 改 rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM