/
/
署名权
/
/
right to sign one's name on a piece of work
/
/
PowerBy: LyShark
/
/
Email: me@lyshark.com
typedef struct _SYSTEM_SERVICE_TABLE
{
PVOID ServiceTableBase;
PVOID ServiceCounterTableBase;
ULONGLONG NumberOfServices;
PVOID ParamTableBase;
} SYSTEM_SERVICE_TABLE,
*
PSYSTEM_SERVICE_TABLE;
ULONGLONG ssdt_base_aadress;
PSYSTEM_SERVICE_TABLE KeServiceDescriptorTable;
typedef UINT64(__fastcall
*
SCFN)(UINT64, UINT64);
SCFN scfn;
/
/
解密算法
VOID DecodeSSDT()
{
UCHAR strShellCode[
36
]
=
"\x48\x8B\xC1\x4C\x8D\x12\x8B\xF8\xC1\xEF\x07\x83\xE7\x20\x4E\x8B\x14\x17\x4D\x63\x1C\x82\x49\x8B\xC3\x49\xC1\xFB\x04\x4D\x03\xD3\x49\x8B\xC2\xC3"
;
/
*
48
:
8BC1
| mov rax,rcx | rcx
=
index
4C
:
8D12
| lea r10,qword ptr ds:[rdx] | rdx
=
ssdt
8BF8
| mov edi,eax |
C1EF
07
| shr edi,
7
|
83E7
20
|
and
edi,
20
|
4E
:
8B1417
| mov r10,qword ptr ds:[rdi
+
r10] |
4D
:
631C82
| movsxd r11,dword ptr ds:[r10
+
rax
*
4
] |
49
:
8BC3
| mov rax,r11 |
49
:C1FB
04
| sar r11,
4
|
4D
:
03D3
| add r10,r11 |
49
:
8BC2
| mov rax,r10 |
C3 | ret |
*
/
scfn
=
ExAllocatePool(NonPagedPool,
36
);
memcpy(scfn, strShellCode,
36
);
}
/
/
获取 KeServiceDescriptorTable 首地址
ULONGLONG GetKeServiceDescriptorTable()
{
/
/
设置起始位置
PUCHAR StartSearchAddress
=
(PUCHAR)__readmsr(
0xC0000082
)
-
0x1806FE
;
/
/
设置结束位置
PUCHAR EndSearchAddress
=
StartSearchAddress
+
0x8192
;
DbgPrint(
"扫描起始地址: %p --> 扫描结束地址: %p \n"
, StartSearchAddress, EndSearchAddress);
PUCHAR ByteCode
=
NULL;
UCHAR OpCodeA
=
0
, OpCodeB
=
0
, OpCodeC
=
0
;
ULONGLONG addr
=
0
;
ULONG templong
=
0
;
for
(ByteCode
=
StartSearchAddress; ByteCode < EndSearchAddress; ByteCode
+
+
)
{
/
/
使用MmIsAddressValid()函数检查地址是否有页面错误
if
(MmIsAddressValid(ByteCode) && MmIsAddressValid(ByteCode
+
1
) && MmIsAddressValid(ByteCode
+
2
))
{
OpCodeA
=
*
ByteCode;
OpCodeB
=
*
(ByteCode
+
1
);
OpCodeC
=
*
(ByteCode
+
2
);
/
/
对比特征值 寻找 nt!KeServiceDescriptorTable 函数地址
/
/
LyShark.com
/
/
4c
8d
15
e5
9e
3b
00
lea r10,[nt!KeServiceDescriptorTable (fffff802`
64da4880
)]
/
/
4c
8d
1d
de
20
3a
00
lea r11,[nt!KeServiceDescriptorTableShadow (fffff802`
64d8ca80
)]
if
(OpCodeA
=
=
0x4c
&& OpCodeB
=
=
0x8d
&& OpCodeC
=
=
0x15
)
{
/
/
获取高位地址fffff802
memcpy(&templong, ByteCode
+
3
,
4
);
/
/
与低位
64da4880
地址相加得到完整地址
addr
=
(ULONGLONG)templong
+
(ULONGLONG)ByteCode
+
7
;
return
addr;
}
}
}
return
0
;
}
/
/
得到函数相对偏移地址
ULONG GetOffsetAddress(ULONGLONG FuncAddr)
{
ULONG dwtmp
=
0
;
PULONG ServiceTableBase
=
NULL;
if
(KeServiceDescriptorTable
=
=
NULL)
{
KeServiceDescriptorTable
=
(PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTable();
}
ServiceTableBase
=
(PULONG)KeServiceDescriptorTable
-
>ServiceTableBase;
dwtmp
=
(ULONG)(FuncAddr
-
(ULONGLONG)ServiceTableBase);
return
dwtmp <<
4
;
}
/
/
根据序号得到函数地址
ULONGLONG GetSSDTFunctionAddress(ULONGLONG NtApiIndex)
{
ULONGLONG ret
=
0
;
if
(ssdt_base_aadress
=
=
0
)
{
/
/
得到ssdt基地址
ssdt_base_aadress
=
GetKeServiceDescriptorTable();
}
if
(scfn
=
=
NULL)
{
DecodeSSDT();
}
ret
=
scfn(NtApiIndex, ssdt_base_aadress);
return
ret;
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DbgPrint((
"驱动程序卸载成功! \n"
));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
DbgPrint(
"hello lyshark.com \n"
);
ULONGLONG ssdt_address
=
GetKeServiceDescriptorTable();
DbgPrint(
"SSDT基地址 = %p \n"
, ssdt_address);
/
/
根据序号得到函数地址
ULONGLONG address
=
GetSSDTFunctionAddress(
51
);
DbgPrint(
"[LyShark] NtOpenFile地址 = %p \n"
, address);
/
/
得到相对SSDT的偏移量
DbgPrint(
"函数相对偏移地址 = %p \n"
, GetOffsetAddress(address));
DriverObject
-
>DriverUnload
=
UnDriver;
return
STATUS_SUCCESS;
}