VOID CheckNtApi(
int
index, const char
*
pApiName, PVOID pApiAddress);
ULONG64 FindProcess(const char
*
pProcessName);
VOID CheckDriver(ULONG64 unknow0, ULONG64 unknow1, const char
*
path, const char
*
name);
ULONG64 g_DriverInfo
=
0
;
/
/
VOID BeThread()
/
/
{
/
/
/
*
/
/
*
首先BE对几个内核API进行了校验 类似如下
/
/
*
/
/
/
/
/
CheckNtApi(
0
,
0
, MmGetSystemRoutineAddress); MmGetSystemRoutineAddress是IAT的地址
/
/
CheckNtApi(
1
,
"MmIsAddressValid"
, MmIsAddressValid);
/
/
CheckNtApi(
2
,
"ZwQuerySystemInformation"
, ZwQuerySystemInformation);
/
/
CheckNtApi(
3
,
"NtQuerySystemInformation"
, NtQuerySystemInformation);
/
/
CheckNtApi(
4
,
"NtReadVirtualMemory"
, NtReadVirtualMemory);
/
/
/
/
/
*
/
/
*
BE操作的一些驱动
/
/
*
/
/
/
const char
*
DrivrStrArr[]
=
/
/
{
"win32k.sys"
,
"hal.dll"
,
"clipsp.sys"
,
"CI.dll"
,
"CI.dll"
,
/
/
"tpm.sys"
,
"ks.sys"
,
"ks.sys"
,
"TSDDD.dll"
,
"TSDDD.dll"
,
"TSDDD.dll"
};
/
/
const char
*
csrss
=
"csrss.exe"
;
/
/
/
/
/
*
/
/
*
首先BE进行了友好的遍历大概是这样子的
/
/
*
/
/
/
auto LocalDriverInfo
=
g_DriverInfo;
/
/
while
(LocalDriverInfo)
/
/
{
/
/
for
(size_t i
=
0
; i < sizeof(DrivrStrArr)
/
sizeof(DrivrStrArr[
0
]); i
+
+
)
/
/
{
/
/
if
(strcmp((char
*
)(LocalDriverInfo
+
*
(PULONG64)LocalDriverInfo
+
2
), DrivrStrArr[
0
])
=
=
0
)
/
/
win32k.sys
/
/
{
/
/
ULONG64 eprocess_csrss
=
FindProcess(csrss);
/
/
/
/
if
(eprocess_csrss)
/
/
{
/
/
KeStackAttachProcess(eprocess_csrss, &ApcState);
/
/
/
/
Check win32k.sys等 (直接读了驱动的物理内存,检测了一些常规的跳板 E8 E9 FF15 。。。等)
/
/
/
/
KeUnstackDetachProcess(&ApcState);
/
/
ObDereferenceProcessHandleTable(eprocess_csrss);
/
/
ObfDereferenceObject((PVOID)eprocess_csrss);
/
/
}
/
/
/
/
continue
;
/
/
}
/
/
/
/
if
(strcmp((char
*
)(LocalDriverInfo
+
*
(PULONG64)LocalDriverInfo
+
2
), DrivrStrArr[i])
=
=
0
)
/
/
{
/
/
Check DriverFile
/
/
RtlInitAnsiString
/
/
RtlAnsiStringToUnicodeString
/
/
/
/
CheckDriver(
*
((ULONG64
*
)LocalDriverInfo
+
161
),
/
/
*
((unsigned
int
*
)LocalDriverInfo
+
324
),DriverPath, DrivrStrArr[i]);
/
/
(获取文件和驱动的物理内存检测了一些常规的跳板 E8 E9 FF15 。。。等)
/
/
/
/
RtlFreeUnicodeString
/
/
}
/
/
}
/
/
/
/
LocalDriverInfo
=
*
((ULONG64
*
)LocalDriverInfo
+
165
);
/
/
}
/
/
/
/
do
/
/
{
/
/
g_check_driverfunc(); 检查BE驱动的io接口是否被劫持
/
/
/
/
auto Result
=
ZwQuerySystemInformation(SystemProcessInformation, v5, SystemInformationLength, ReturnLength);
/
/
if
(Result
=
=
0xC0000004
)
/
/
{
/
/
if
(g_ProcInfo)
/
/
{
/
/
ExFreePoolWithTag(g_ProcInfo,
0
);
/
/
}
/
/
SystemInformationLength
=
*
ReturnLength
+
1024
;
/
/
/
/
g_ProcInfo
=
ExAllocatePoolWithTag(PagedPool, SystemInformationLength,
'EB'
);
/
/
/
/
do
/
/
{
/
/
Result
=
ZwQuerySystemInformation(
/
/
SystemProcessInformation,
/
/
g_ProcInfo,
/
/
SystemInformationLength,
/
/
ReturnLength);
/
/
/
/
if
(Result !
=
0xC0000004
)
/
/
{
/
/
break
;
/
/
}
/
/
ExFreePoolWithTag(g_ProcInfo,
0
);
/
/
SystemInformationLength
=
*
ReturnLength
+
1024
;
/
/
g_ProcInfo
=
ExAllocatePoolWithTag(PagedPool, SystemInformationLength,
'EB'
);
/
/
}
while
(g_ProcInfo);
/
/
/
/
ProcessId
=
PsGetProcessId(
*
(PEPROCESS
*
)PsInitialSystemProcess);
/
/
/
/
pProcIndex
=
(PSYSTEM_PROCESSES)g_ProcInfo;
/
/
do
/
/
{
/
/
if
(ProcessId !
=
pProcIndex.ProcessId &&
/
/
PsLookupProcessByProcessId(UniqueProcessId, (PEPROCESS
*
)&process))
/
/
这边还有很多其他的判断
/
/
{
/
/
/
/
枚举句柄表
/
/
{
/
/
ObGetObjectType
/
/
auto HnadleFunc
=
[]()
-
>VOID
/
/
{
/
/
大概的行为是
/
/
if
(ObGetObjectType(v7) !
=
*
PsThreadType)
/
/
{
/
/
return
;
/
/
}
/
/
if
(PsGetThreadProcess(v7) !
=
(PEPROCESS)qword_140016210)
/
/
{
/
/
return
;
/
/
}
/
/
/
/
v10
=
*
(_DWORD
*
)(a1
+
8
);
/
/
if
((v10 &
0x18
)
=
=
0
)
/
/
return
;
/
/
v9
=
v10 &
0xFFFFFFE7
;
/
/
/
/
if
(ObGetObjectType(v5
+
48
)
=
=
*
IoFileObjectType &&
/
/
*
(_DWORD
*
)(
*
(_QWORD
*
)(v5
+
56
)
+
72i64
)
=
=
64
)
/
/
{
/
/
sub_xxxxxxx((_QWORD
*
)(v5
+
48
));
/
/
一部分的文件操作
/
/
}
/
/
/
/
}
/
/
ExEnumHandleTable(v5, HnadleFunc, v2,
0i64
);
/
/
ObfDereferenceObject(
*
(PVOID
*
)process);
/
/
}
/
/
/
/
}
/
/
pProcIndex
=
(PSYSTEM_PROCESSES)((char
*
)pProcIndex
+
pProcIndex
-
>NextEntryDelta);
/
/
}
while
(pProcIndex
-
>NextEntryDelta !
=
0
);
/
/
}
/
/
/
/
/
/
/
/
if
(
1
/
*
某个全局变量
*
/
)
/
/
{
/
/
CheckNtApi(
7
,
0
, KeInitializeEvent);
/
/
CheckNtApi(
8
,
0
, KeInitializeApc);
/
/
CheckNtApi(
9
,
0
, KeInsertQueueApc);
/
/
CheckNtApi(
10
,
0
, RtlWalkFrameChain);
/
/
CheckNtApi(
11
,
0
, KeSetEvent);
/
/
CheckNtApi(
12
,
0
, KeWaitForSingleObject);
/
/
}
/
/
/
/
Check Thread
/
/
auto CheckThread
=
[]()
/
/
{
/
/
这里只是部分功能简述
/
/
ZwQuerySystemInformation SystemProcessInformation
/
/
先遍历进程 照例排除PsInitialSystemProcess在外
/
/
/
/
以
0x10000
为结束 以
4
为线程
id
起始 每次线程di
+
4
调用PsLookupThreadByThreadId获取线程对象
/
/
/
/
当获取线程对象成功后判断
/
/
if
(PsGetThreadProcessId(EThread)
=
=
ProcessInformation
-
>UniqueProcessId)
/
/
{
/
/
NumberOfThreads
=
ProcessInformation
-
>NumberOfThreads;
/
/
if
(NumberOfThreads)
/
/
{
/
/
p_KernelTime
=
&ProcessInformation[
1
].KernelTime;
/
/
do
/
/
{
/
/
if
(p_KernelTime
-
>QuadPart
=
=
i)
/
/
break
;
/
/
+
+
v18;
/
/
p_KernelTime
+
=
10
;
/
/
}
while
(v18 < NumberOfThreads);
/
/
}
/
/
}
/
/
/
/
if
(ObOpenObjectByPointer(EThread,
0x200u
,
0i64
,
0
,
*
PsThreadType,
0
, &v41) >
=
0
)
/
/
{
/
/
ZwQueryInformationThread(
/
/
v41,
/
/
ThreadQuerySetWin32StartAddress,
/
/
&ProcessInformation[
1
].CreateTime,
/
/
8u
,
/
/
0i64
);
/
/
if
(ZwQueryInformationThread(v41, ThreadTimes, v46,
0x20u
,
0i64
) >
=
0
)
/
/
*
(_LARGE_INTEGER
*
)&ProcessInformation[
1
].HardFaultCount
=
v46[
0
];
/
/
ZwClose(v41);
/
/
}
/
/
/
/
KeInitializeEvent((PRKEVENT)&Pool[
1
], NotificationEvent,
0
);
/
/
KeInitializeApc(Apc, Thread,
0i64
, j_g_apc_call,
0i64
);
/
/
if
( ((BOOLEAN (__stdcall
*
)(PRKAPC, PVOID, PVOID, KPRIORITY))KeInsertQueueApc)(Apc, Apc,
0i64
,
2
) )
/
/
{
/
/
...
/
/
}
/
/
};
/
/
/
/
CheckThread();
/
/
}
while
(
1
/
*
KeWaitForSingleObject(&
Object
, Executive,
0
,
0
, &Timeout)
*
/
);
/
/
/
/
if
( qword_xxxxx )
/
/
ExFreePoolWithTag(qword_xxxxx,
0
);
/
/
return
PsTerminateSystemThread(
0
);
/
/
}