一个简单的Object Hook的例子(win7 32bit)

野性酷女 2023-10-12 06:36 48阅读 0赞

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][DOY_23HX_SA7GI_FF_4L_DOY_23HX_SA7GI_FF_4L]![{}$D6}(GSQT}6T[9)[RP[2K]D6_GSQT_6T_9_RP_2K

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

object_header地址=_EPROCESS地址

923483-20160830094107761-1279901750.jpgjpg 改 rar

转载于:https://www.cnblogs.com/kuangke/p/5818815.html

发表评论

表情:
评论列表 (有 0 条评论,48人围观)

还没有评论,来说两句吧...

相关阅读

    相关 WIN32 消息Hook API

    前言 在`Win32`中存在一个消息机制,程序任何点击或者消息都会通过窗口过程下发,而微软提供`SetWindowsHookEx`API来来允许我们进行相关事件监听,并且