/
/
获取 PspCidTable
/
/
By: LyShark.com
BOOLEAN get_PspCidTable(ULONG64
*
tableAddr)
{
/
/
获取 PsLookupProcessByProcessId 地址
UNICODE_STRING uc_funcName;
RtlInitUnicodeString(&uc_funcName, L
"PsLookupProcessByProcessId"
);
ULONG64 ul_funcAddr
=
MmGetSystemRoutineAddress(&uc_funcName);
if
(ul_funcAddr
=
=
NULL)
{
return
FALSE;
}
DbgPrint(
"PsLookupProcessByProcessId addr = %p \n"
, ul_funcAddr);
/
/
前
40
字节有 call(PspReferenceCidTableEntry)
/
*
0
: kd> uf PsLookupProcessByProcessId
nt!PsLookupProcessByProcessId:
fffff802`
0841cfe0
48895c2418
mov qword ptr [rsp
+
18h
],rbx
fffff802`
0841cfe5
56
push rsi
fffff802`
0841cfe6
4883ec20
sub rsp,
20h
fffff802`
0841cfea
48897c2438
mov qword ptr [rsp
+
38h
],rdi
fffff802`
0841cfef
488bf2
mov rsi,rdx
fffff802`
0841cff2
65488b3c2588010000
mov rdi,qword ptr gs:[
188h
]
fffff802`
0841cffb
66ff8fe6010000
dec word ptr [rdi
+
1E6h
]
fffff802`
0841d002
b203 mov dl,
3
fffff802`
0841d004
e887000000 call nt!PspReferenceCidTableEntry (fffff802`
0841d090
)
fffff802`
0841d009
488bd8
mov rbx,rax
fffff802`
0841d00c
4885c0
test rax,rax
fffff802`
0841d00f
7435
je nt!PsLookupProcessByProcessId
+
0x66
(fffff802`
0841d046
) Branch
*
/
ULONG64 ul_entry
=
0
;
for
(
INT
i
=
0
; i <
100
; i
+
+
)
{
/
/
fffff802`
0841d004
e8
87
00
00
00
call nt!PspReferenceCidTableEntry (fffff802`
0841d090
)
if
(
*
(PUCHAR)(ul_funcAddr
+
i)
=
=
0xe8
)
{
ul_entry
=
ul_funcAddr
+
i;
break
;
}
}
if
(ul_entry !
=
0
)
{
/
/
解析 call 地址
INT
i_callCode
=
*
(
INT
*
)(ul_entry
+
1
);
DbgPrint(
"i_callCode = %p \n"
, i_callCode);
ULONG64 ul_callJmp
=
ul_entry
+
i_callCode
+
5
;
DbgPrint(
"ul_callJmp = %p \n"
, ul_callJmp);
/
/
来到 call(PspReferenceCidTableEntry) 内找 PspCidTable
/
*
0
: kd> uf PspReferenceCidTableEntry
nt!PspReferenceCidTableEntry
+
0x115
:
fffff802`
0841d1a5
488b0d8473f5ff
mov rcx,qword ptr [nt!PspCidTable (fffff802`
08374530
)]
fffff802`
0841d1ac
b801000000 mov eax,
1
fffff802`
0841d1b1
f0480fc107 lock xadd qword ptr [rdi],rax
fffff802`
0841d1b6
4883c130
add rcx,
30h
fffff802`
0841d1ba
f0830c2400 lock
or
dword ptr [rsp],
0
fffff802`
0841d1bf
48833900
cmp
qword ptr [rcx],
0
fffff802`
0841d1c3
0f843fffffff
je nt!PspReferenceCidTableEntry
+
0x78
(fffff802`
0841d108
) Branch
*
/
for
(
INT
i
=
0
; i <
0x120
; i
+
+
)
{
/
/
fffff802`
0841d1a5
48
8b
0d
84
73
f5 ff mov rcx,qword ptr [nt!PspCidTable (fffff802`
08374530
)]
if
(
*
(PUCHAR)(ul_callJmp
+
i)
=
=
0x48
&&
*
(PUCHAR)(ul_callJmp
+
i
+
1
)
=
=
0x8b
&&
*
(PUCHAR)(ul_callJmp
+
i
+
2
)
=
=
0x0d
)
{
/
/
解析 mov 地址
INT
i_movCode
=
*
(
INT
*
)(ul_callJmp
+
i
+
3
);
DbgPrint(
"i_movCode = %p \n"
, i_movCode);
ULONG64 ul_movJmp
=
ul_callJmp
+
i
+
i_movCode
+
7
;
DbgPrint(
"ul_movJmp = %p \n"
, ul_movJmp);
/
/
得到 PspCidTable
*
tableAddr
=
ul_movJmp;
return
TRUE;
}
}
}
return
FALSE;
}
/
*
解析一级表
/
/
By: LyShark.com
BaseAddr:一级表的基地址
index1:第几个一级表
index2:第几个二级表
*
/
VOID parse_table_1(ULONG64 BaseAddr,
INT
index1,
INT
index2)
{
/
/
遍历一级表(每个表项大小
16
),表大小
4k
,所以遍历
4096
/
16
=
526
次
PEPROCESS p_eprocess
=
NULL;
PETHREAD p_ethread
=
NULL;
INT
i_id
=
0
;
for
(
INT
i
=
0
; i <
256
; i
+
+
)
{
if
(!MmIsAddressValid((PVOID64)(BaseAddr
+
i
*
16
)))
{
DbgPrint(
"非法地址= %p \n"
, BaseAddr
+
i
*
16
);
continue
;
}
ULONG64 ul_recode
=
*
(PULONG64)(BaseAddr
+
i
*
16
);
/
/
解密
ULONG64 ul_decode
=
(LONG64)ul_recode >>
0x10
;
ul_decode &
=
0xfffffffffffffff0
;
/
/
判断是进程还是线程
i_id
=
i
*
4
+
1024
*
index1
+
512
*
index2
*
1024
;
if
(PsLookupProcessByProcessId(i_id, &p_eprocess)
=
=
STATUS_SUCCESS)
{
DbgPrint(
"进程PID: %d | ID: %d | 内存地址: %p | 对象: %p \n"
, i_id, i, BaseAddr
+
i
*
0x10
, ul_decode);
}
else
if
(PsLookupThreadByThreadId(i_id, &p_ethread)
=
=
STATUS_SUCCESS)
{
DbgPrint(
"线程TID: %d | ID: %d | 内存地址: %p | 对象: %p \n"
, i_id, i, BaseAddr
+
i
*
0x10
, ul_decode);
}
}
}
/
*
解析二级表
/
/
By: LyShark.com
BaseAddr:二级表基地址
index2:第几个二级表
*
/
VOID parse_table_2(ULONG64 BaseAddr,
INT
index2)
{
/
/
遍历二级表(每个表项大小
8
),表大小
4k
,所以遍历
4096
/
8
=
512
次
ULONG64 ul_baseAddr_1
=
0
;
for
(
INT
i
=
0
; i <
512
; i
+
+
)
{
if
(!MmIsAddressValid((PVOID64)(BaseAddr
+
i
*
8
)))
{
DbgPrint(
"非法二级表指针(1):%p \n"
, BaseAddr
+
i
*
8
);
continue
;
}
if
(!MmIsAddressValid((PVOID64)
*
(PULONG64)(BaseAddr
+
i
*
8
)))
{
DbgPrint(
"非法二级表指针(2):%p \n"
, BaseAddr
+
i
*
8
);
continue
;
}
ul_baseAddr_1
=
*
(PULONG64)(BaseAddr
+
i
*
8
);
parse_table_1(ul_baseAddr_1, i, index2);
}
}
/
*
解析三级表
/
/
By: LyShark.com
BaseAddr:三级表基地址
*
/
VOID parse_table_3(ULONG64 BaseAddr)
{
/
/
遍历三级表(每个表项大小
8
),表大小
4k
,所以遍历
4096
/
8
=
512
次
ULONG64 ul_baseAddr_2
=
0
;
for
(
INT
i
=
0
; i <
512
; i
+
+
)
{
if
(!MmIsAddressValid((PVOID64)(BaseAddr
+
i
*
8
)))
{
continue
;
}
if
(!MmIsAddressValid((PVOID64)
*
(PULONG64)(BaseAddr
+
i
*
8
)))
{
continue
;
}
ul_baseAddr_2
=
*
(PULONG64)(BaseAddr
+
i
*
8
);
parse_table_2(ul_baseAddr_2, i);
}
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint((
"Uninstall Driver Is OK \n"
));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
DbgPrint((
"hello lyshark.com \n"
));
ULONG64 tableAddr
=
0
;
get_PspCidTable(&tableAddr);
DbgPrint(
"PspCidTable Address = %p \n"
, tableAddr);
/
/
获取 _HANDLE_TABLE 的 TableCode
ULONG64 ul_tableCode
=
*
(PULONG64)(((ULONG64)
*
(PULONG64)tableAddr)
+
8
);
DbgPrint(
"ul_tableCode = %p \n"
, ul_tableCode);
/
/
取低
2
位(二级制
11
=
3
)
INT
i_low2
=
ul_tableCode &
3
;
DbgPrint(
"i_low2 = %X \n"
, i_low2);
/
/
一级表
if
(i_low2
=
=
0
)
{
/
/
TableCode 低
2
位抹零(二级制
11
=
3
)
parse_table_1(ul_tableCode & (~
3
),
0
,
0
);
}
/
/
二级表
else
if
(i_low2
=
=
1
)
{
/
/
TableCode 低
2
位抹零(二级制
11
=
3
)
parse_table_2(ul_tableCode & (~
3
),
0
);
}
/
/
三级表
else
if
(i_low2
=
=
2
)
{
/
/
TableCode 低
2
位抹零(二级制
11
=
3
)
parse_table_3(ul_tableCode & (~
3
));
}
else
{
DbgPrint(
"LyShark提示: 错误,非法! "
);
return
FALSE;
}
Driver
-
>DriverUnload
=
UnDriver;
return
STATUS_SUCCESS;
}