第3个回答 2011-03-29
def struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
VOID Hook();
ULONG JmpAddress;//要HOOK到的地址
ULONG OldServiceAddress;//原来NtShutdownSystem的地址
__declspec(naked) NTSTATUS __stdcall NtShutdownSystem(PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId)
{
//这里填写HOOK后要做的一些事情
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = OnUnload;
DbgPrint("Unhooker load");
Hook();
return STATUS_SUCCESS;
}
VOID Hook()
{
ULONG Address; //获得原函数地址
Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xF9 * 4;//0xF9为NtShutdownSystem服务ID
DbgPrint("Address:0x%08X",Address);
OldServiceAddress = *(ULONG*)Address;//保存原来NtShutdownSystem的地址
DbgPrint("OldServiceAddress:0x%08X",OldServiceAddress);
DbgPrint("MyNtShutdownSystem:0x%08X",MyNtShutdownSystem);
JmpAddress = (ULONG)MyNtShutdownSystem ; //跳转到MyNtShutdownSystem函数,即是跳转到我们自己的处理函数
DbgPrint("JmpAddress:0x%08X",JmpAddress);
__asm{//去掉内存保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
*((ULONG*)Address) = (ULONG)NtShutdownSystem;//HOOK SSDT
__asm{//恢复内存保护
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}