**在DriverMain中驱动主要做了几件事
①初始化系统版本偏移
②注册通信的分发函数
③设置了通讯函数
④注册通知和回调
⑤创建进程通知
主要是根据不同的系统版本号初始化一些全局变量,这里不做具体分析了。
默认的分发函数,没什么好说的。
这里就比较关键了,可以注意到这里丢了两个通讯条件,一个是在通讯函数的头部存放了一个长度值,另一个是sysBuffer的值是一个固定值。
由此我们目前可以确定InputBuffer中的前8个字节0x345821AB00000270
前四个字节是长度,后四个字节是固定标识码,用于确认三环程序的身份。
由于在上一小节中我们只知道了InputBuffer的前8个字节,我们直接看到我ida分析过后的代码,可以看到while中的条件判断是在判断FuncIndex,函数编号。
我们双击FunCallArray进去看看里面是什么,可以看到是标准的8字节排列的对象,由此猜测这很可能是函数数组,那么我怎么确定这个事实,并且也确定FuncIndex就是函数索引的呢?我们继续看下一节“设置函数通讯你列表”
我们观察上面的截图,看到第一个140010F88(8字节)和140010F90(4字节)
再看看下方的截图,你发现了什么?
是吧?他就是一个8字节对齐的全局的结构体数组
由此我们可以知道3.2.2小节中FuncCall的命名由来,实际上他在根据索引确定函数的调用。
接下来我挑几个我觉得比较有意思的函数发一下分析。
可以看到一个附加操作下面,又调用了一个函数,ok,继续跟进去,发现内部调用了“ObSetHandleAttributes”
如果你在逆向分析的时候不了解这种函数是做什么的,打开wrk搜索一下
我们继续看一下HandleFlags的结构体类型
基本可以确定这是一个用于关闭文件的函数。如果你不是十分肯定的话,再搜索引擎确认一下。
一直跟进可以发现是在做一些函数全局变量的初始化。
可以看到这个函数里的关键部分“CraeteDrawDLLDetectMemory”
我们继续跟进
可以发现里面申请了内存,然后把字符串拷贝进去,显然这是在创建需要检测的dll数据。ok,那我们知道了,这个驱动会在“dwmcore.dll”、“ gdi32.dll”、“ user32.dll” 上做一些监控。
继续跟进
进入“CreateKernelAndUserDetectThread”,参考图中注释可以看到这个函数在做什么。
里面干了两件事,红框圈出来的部分
我们深入进去看下RegisterCallBack
我们深入进去看一下
继续跟进CheckInformationProcess
看到两个关键点,ZwQueryInformationProcess, 查询号为27:ProcessImageFileName,然后也出现了ZwClose,兄弟们懂了吧,如果你有在这款驱动加载的情况下打开某些调试器的经验,那么大概就是这个函数搞的鬼。
希望自己在学习分析时候遇到的一些经验和思路能够帮助吧友。
struct _FunCallArray
{
ULONG64 FuncAddr;
ULONG FuncIndex;
};
struct _FunCallArray
{
ULONG64 FuncAddr;
ULONG FuncIndex;
};
NTKERNELAPI
NTSTATUS
ObSetHandleAttributes (
__in HANDLE Handle,
__in POBJECT_HANDLE_FLAG_INFORMATION HandleFlags,
__in KPROCESSOR_MODE PreviousMode
);
NTKERNELAPI
NTSTATUS
ObSetHandleAttributes (
__in HANDLE Handle,
__in POBJECT_HANDLE_FLAG_INFORMATION HandleFlags,
__in KPROCESSOR_MODE PreviousMode
);
typedef struct _OBJECT_HANDLE_FLAG_INFORMATION {
BOOLEAN Inherit;
BOOLEAN ProtectFromClose;
} OBJECT_HANDLE_FLAG_INFORMATION,
*
POBJECT_HANDLE_FLAG_INFORMATION;
typedef struct _OBJECT_HANDLE_FLAG_INFORMATION {
BOOLEAN Inherit;
BOOLEAN ProtectFromClose;
} OBJECT_HANDLE_FLAG_INFORMATION,
*
POBJECT_HANDLE_FLAG_INFORMATION;
__int64 sub_1400075D4()
{
unsigned
int
v0;
/
/
ebx
__int64 (__fastcall
*
v1)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD);
/
/
r15
__int64 (__fastcall
*
RtlCreateUserThreadFunc)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD);
/
/
r13
__int64 result;
/
/
rax
int
*
v4;
/
/
rdi
const void
*
win32kModule;
/
/
r14
__int64 win32kfullModule;
/
/
rax
__int64 v7;
/
/
r8
__int64 v8;
/
/
r9
__int64 win32kfullModule1;
/
/
rsi
__int64 v10;
/
/
r8
__int64 v11;
/
/
r9
__int64 v12;
/
/
r8
__int64 v13;
/
/
r9
__int64 v14;
/
/
r8
__int64 v15;
/
/
r9
__int64 v16;
/
/
r8
__int64 v17;
/
/
r9
__int64 v18;
/
/
r8
__int64 v19;
/
/
r9
PIMAGE_NT_HEADERS winkNts;
/
/
rax
PIMAGE_NT_HEADERS winkNts1;
/
/
rsi
__int64 win32SizeOfImage;
/
/
r12
int
v23;
/
/
eax
const void
*
v24;
/
/
rbx
const void
*
W32pServiceTable1;
/
/
[rsp
+
30h
] [rbp
-
48h
] BYREF
__int64 v26;
/
/
[rsp
+
38h
] [rbp
-
40h
] BYREF
const void
*
v27;
/
/
[rsp
+
40h
] [rbp
-
38h
] BYREF
__int64 v28;
/
/
[rsp
+
48h
] [rbp
-
30h
] BYREF
__int64 (__fastcall
*
v29)(_QWORD, _QWORD);
/
/
[rsp
+
50h
] [rbp
-
28h
] BYREF
__int64 W32pServiceTable2;
/
/
[rsp
+
58h
] [rbp
-
20h
] BYREF
UNICODE_STRING DestinationString;
/
/
[rsp
+
60h
] [rbp
-
18h
] BYREF
const void
*
win32kMemoryModule;
/
/
[rsp
+
C0h] [rbp
+
48h
] BYREF
__int64 v33;
/
/
[rsp
+
C8h] [rbp
+
50h
] BYREF
__int64 NtUserGetWindowDisplayAffinity;
/
/
[rsp
+
D0h] [rbp
+
58h
] BYREF
__int64 NtUserSetWindowDisplayAffinity;
/
/
[rsp
+
D8h] [rbp
+
60h
] BYREF
v0
=
0
;
v1
=
0i64
;
v26
=
0i64
;
v27
=
0i64
;
v29
=
0i64
;
v28
=
0i64
;
if
( qword_140011700 )
return
0i64
;
RtlInitUnicodeString_0(&DestinationString, L
"RtlCreateUserThread"
);
RtlCreateUserThreadFunc
=
(__int64 (__fastcall
*
)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD))sub_140014948();
if
( !RtlCreateUserThreadFunc )
{
v1
=
(__int64 (__fastcall
*
)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD))GetNtCreateThreadEx();
if
( !v1 )
return
0xE01AF211i64
;
}
if
( version1 !
=
1
&& version1 !
=
2
&& version1 !
=
3
)
{
if
( version1 !
=
4
)
{
switch ( version1 )
{
case
6
:
v4
=
(
int
*
)&unk_140010480;
break
;
case
7
:
v4
=
(
int
*
)&unk_1400104D0;
break
;
case
8
:
v4
=
(
int
*
)&unk_140010520;
break
;
default:
result
=
sub_140006D7C();
if
( (
int
)result <
0
)
{
_mm_lfence();
return
result;
}
v4
=
(
int
*
)&unk_140010570;
LABEL_20:
j_DbgPrint_54(
"check ntusercalloneparam\n"
);
if
( v4[
9
] >
=
0
)
{
j_DbgPrint_55(
"load win32k image\n"
);
if
( (
int
)readSysFileToMemory((__int64)&win32kMemoryModule, L
"\\systemroot\\system32\\win32k.sys"
) >
=
0
)
{
j_DbgPrint_56(
"get real win32k address\n"
);
win32kModule
=
(const void
*
)QueryModules(
"win32k.sys"
);
if
( !win32kModule )
goto LABEL_23;
j_DbgPrint_57(
"fetch win32k service table\n"
);
win32kfullModule
=
QueryModules(
"win32kfull.sys"
);
NtUserGetWindowDisplayAffinity
=
0i64
;
win32kfullModule1
=
win32kfullModule;
NtUserSetWindowDisplayAffinity
=
0i64
;
if
( win32kfullModule )
{
writeFileLog(
"win32kfull => %p\n"
, win32kfullModule, v7, v8);
if
( (
int
)readSysFileToMemory((__int64)&v33, L
"\\systemroot\\system32\\win32kfull.sys"
) <
0
)
{
GetExportTableFunc(
&NtUserGetWindowDisplayAffinity,
win32kfullModule1,
(__int64)
"NtUserGetWindowDisplayAffinity"
);
GetExportTableFunc(
&NtUserSetWindowDisplayAffinity,
win32kfullModule1,
(__int64)
"NtUserSetWindowDisplayAffinity"
);
writeFileLog(
"getdisp %p"
, NtUserGetWindowDisplayAffinity, v16, v17);
writeFileLog(
"setdisp %p"
, NtUserSetWindowDisplayAffinity, v18, v19);
}
else
{
writeFileLog(
"win32kfull safe => %p\n"
, v33, v10, v11);
if
( (
int
)GetExportTableFunc(
&NtUserGetWindowDisplayAffinity,
v33,
(__int64)
"NtUserGetWindowDisplayAffinity"
) >
=
0
)
{
writeFileLog(
"getdisp %p %08x => %p %p\n"
,
NtUserGetWindowDisplayAffinity,
NtUserGetWindowDisplayAffinity
-
v33,
win32kfullModule1);
NtUserGetWindowDisplayAffinity
+
=
win32kfullModule1
-
v33;
writeFileLog(
"getdisp %p"
, NtUserGetWindowDisplayAffinity, v12, v13);
}
if
( (
int
)GetExportTableFunc(
&NtUserSetWindowDisplayAffinity,
v33,
(__int64)
"NtUserSetWindowDisplayAffinity"
) >
=
0
)
{
writeFileLog(
"setdisp %p %08x => %p %p\n"
,
NtUserSetWindowDisplayAffinity,
NtUserSetWindowDisplayAffinity
-
v33,
win32kfullModule1);
NtUserSetWindowDisplayAffinity
+
=
win32kfullModule1
-
v33;
writeFileLog(
"setdisp %p"
, NtUserSetWindowDisplayAffinity, v14, v15);
}
tryPrint(v33);
}
}
W32pServiceTable1
=
0i64
;
if
( (
int
)GetExportTableFunc(&W32pServiceTable1, (__int64)win32kMemoryModule, (__int64)
"W32pServiceTable"
) >
=
0
&& (W32pServiceTable2
=
0i64
,
(
int
)GetExportTableFunc(&W32pServiceTable2, (__int64)win32kModule, (__int64)
"W32pServiceTable"
) >
=
0
) )
{
_mm_lfence();
j_DbgPrint_58(
"get real win32k nt header\n"
);
winkNts
=
GetImageNts((__int64)win32kModule);
winkNts1
=
winkNts;
if
( !winkNts )
{
LABEL_44:
tryPrint((__int64)win32kMemoryModule);
return
v0;
}
_mm_lfence();
win32SizeOfImage
=
(__int64)win32kModule
+
winkNts
-
>OptionalHeader.SizeOfImage;
j_DbgPrint_59(
"resolve pNtUserGetForegroundWindow\n"
);
v23
=
sub_1400070A4(
&v28,
v4[
4
],
(__int64)win32kMemoryModule,
(__int64)W32pServiceTable1,
(__int64)win32kModule);
_mm_lfence();
if
( v23 <
0
)
{
LABEL_43:
v0
=
v23;
goto LABEL_44;
}
j_DbgPrint_60(
"resolve pNtUserQueryWindow\n"
);
v23
=
sub_1400070A4(
&v29,
v4[
6
],
(__int64)win32kMemoryModule,
(__int64)W32pServiceTable1,
(__int64)win32kModule);
if
( v23 <
0
|| (j_DbgPrint_61(
"resolve NtUserSetWindowDisplayAffinity\n"
), v4[
15
] >
=
0
)
&& (_mm_lfence(),
v23
=
sub_1400070A4(
&v27,
v4[
15
],
(__int64)win32kMemoryModule,
(__int64)W32pServiceTable1,
(__int64)win32kModule),
v23 <
0
)
|| v4[
16
] >
=
0
&& (_mm_lfence(),
v23
=
sub_1400070A4(
&v26,
v4[
16
],
(__int64)win32kMemoryModule,
(__int64)W32pServiceTable1,
(__int64)win32kModule),
v23 <
0
) )
{
_mm_lfence();
goto LABEL_43;
}
_mm_lfence();
v24
=
v27;
W32pServiceTable11
=
(__int64)W32pServiceTable1;
qword_1400117C8
=
v26;
qword_140011850
=
v28;
qword_140011858
=
v29;
NtUserGetWindowDisplayAffinity1
=
NtUserGetWindowDisplayAffinity;
NtUserSetWindowDisplayAffinity2
=
NtUserSetWindowDisplayAffinity;
win32kMemoryModule1
=
(__int64)win32kMemoryModule;
win32kModule2
=
(__int64)win32kModule;
win32SizeOfImage1
=
win32SizeOfImage;
NtCreateThreadEx
=
v1;
::RtlCreateUserThreadFunc
=
RtlCreateUserThreadFunc;
qword_1400117C0
=
(__int64)v27;
qword_140011708
=
(__int64)win32kModule;
qword_140011700
=
(__int64)v4;
j_DbgPrint_62(
"z s_safe_win32k == > %p\n"
, win32kMemoryModule);
j_DbgPrint_63(
"z w32_table == > %p\n"
, W32pServiceTable1);
j_DbgPrint_64(
"z win32k == > %p\n"
, win32kModule);
j_DbgPrint_65(
"z nt == > %p\n"
, winkNts1);
j_DbgPrint_66(
"z s_win32k_begin == > %p\n"
, (const void
*
)win32kModule2);
j_DbgPrint_67(
"z s_win32k_end == > %p\n"
, (const void
*
)win32SizeOfImage1);
j_DbgPrint_68(
"z s_win32k_table == > %p\n"
, (const void
*
)W32pServiceTable11);
j_DbgPrint_69(
"z pNtUserSetWindowDisplayAffinity == > %p\n"
, v24);
}
else
{
LABEL_23:
tryPrint((__int64)win32kMemoryModule);
}
}
return
0i64
;
}
return
0xC0000001i64
;
}
sub_140006AC8();
goto LABEL_20;
}
v4
=
(
int
*
)&unk_140010430;
goto LABEL_20;
}
return
0xC0000001i64
;
__int64 sub_1400075D4()
{
unsigned
int
v0;
/
/
ebx
__int64 (__fastcall
*
v1)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD);
/
/
r15
__int64 (__fastcall
*
RtlCreateUserThreadFunc)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD);
/
/
r13
__int64 result;
/
/
rax
int
*
v4;
/
/
rdi
const void
*
win32kModule;
/
/
r14
__int64 win32kfullModule;
/
/
rax
__int64 v7;
/
/
r8
__int64 v8;
/
/
r9
__int64 win32kfullModule1;
/
/
rsi
__int64 v10;
/
/
r8
__int64 v11;
/
/
r9
__int64 v12;
/
/
r8
__int64 v13;
/
/
r9
__int64 v14;
/
/
r8
__int64 v15;
/
/
r9
__int64 v16;
/
/
r8
__int64 v17;
/
/
r9
__int64 v18;
/
/
r8
__int64 v19;
/
/
r9
PIMAGE_NT_HEADERS winkNts;
/
/
rax
PIMAGE_NT_HEADERS winkNts1;
/
/
rsi
__int64 win32SizeOfImage;
/
/
r12
int
v23;
/
/
eax
const void
*
v24;
/
/
rbx
const void
*
W32pServiceTable1;
/
/
[rsp
+
30h
] [rbp
-
48h
] BYREF
__int64 v26;
/
/
[rsp
+
38h
] [rbp
-
40h
] BYREF
const void
*
v27;
/
/
[rsp
+
40h
] [rbp
-
38h
] BYREF
__int64 v28;
/
/
[rsp
+
48h
] [rbp
-
30h
] BYREF
__int64 (__fastcall
*
v29)(_QWORD, _QWORD);
/
/
[rsp
+
50h
] [rbp
-
28h
] BYREF
__int64 W32pServiceTable2;
/
/
[rsp
+
58h
] [rbp
-
20h
] BYREF
UNICODE_STRING DestinationString;
/
/
[rsp
+
60h
] [rbp
-
18h
] BYREF
const void
*
win32kMemoryModule;
/
/
[rsp
+
C0h] [rbp
+
48h
] BYREF
__int64 v33;
/
/
[rsp
+
C8h] [rbp
+
50h
] BYREF
__int64 NtUserGetWindowDisplayAffinity;
/
/
[rsp
+
D0h] [rbp
+
58h
] BYREF
__int64 NtUserSetWindowDisplayAffinity;
/
/
[rsp
+
D8h] [rbp
+
60h
] BYREF
v0
=
0
;
v1
=
0i64
;
v26
=
0i64
;
v27
=
0i64
;
v29
=
0i64
;
v28
=
0i64
;
if
( qword_140011700 )
return
0i64
;
RtlInitUnicodeString_0(&DestinationString, L
"RtlCreateUserThread"
);
RtlCreateUserThreadFunc
=
(__int64 (__fastcall
*
)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD))sub_140014948();
if
( !RtlCreateUserThreadFunc )
{
v1
=
(__int64 (__fastcall
*
)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD))GetNtCreateThreadEx();
if
( !v1 )
return
0xE01AF211i64
;
}
if
( version1 !
=
1
&& version1 !
=
2
&& version1 !
=
3
)
{
if
( version1 !
=
4
)
{
switch ( version1 )
{
case
6
:
v4
=
(
int
*
)&unk_140010480;
break
;
case
7
:
v4
=
(
int
*
)&unk_1400104D0;
break
;
case
8
:
v4
=
(
int
*
)&unk_140010520;
break
;
default:
result
=
sub_140006D7C();
if
( (
int
)result <
0
)
{
_mm_lfence();
return
result;
}
v4
=
(
int
*
)&unk_140010570;
LABEL_20:
j_DbgPrint_54(
"check ntusercalloneparam\n"
);
if
( v4[
9
] >
=
0
)
{
j_DbgPrint_55(
"load win32k image\n"
);
if
( (
int
)readSysFileToMemory((__int64)&win32kMemoryModule, L
"\\systemroot\\system32\\win32k.sys"
) >
=
0
)
{
j_DbgPrint_56(
"get real win32k address\n"
);
win32kModule
=
(const void
*
)QueryModules(
"win32k.sys"
);
if
( !win32kModule )
goto LABEL_23;
j_DbgPrint_57(
"fetch win32k service table\n"
);
win32kfullModule
=
QueryModules(
"win32kfull.sys"
);
NtUserGetWindowDisplayAffinity
=
0i64
;
win32kfullModule1
=
win32kfullModule;
NtUserSetWindowDisplayAffinity
=
0i64
;
if
( win32kfullModule )
{
writeFileLog(
"win32kfull => %p\n"
, win32kfullModule, v7, v8);
if
( (
int
)readSysFileToMemory((__int64)&v33, L
"\\systemroot\\system32\\win32kfull.sys"
) <
0
)
{
GetExportTableFunc(
&NtUserGetWindowDisplayAffinity,
win32kfullModule1,
(__int64)
"NtUserGetWindowDisplayAffinity"
);
[注意]APP应用上架合规检测服务,协助应用顺利上架!
最后于 2022-2-16 10:44
被铜锣湾扛把子编辑
,原因: 上传缺失图片