emmmmm 这个其实 和Windows x86差不多~~~~~
这里参考了 看雪论坛分享的 资料 作者是 Tesla.Angela(GDUT.HWL)
下面是代码
#include <ntddk.h>
#include <windef.h>
#pragma intrinsic(__readmsr)
typedef struct _SYSTEM_SERVICE_TABLE{
PLONG ServiceTableBase;
PVOID ServiceCounterTableBase;
ULONGLONG NumberOfServices;
PVOID ParamTableBase;
} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
PSYSTEM_SERVICE_TABLE ssdt;
ULONGLONG GetSsdt()
{
PUCHAR startaddr = (PUCHAR)__readmsr(0xc0000082);//这里是两个下划线
PUCHAR Endaddr = startaddr + 0x500;
PUCHAR i = NULL;
UCHAR b1, b2, b3;
ULONG temp = 0;
ULONGLONG addr = 0;
for (i = startaddr; i < Endaddr; i++)
{
b1 = *i;
b2 = *(i + 1);
b3 = *(i + 2);
if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15)
{
memcpy(&temp, i + 3, 4);
addr = (ULONGLONG)temp + (ULONGLONG)i + 7;
return addr;
}
}
return 0;
}
ULONGLONG GetFunctionAddress(ULONGLONG index)
{
LONG Temp;
ULONGLONG temp,ret=0;
temp = (ULONGLONG)ssdt + 4 * index;
Temp = *(PLONG)temp;
Temp = Temp >> 4;
ret = (ULONGLONG)ssdt + (LONG64)Temp;
return ret;
}
VOID DriverUnload(PDRIVER_OBJECT driver)
{
KdPrint(("goodbye"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
ULONGLONG i = 0;
PSYSTEM_SERVICE_TABLE add=NULL;
ULONGLONG addr = GetSsdt();
if (addr== 0)
{
KdPrint(("大哥对不起 没有找到ssdt!\n"));
return STATUS_SUCCESS;
}
ssdt = (PSYSTEM_SERVICE_TABLE)addr;
KdPrint(("sstd :%d\n", ssdt->NumberOfServices));
for (i = 0; i < ssdt->NumberOfServices; i++)
{
KdPrint(("【%d】%x", i, (ssdt->ServiceTableBase[i])));
}
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
这是效果图
然后 这里说一下 总结吧
其实这里也是一步一步调试出来的
因为x64的ssdt 表没有导出 所以需要动态导出ssdt 表 这个比较坑爹
不过 看教程 比较厉害的是通过读取 C0000082 寄存器,能够得到 KiSystemCall64 的地址, 这个虽然不知道前辈们怎么得出来的 但是可以肯定的是,这个帮了我们的大忙
fffff800`03cc7ff2 4c8d1547782300 lea r10,[nt!KeServiceDescriptorTable
然后我们的 KeServiceDescriptorTable 的特征码就是 4c8d15
而 我们换一下特征码(4c8d1d),就能获得 KeServiceDescriptorTableShadow 的地址了。
然后 这样我们就能得出 他们的地址了 然后就可以枚举地址了
然后 至于 根据 服务号 然后推断出 地址的
mov rax, rcx ;rcx=Native API 的 index
lea r10,[rdx] ;rdx=ssdt 基址
mov edi,eax
shr edi,7
and edi,20h
mov r10, qword ptr [r10+rdi]
movsxd r11,dword ptr [r10+rax]
mov rax,r11
sar r11,4
add r10,r11
mov rax,r10 ret
(以上代码是 作者Tesla.Angela(GDUT.HWL) 所总结)
但是驱动不支持汇编 那么只能 转化成 C或者 shellcode 了
C的呢 我上面有
下面shellcode 我直接放出 Tesla.Angela(GDUT.HWL) 的代码了
VOID Initxxxx()
{
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";
/*
mov rax, rcx ;rcx=index
lea r10,[rdx] ;rdx=ssdt
mov edi,eax
shr edi,7
and edi,20h
mov r10, qword ptr [r10+rdi]
movsxd r11,dword ptr [r10+rax*4]
mov rax,r11
sar r11,4
add r10,r11
mov rax,r10
ret
*/
scfn=ExAllocatePool(NonPagedPool,36);
memcpy(scfn,strShellCode,36);
}
也没有什么东西~~