A、Shadow SSDT表基址定位
B、Shadow SSDT表结构
C、Shadow SSDT HOOK
KeServiceDescriptorTable //系统描述符表 extern
KeServiceDescriptorTableShadow //影子系统描述符表 win32k.sys
bp win32k!NtUserPostMessage
bp win32k!NtUserShowWindow
bp win32k!NtUserFindWindow
bp win32k!NtUserDestroyWindow
bp win32k!NtUserPostMessage
Shadow SSDT表基址定位
系统只提供了KeServiceDescriptorTable导出
KeServiceDescriptorTableShadow是个未导出结构
dd poi(KeServiceDescriptorTable-0x40+0x10) //XP
RtlGetVersion
PsGetVersion
Windows 2000: dwMajorVersion = 5 dwMinorVersion = 0
Windows XP: dwMajorVersion = 5 dwMinorVersion = 1
Windows 2003: dwMajorVersion = 5 dwMinorVersion = 1
Windows Vista: dwMajorVersion = 6
Operating system | Version number | dwMajorVersion | dwMinorVersion | Other |
Windows 7 | 6.1 | 6 | 1 | OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION |
Windows Server 2008 R2 | 6.1 | 6 | 1 | OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION |
Windows Server 2008 | 6.0 | 6 | 0 | OSVERSIONINFOEX.wProductType != VER_NT_WORKSTATION |
Windows Vista | 6.0 | 6 | 0 | OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION |
Windows Server 2003 R2 | 5.2 | 5 | 2 | GetSystemMetrics(SM_SERVERR2) != 0 |
Windows Home Server | 5.2 | 5 | 2 | OSVERSIONINFOEX.wSuiteMask & VER_SUITE_WH_SERVER |
Windows Server 2003 | 5.2 | 5 | 2 | GetSystemMetrics(SM_SERVERR2) == 0 |
Windows XP Professional x64 Edition | 5.2 | 5 | 2 | (OSVERSIONINFOEX.wProductType == VER_NT_WORKSTATION) && (SYSTEM_INFO.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) |
Windows XP | 5.1 | 5 | 1 | Not applicable |
Windows 2000 | 5.0 | 5 | 0 | Not applicable |
DWORD Get_KeServiceDescriptorTableShadow_Addr()
{ DWORD KeServiceDescriptorTableShadow=0;
DWORD Version=GetVersion();
switch (Version )
{
case VERSION_2K:
KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable+0xE0;
break;
case VERSION_2K3:
break;
case VERSION_XP:
KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable-0x40;
break;
default:
break;
}
return KeServiceDescriptorTableShadow;
}
dd poi(KeServiceDescriptorTableShadow+10) ///SSDT Shadow Base
NtUserDestroyWindow //ZwTerminateProcess
NtUserFindWindowEx
NtUserSetWindowLong
NtUserPostMessage
NtUserGetForegroundWindow
#define VERSION_2K 50
#define VERSION_XP 51
#define VERSION_2K3 52
#define VERSION_XP64 52
#define VERSION_2K3_R2 52
#define VERSION_VISTA 60
#define VERSION_SERVER2008 60
#define VERSION_WIN7 61
#define VERSION_SERVER2008_R2 61
#pragma PAGECODE
DWORD GetVersion()
{ ULONG rtn=0;
ULONG MajorVersion,MinorVersion,BuildNumber;
PsGetVersion(&MajorVersion,&MinorVersion,&BuildNumber,NULL);
rtn=MajorVersion;
rtn=rtn *10;
rtn+=MinorVersion;
return rtn;
}
#pragma PAGECODE
DWORD Get_KeServiceDescriptorTableShadow_Addr()
{ DWORD KeServiceDescriptorTableShadow=0;
DWORD Version=GetVersion();
switch (Version )
{
case VERSION_2K:
KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable+0xE0;
break;
case VERSION_2K3:
break;
case VERSION_XP:
KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable-0x40;
break;
default:
break;
}
return KeServiceDescriptorTableShadow;
}
#pragma PAGECODE
VOID Show_SSDTShadowList()
{
KdPrint(("Entry Show_SSDTShadowList \n"));
DWORD TableBase=Get_KeServiceDescriptorTableShadow_Addr();
TableBase=TableBase+0x10;
DWORD TableCount=TableBase+8;
DWORD count=*((PDWORD)TableCount);
KdPrint(("SSDT_Shadow Base=%x Count=%x\n",TableBase,count));
//__asm int 3
PDWORD CFun_Addr=PDWORD(TableBase);
CFun_Addr=PDWORD(*CFun_Addr);
for (DWORD i=0;i<count;i++)
{
KdPrint(("\n %d=%x\n",i,*CFun_Addr ));
CFun_Addr++;
//__asm int 3
}
}
HWND myh;
typedef BOOL (__stdcall *PNtUserDestroyWindow)(HWND hwnd);
PNtUserDestroyWindow Old_NtUserDestroyWindow,Cur_NtUserDestroyWindow;
#pragma PAGECODE
BOOL __stdcall My_NtUserDestroyWindow(HWND h)
{
KdPrint(("h=%x \n",h));
if (h==myh)
{
KdPrint(("被保护窗口h=%x \n",h));
return FALSE;
}else return Old_NtUserDestroyWindow(h);
}
#pragma PAGECODE
VOID SSDT_HOOK_NtUserDestroyWindow() //355
{ KdPrint(("Entry Show_SSDTShadowList \n"));
DWORD TableBase=Get_KeServiceDescriptorTableShadow_Addr();
TableBase=TableBase+0x10;
DWORD TableCount=TableBase+8;
DWORD count=*((PDWORD)TableCount);
KdPrint(("SSDT_Shadow Base=%x Count=%x\n",TableBase,count));
//__asm int 3
PDWORD CFun_Addr=PDWORD(TableBase);
CFun_Addr=PDWORD(*CFun_Addr);
CFun_Addr+=355;
Old_NtUserDestroyWindow=(PNtUserDestroyWindow)(*CFun_Addr);
KdPrint(("\n NtUserDestroyWindow当前地址=%x,%x \n",CFun_Addr,*CFun_Addr));
__asm //去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
*CFun_Addr=(DWORD)(&My_NtUserDestroyWindow);
KdPrint(("\n NtUserDestroyWindow HOOK后地址=%x,%x \n",CFun_Addr,*CFun_Addr));
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
}
#pragma PAGECODE
VOID SSDT_UNHOOK_NtUserDestroyWindow() //335
{
KdPrint(("Entry Show_SSDTShadowList \n"));
DWORD TableBase=Get_KeServiceDescriptorTableShadow_Addr();
TableBase=TableBase+0x10;
DWORD TableCount=TableBase+8;
DWORD count=*((PDWORD)TableCount);
KdPrint(("SSDT_Shadow Base=%x Count=%x\n",TableBase,count));
//__asm int 3
PDWORD CFun_Addr=PDWORD(TableBase);
CFun_Addr=PDWORD(*CFun_Addr);
CFun_Addr+=355;
*CFun_Addr=(DWORD)(Old_NtUserDestroyWindow);