SSDT hook技术是一种很老的技术了,但是作为新手还是有必要知道和学习的。首先说一下 KeServiceDescriptorTable ,通过WRK可以找到该函数的原型
typedef struct _KSERVICE_TABLE_DESCRIPTOR {
PULONG_PTR Base;
PULONG Count;
ULONG Limit;
PUCHAR Number;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
该函数为导出,首先要到处该函数,才能使用
废话不多说了,贴出自己写的代码 (vs2010+WDK)
//SSDT.h
typedef struct _KSERVICE_TABLE_DESCRIPTOR {
PULONG_PTR Base;
PULONG Count;
ULONG Limit;
PUCHAR Number;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR; //申明KeServiceDescriptorTable结构,通过wrk查找
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;//导出该函数
//获取SSDT的基地址
ULONG GetSSDTAddr(int _index)
{
return KeServiceDescriptorTable->Base[_index];
}
//暴力去除页面保护,如果不去除无法修改
void off()
{
__asm
{
cli
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
};
//恢复页面保护,否则会蓝屏
void on()
{
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
};
typedef NTSTATUS (__stdcall *NewNtOpenProcess)
(
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
);
extern "C" NTSTATUS
PsLookupProcessByProcessId(
__in HANDLE ProcessId,
__deref_out PEPROCESS *Process
);
extern "C" UCHAR *
PsGetProcessImageFileName(
__in PEPROCESS Process
);
//全局变量,用于存放原始地址
ULONG oldaddr;
NewNtOpenProcess _NewNtOpenProcess;
//自己的HOOK函数
NTSTATUS MyNtOpenProcess(
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
NTSTATUS _ntstatus;
PEPROCESS _eprocess;
_ntstatus=_NewNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
if (NT_SUCCESS(_ntstatus))
{
//通过PsLookupProcessByProcessId遍历出所有进程ID,并存放在_eprocess
_ntstatus=PsLookupProcessByProcessId(ClientId->UniqueProcess,&_eprocess);
if (NT_SUCCESS(_ntstatus))
{
//获取所有的进程名称
CHAR *ProcessN=(CHAR*)PsGetProcessImageFileName(_eprocess);
//判断所有进程名称内存地址是否有效
if (MmIsAddressValid(ProcessN)==TRUE)
{
/*DbgPrint("%s",ProcessN)*/;
//通过与字符串比较获取进程中是否有相同的进程名称
if (strcmp(ProcessN,"calc.exe")==0)
{
//如果存在就返回无权操作
_ntstatus=STATUS_ACCESS_DENIED;
}
}
}
ObDereferenceObject(_eprocess);
}
return _ntstatus;
}
//hook方法
void SSDTHOOKNtOpenProcess()
{
//保存旧的地址
oldaddr=GetSSDTAddr(122);
_NewNtOpenProcess=(NewNtOpenProcess)oldaddr;
off();
KeServiceDescriptorTable->Base[122]=(ULONG)MyNtOpenProcess;//
on();
}
void UnHook()
{
off();
KeServiceDescriptorTable->Base[122]=oldaddr;
on();
}
到这里基本完成了,测试也是通过的,如果想要源代码,请加QQ:361121687 有不对的地方请指正
下次说说保护文件吧,然后通过不同测试写一下内核的各种hook方法。