如上述可知ObRegisterCallbacks有两个调用参数
rcx
=
ObCallBack;
rdx
=
Handle;
PAGE:
00000001404B6D60
arg_0
=
qword ptr
8
PAGE:
00000001404B6D60
arg_8
=
qword ptr
10h
PAGE:
00000001404B6D60
arg_10
=
qword ptr
18h
PAGE:
00000001404B6D60
arg_18
=
qword ptr
20h
PAGE:
00000001404B6D60
PAGE:
00000001404B6D60
mov rax, rsp
PAGE:
00000001404B6D63
mov [rax
+
8
], rbx
PAGE:
00000001404B6D67
mov [rax
+
18h
], rbp
PAGE:
00000001404B6D6B
mov [rax
+
20h
], rsi
PAGE:
00000001404B6D6F
mov [rax
+
10h
], rdx
PAGE:
00000001404B6D73
push rdi
PAGE:
00000001404B6D74
push r12
PAGE:
00000001404B6D76
push r13
PAGE:
00000001404B6D78
push r14
PAGE:
00000001404B6D7A
push r15
PAGE:
00000001404B6D7C
sub rsp,
20h
PAGE:
00000001404B6D80
movzx eax, [rcx
+
OB_CALLBACK_REGISTRATION.Version] ; 获得填充结构中的Version
PAGE:
00000001404B6D83
xor ebx, ebx ; ebx
=
0
PAGE:
00000001404B6D85
mov r12, rcx ; r12
=
ObCallBack
PAGE:
00000001404B6D88
mov ecx,
0FF00h
; ecx
=
0xFF00
PAGE:
00000001404B6D8D
mov r14d,
100h
; r14d
=
0x100
PAGE:
00000001404B6D93
mov r15, rdx ; r15
=
Handle
PAGE:
00000001404B6D96
and
ax, cx ; ax
=
Version &
0xFF00
PAGE:
00000001404B6D99
mov esi, ebx ; esi
=
0
PAGE:
00000001404B6D9B
cmp
ax, r14w ; 将(Version &
0xFF00
)和
0x100
进行比较
PAGE:
00000001404B6D9F
jz short loc_1404B6DAB
PAGE:
00000001404B6DA1
loc_1404B6DA1:
PAGE:
00000001404B6DA1
mov eax,
0C000000Dh
; 如果(Version &
0xFF00
)不为
0x100
或设置的Count为
0
返回
0xC000000D
错误
PAGE:
00000001404B6DA6
jmp loc_1404B7009
PAGE:
00000001404B6DAB
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
PAGE:
00000001404B6DAB
PAGE:
00000001404B6DAB
loc_1404B6DAB:
PAGE:
00000001404B6DAB
cmp
[r12
+
OB_CALLBACK_REGISTRATION.OperationRegistrationCount], bx
PAGE:
00000001404B6DB1
jz short loc_1404B6DA1 ; 如果(Version &
0xFF00
)不为
0x100
或设置的Count为
0
返回
0xC000000D
错误
PAGE:
00000001404B6DB3
movzx ecx, [r12
+
OB_CALLBACK_REGISTRATION.OperationRegistrationCount]
PAGE:
00000001404B6DB9
movzx eax, [r12
+
OB_CALLBACK_REGISTRATION.Altitude.Length]
PAGE:
00000001404B6DBF
mov r8d,
6C46624Fh
; Tag
PAGE:
00000001404B6DC5
shl ecx,
6
PAGE:
00000001404B6DC8
lea ebp, [rcx
+
rax
+
20h
]
PAGE:
00000001404B6DCC
mov ecx,
1
; PoolType
PAGE:
00000001404B6DD1
mov edx, ebp ; NumberOfBytes
PAGE:
00000001404B6DD3
mov r13d, ebp
PAGE:
00000001404B6DD6
call ExAllocatePoolWithTag ; 申请
0x40
*
Count
+
0x20
+
Altitude.Length的长度
PAGE:
00000001404B6DDB
mov rdi, rax
PAGE:
00000001404B6DDE
cmp
rax, rbx
PAGE:
00000001404B6DE1
jnz short loc_1404B6DED
PAGE:
00000001404B6DE3
mov eax,
0C000009Ah
; 如果申请内存失败 则返回
0xC000009A
错误
PAGE:
00000001404B6DE8
jmp loc_1404B7009
PAGE:
00000001404B6DED
;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
PAGE:
00000001404B6DED
PAGE:
00000001404B6DED
loc_1404B6DED:
PAGE:
00000001404B6DED
mov r8, r13 ; Size
PAGE:
00000001404B6DF0
xor edx, edx ; Val
PAGE:
00000001404B6DF2
mov rcx, rax ; Dst
PAGE:
00000001404B6DF5
call memset ; 将申请的内存置零
PAGE:
00000001404B6DF5
; 接下来就开始进行结构的填充
PAGE:
00000001404B6DF5
; 我们暂且将这个结构命名为CallBackStr
PAGE:
00000001404B6DFA
mov [rdi
+
CallBackStr.VersionCmp], r14w ; 根据上面可知r14w
=
0x100
将r14w填入结构偏移
0
处
PAGE:
00000001404B6DFE
mov rax, [r12
+
OB_CALLBACK_REGISTRATION.RegistrationContext]
PAGE:
00000001404B6E03
mov [rdi
+
CallBackStr.RegistrationContext], rax ; 将提供的RegistrationContext填入结构
0x8
偏移处
PAGE:
00000001404B6E03
; 该对象在调用到回调函数时为函数的第一个参数
PAGE:
00000001404B6E07
movzx edx, [r12
+
OB_CALLBACK_REGISTRATION.Altitude.Length]
PAGE:
00000001404B6E0D
sub ebp, edx ; ebp
=
0x40
*
Count
+
0x20
PAGE:
00000001404B6E0F
mov [rdi
+
CallBackStr.length2], dx ; 将所给Altitude字符的长度 填入偏移
0x10
和
0x12
处
PAGE:
00000001404B6E13
mov [rdi
+
CallBackStr.length1], dx
PAGE:
00000001404B6E17
mov r8, rdx ; Size
PAGE:
00000001404B6E1A
mov ecx, ebp ; ecx
=
0x40
*
count
+
0x20
PAGE:
00000001404B6E1C
add rcx, rdi ; rcx
=
申请的内存地址
+
0x40
*
count
+
0x20
PAGE:
00000001404B6E1F
mov [rdi
+
18h
], rcx
PAGE:
00000001404B6E23
mov rdx, [r12
+
OB_CALLBACK_REGISTRATION.Altitude.
Buffer
]
PAGE:
00000001404B6E28
call memmove ; 从这个拷贝复制可以看出在结构的最后一个部分存放着提供的Altitude中的字符串
PAGE:
00000001404B6E2D
mov r14d, ebx ; r14d
=
0
PAGE:
00000001404B6E30
cmp
bx, [r12
+
OB_CALLBACK_REGISTRATION.OperationRegistrationCount]
PAGE:
00000001404B6E36
jnb loc_1404B6FDD ; 判断所给的count是否为非正数,如果成立则跳转 我们这里不考虑负数的情况
PAGE:
00000001404B6E3C
mov rbp, rbx ; rbp
=
0
PAGE:
00000001404B6E3F
lea r13, [rdi
+
58h
] ; r13
=
申请内存地址
+
0x58
处
PAGE:
00000001404B6E43
PAGE:
00000001404B6E43
loc_1404B6E43:
PAGE:
00000001404B6E43
mov rsi, [r12
+
OB_CALLBACK_REGISTRATION.OperationRegistration]
PAGE:
00000001404B6E48
cmp
[rsi
+
rbp
+
OB_OPERATION_REGISTRATION.Operations], ebx ;
PAGE:
00000001404B6E48
; 判断所提供的参数中是否已经定义了对于何种情况需要进入回调函数
PAGE:
00000001404B6E48
; 在前面提供的例子中 可以看到这里我们设置为
PAGE:
00000001404B6E48
; OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE
PAGE:
00000001404B6E48
; 即在打开句柄或者复制句柄的时候会进入回调函数
PAGE:
00000001404B6E4C
jz loc_1404B6F08
PAGE:
00000001404B6E52
mov rax, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.ObjectType]
PAGE:
00000001404B6E56
mov rcx, [rax]
PAGE:
00000001404B6E59
test [rcx
+
_OBJECT_TYPE.TypeInfo.___u1.ObjectTypeFlags],
40h
PAGE:
00000001404B6E5D
jz loc_1404B6F08 ;
PAGE:
00000001404B6E5D
; 判断类型对象中的ObjectTyoeFlags第
7
位是否为
1
PAGE:
00000001404B6E5D
; 该值在调用回调函数的时候也会进行判断
PAGE:
00000001404B6E5D
; 如果将该值设置为
0
则会禁止回调
PAGE:
00000001404B6E63
mov rcx, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.PreOperation]
PAGE:
00000001404B6E68
cmp
rcx, rbx ; 接下来判断是否给了访问前的回调函数和访问后的回调函数
PAGE:
00000001404B6E68
; 如果给了则会调用MmVerifyCallbackFunction判断回调函数是否合法
PAGE:
00000001404B6E6B
jnz short loc_1404B6E7D
PAGE:
00000001404B6E6D
cmp
[rsi
+
rbp
+
OB_OPERATION_REGISTRATION.PostOperation], rbx
PAGE:
00000001404B6E72
jz loc_1404B6F08
PAGE:
00000001404B6E78
cmp
rcx, rbx
PAGE:
00000001404B6E7B
jz short loc_1404B6E86
PAGE:
00000001404B6E7D
PAGE:
00000001404B6E7D
loc_1404B6E7D:
PAGE:
00000001404B6E7D
call MmVerifyCallbackFunction
PAGE:
00000001404B6E82
cmp
eax, ebx
PAGE:
00000001404B6E84
jz short loc_1404B6F01
PAGE:
00000001404B6E86
PAGE:
00000001404B6E86
loc_1404B6E86:
PAGE:
00000001404B6E86
mov rcx, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.PostOperation]
PAGE:
00000001404B6E8B
cmp
rcx, rbx
PAGE:
00000001404B6E8E
jz short loc_1404B6E99 ; r13
=
申请内存地址
+
0x58
处 所以相当于在结构
0x58
偏移处填充
0
PAGE:
00000001404B6E90
call MmVerifyCallbackFunction
PAGE:
00000001404B6E95
cmp
eax, ebx
PAGE:
00000001404B6E97
jz short loc_1404B6F01
PAGE:
00000001404B6E99
PAGE:
00000001404B6E99
loc_1404B6E99:
PAGE:
00000001404B6E99
mov [r13
+
0
], rbx ; r13
=
申请内存地址
+
0x58
处 所以相当于在结构
0x58
偏移处填充
0
PAGE:
00000001404B6E9D
lea rdx, [r13
-
38h
] ; 在结构偏移
0x20
处 初始化一个链表
PAGE:
00000001404B6EA1
mov [rdx], rdx
PAGE:
00000001404B6EA4
mov [r13
-
30h
], rdx
PAGE:
00000001404B6EA8
mov eax, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.Operations]
PAGE:
00000001404B6EAC
mov [r13
-
28h
], eax ; 将操作码 填充到结构的
0x30
PAGE:
00000001404B6EB0
mov [r13
-
20h
], rdi ; 将结构的首地址 填充到偏移
0x38
处
PAGE:
00000001404B6EB4
mov rax, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.ObjectType]
PAGE:
00000001404B6EB8
mov rcx, [rax] ; 取出类型对象地址赋给rcx 即PsProcessType
PAGE:
00000001404B6EBB
mov [r13
-
18h
], rcx ; 将类型对象地址 填充到结构
0x40
处
PAGE:
00000001404B6EBF
mov rax, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.PreOperation]
PAGE:
00000001404B6EC4
mov [r13
-
10h
], rax ; 将访问前函数地址填充到结构
0x48
处
PAGE:
00000001404B6EC8
mov rax, [rsi
+
rbp
+
OB_OPERATION_REGISTRATION.PostOperation]
PAGE:
00000001404B6ECD
mov [r13
-
8
], rax ; 将访问后函数地址填充到结构
0x50
偏移处
PAGE:
00000001404B6ED1
call ObpInsertCallbackByAltitude ; 将结构中的链表插入到类型对象的CallbackList链表中