求帮望解决x64 SSDT NtUserBuildHwndList问题
求帮望解决下x64位SSDT hook 代码是引用别人的代码.其他函数的HOOK没问题唯独NtUserBuildHwndList错误....
求帮望解决
00000015 13:07:25 NTUSERBUILDHWNDLISTHook: 0 0 0 fffffa8000000000 fffff96000000000 1fa002010000 0 //NtUserBuildHwndList参数
00000016 13:07:25 NTUSERBUILDHWNDLISTHook: c0000008 0 //NtUserBuildHwndList返回值
00000017 13:07:25 NTUSERBUILDHWNDLISTHook: 0 0 0 fffffa8000000000 fffff96000000000 1fa002010000 0 //NtUserBuildHwndList参数
00000018 13:07:25 NTUSERBUILDHWNDLISTHook: c0000008 0 //NtUserBuildHwndList返回值
00000019 13:07:26 NTUSERBUILDHWNDLISTHook: 0 0 0 fffffa8000000000 fffff96000000000 1fa002010000 0 //NtUserBuildHwndList参数
00000020 13:07:26 NTUSERBUILDHWNDLISTHook: c0000008 0 //NtUserBuildHwndList返回值
00000021 13:07:43 NTUSERBUILDHWNDLISTHook: 0 2028c 1 0 0 1f8002000000 8e2f8 //NtUserBuildHwndList参数00000022 13:07:43 NTUSERBUILDHWNDLISTHook: c0000023 0 //NtUserBuildHwndList返回值
x64错误代码0xc0000008和c0000023
//余下代码和解释
//替换函数
NTSTATUS NTUSERBUILDHWNDLISTHook(
HDESK hdesk,
HWND hwndNext,
ULONG fEnumChildren,
DWORD idThread,
UINT cHwndMax,
HWND *phwndFirst,
ULONG *pcHwndNeeded)
{
NTSTATUS status;
//打印参数
DbgPrint("NTUSERBUILDHWNDLISTHook: %llx %llx %llx %llx %llx %llx %llx",hdesk,hwndNext,fEnumChildren,idThread,cHwndMax,phwndFirst,pcHwndNeeded);
//调用真正函数
status = g_NtUserBuildHwndList(hdesk,
hwndNext,
fEnumChildren,
idThread,
cHwndMax,
phwndFirst,
pcHwndNeeded);
//打印返回值
DbgPrint("NTUSERBUILDHWNDLISTHook: %llx %llx",status,hdesk);
return status;
}
//替换SSDT函数
VOID ModifySSSDT(ULONG64 Index, ULONG64 Address)
{
ULONGLONG W32pServiceTable=0, qwTemp=0;
LONG dwTemp=0;
PSYSTEM_SERVICE_TABLE pWin32k;
KIRQL irql;
DbgPrint("ModifySSSDTAddress: %llx %llx",Address,Index);
pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE)); //4*8
W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase);
qwTemp = W32pServiceTable + 4 * (Index);
dwTemp = (LONG)(Address - W32pServiceTable);
DbgPrint("ModifySSSDTAddress: %llx %llx",dwTemp,Address - W32pServiceTable);
dwTemp = dwTemp << 4; //DbgPrint("*(PLONG)qwTemp: %x, dwTemp: %x",*(PLONG)qwTemp,dwTemp);
DbgPrint("ModifySSSDTAddress: %llx %llx",dwTemp,qwTemp);
irql=WPOFFx64();
*(PLONG)qwTemp = dwTemp;
WPONx64(irql);
}
//写入替换函数
//为什么要写入机器码我解释下.......由于x64的读取SSDT是根据一个基址+偏于的 基址是64位的 偏于是32位的,所以我们无法直接替换函数地址进去....我做的解决是从ssdt的基址
//查找14个0x90机器码作为我的中转在jmp [到我的函数];这样就可以跳转64位地址了......
//还有很多种解决方案,或者重在SSDT基址这个有点复杂
VOID HOOK_ShadowSSDT(ULONG64 X_hookAddress,ULONG64 Index,ULONGLONG MyFun)
{
KIRQL irql;
ULONG64 myfun;
UCHAR jmp_code[]="\xFF\x25\x00\x00\x00\x00\x90\x90\x90\x90\x90\x90\x90\x90"; //需要14字节+4字节(jmp [我的函数])
//代理函数地址
myfun=MyFun;//取函数地址
DbgPrint("HOOK_SSSDTmyfun: %llx",myfun);
//填充shellcode
memcpy(jmp_code+6,&myfun,8);
irql=WPOFFx64();
memcpy((PVOID)(X_hookAddress),jmp_code,14);//写入中转的机器码
DbgPrint("HOOK_SSSDTmyfun: %s %llx",jmp_code,X_hookAddress);//输机器码和HOOK地址
WPONx64(irql);
ModifySSSDT(Index, X_hookAddress);//替换SSDT表
DbgPrint("HOOK_SSSDT OK!");
}
//根据序号获取函数
ULONGLONG GetSSSDTFuncCurAddr64(ULONG64 Index)
{
ULONGLONG W32pServiceTable=0, qwTemp=0;
LONG dwTemp=0;
PSYSTEM_SERVICE_TABLE pWin32k;
pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE));
W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase);
ul64W32pServiceTable = W32pServiceTable;
qwTemp = W32pServiceTable + 4 * (Index); //这里是获得偏移地址的位置,要HOOK的话修改这里即可
dwTemp = *(PLONG)qwTemp;
dwTemp = dwTemp >> 4;
qwTemp = W32pServiceTable + (LONG64)dwTemp;
return qwTemp;
}
//获取x64 ShadowSSDT特征
ULONGLONG GetKeServiceDescriptorTableShadow64()
{
PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);
PUCHAR EndSearchAddress = StartSearchAddress + 0x500;
PUCHAR i = NULL;
UCHAR b1=0,b2=0,b3=0;
ULONG templong=0;
ULONGLONG addr=0;
//DbgPrint("templong地址 i=: %llx",i);
for(i=StartSearchAddress;i<EndSearchAddress;i++)
{
//DbgPrint("templong地址 i=: %llx",i);
if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) )
{
b1=*i;
b2=*(i+1);
b3=*(i+2);
if( b1==0x4c && b2==0x8d && b3==0x1d ) //4c8d1d
{
memcpy(&templong,i+3,4);
// DbgPrint("templong地址: %llx",i);
// DbgPrint("templong地址: %llx",templong);
addr = (ULONGLONG)templong + (ULONGLONG)i + 7;
HookNum = (int)(i+20);
return addr;
}
}
}
return 0;
}
页:
[1]