Wednesday, August 24, 2011

Hook Specials 17 : Create oneself hook engine one out of a multitude --- SSDT Engine

Author:easystone
SSDT HOOK already is question by a platitude, There is not introduction. The basice idea of hook engine is about package hook, Becasue don't modify if, User only write routine of hook by oneself .

Because I first write these , The code is simple.
Example NtOpenProcess is hooked as MyNtOpenProcess by user, Only call HookService((ULONG)ZwOpenProcess, (ULONG)MyNtOpenProcess) in DriverEntry.
Then write oneself hook function, the interface is simple and realize.

For example:
// Unload routine , Unload hook
VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
KdPrint(("Unload Routine.\n"));
UnHookService((ULONG)ZwSetInformationFile);
UnHookService((ULONG)ZwOpenProcess);
}

// DriverEntry routine, initalize and install hook
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = Unload;
InitServicesTable();
HookService((ULONG)ZwSetInformationFile, (ULONG)MyZwSetInformationFile);
HookService((ULONG)ZwOpenProcess, (ULONG)MyNtOpenProcess);

return STATUS_SUCCESS;
}

Then only notice own function, as follow two example , First hook ZwSetInformationFile to protect test.txt can't to delete. Second example hook NtOpenProcess to PID of process is greater than 100.

Code:
// Define hook's fanction prototype
typedef
NTSTATUS
(__stdcall *ZWSETINFORMATIONFILE)(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass);
typedef
NTSTATUS
(__stdcall *NTOPENPROCESS)( OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);


NTSYSAPI
NTSTATUS
NTAPI
ZwOpenProcess( OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);

// ==============================================================
// User defined hook routine
NTSTATUS MyZwSetInformationFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass)
{
PFILE_OBJECT pFileObject;

// 在OldServiceAddressTable中取出原服务函数地址
ZWSETINFORMATIONFILE OldZwSetInformationFile =
(ZWSETINFORMATIONFILE)OldServiceAddressTable[SERVICE_ID(ZwSetInformationFile)];

NTSTATUS ret = ObReferenceObjectByHandle(FileHandle,
GENERIC_READ,
*IoFileObjectType,
KernelMode,
(PVOID*)&pFileObject,
0);
if(NT_SUCCESS(ret))
{
KdPrint(("%S opened.\n", pFileObject->FileName.Buffer));
if (wcsstr(pFileObject->FileName.Buffer, L"test.txt"))
{
KdPrint(("test.txt opened. Deny it.\n"));
return STATUS_ACCESS_DENIED;
}
}
ObDereferenceObject(pFileObject);
// Call original service function
return OldZwSetInformationFile( FileHandle, IoStatusBlock, FileInformation,
Length, FileInformationClass);
}

NTSTATUS MyNtOpenProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId )
{
NTSTATUS rc;
ULONG PID;

KPROCESSOR_MODE PreMode;


NTOPENPROCESS OldNtOpenProcess =
(NTOPENPROCESS)OldServiceAddressTable[SERVICE_ID(ZwOpenProcess)];

PreMode = ExGetPreviousMode();
if(PreMode != KernelMode)
{
__try
{
ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}
}

if(ClientId != NULL)
{
PID = (ULONG)ClientId->UniqueProcess;
if(PID > 1000)
{
return STATUS_ACCESS_DENIED;
}
}
return OldNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}

Donwloand : The code

No comments:

Post a Comment