A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #1112  by __Genius__
 Tue May 18, 2010 9:11 am
Hey there, I'm trying to hook ZwTerminateProcess with the following code :
Code: Select all
#include "ntddk.h"
#include "stdafx.h"
#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.CounterTableBase[ *(PULONG)((PUCHAR)_function+1)]
extern NTSTATUS ZwTerminateProcess(IN HANDLE ProcessHandle,IN NTSTATUS ExitStatus); 
#define DEBUG
typedef unsigned long DWORD, *PDWORD;
typedef unsigned char BYTE, *PBYTE;
void hook(void);
void Unhook();
NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING);
void Unload_driver(IN PDRIVER_OBJECT);
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
	PDWORD ServiceTable;
    PDWORD CounterTableBase;
    DWORD  ServiceLimit;
    PBYTE  ArgumentTable;
} ServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
typedef NTSYSAPI NTSTATUS (*ZWTERMINATEPROCESS)
(
    IN HANDLE  ProcessHandle,
    IN NTSTATUS  ExitStatus
);
ZWTERMINATEPROCESS OrigZwTerminateProcess;
extern ZWTERMINATEPROCESS OrigZwTerminateProcess;

NTSTATUS FakeZwTerminateProcess(
    IN HANDLE  ProcessHandle,
    IN NTSTATUS  ExitStatus)
{
     return STATUS_PROCESS_IS_TERMINATING;
}

PMDL  g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)

void Hook(void)
{
    _asm{cli}
    OrigZwTerminateProcess = (ZWTERMINATEPROCESS) (SYSTEMSERVICE(ZwTerminateProcess));
    (ZWTERMINATEPROCESS) (SYSTEMSERVICE(ZwTerminateProcess)) =    FakeZwTerminateProcess;
    _asm{sti}
}

void Unhook()
{
    _asm{cli}
    (ZWTERMINATEPROCESS) (SYSTEMSERVICE(ZwTerminateProcess)) = OrigZwTerminateProcess; // restore
    _asm{sti}
}

void OnUnload(IN PDRIVER_OBJECT DriverObject)
{
	Unhook();
	if(g_pmdlSystemCall)
	{
		MmUnmapLockedPages(MappedSystemCallTable,g_pmdlSystemCall) ;
		IoFreeMdl(g_pmdlSystemCall) ;
	}
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, 
					 IN PUNICODE_STRING theRegistryPath)
{
   theDriverObject->DriverUnload  = OnUnload; 
   g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.CounterTableBase, KeServiceDescriptorTable.ServiceLimit*4);
   if(!g_pmdlSystemCall)
      return STATUS_UNSUCCESSFUL;
   MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
   g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
   MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
   Hook();                              
   return STATUS_SUCCESS;
}
don't know where's the problem but everytime I load it into kernel I get BSoD (test on VirtualBox) ... .
prior to the above code I didn't use MDL for defining a writable memory section, and when defining Memory descriptor list I got BSoD .

with much of effort and trying to edit the code and fix the problem I still have the BSoD issue .

Any help would be appreciated .
thanks .
 #1113  by Alex
 Tue May 18, 2010 12:41 pm
Here is corrected source.
Code: Select all
#include "ntddk.h"

typedef struct _SERVICE_DESCRIPTOR_TABLE
{
	PULONG ServiceTableBase;
	PULONG ServiceCounterTableBase;
	ULONG NumberOfServices;
	PUCHAR ParamTableBase;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;

__declspec(dllimport) SERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

#define SYSCALL_INDEX(Service) *(PULONG)((PUCHAR)Service+1)

#define HOOK_SYSCALL(Service, HookService, OriginalService) \
        OriginalService = (PVOID)InterlockedExchange((PULONG)&SystemServiceTable[SYSCALL_INDEX(Service)], (ULONG)HookService)

#define UNHOOK_SYSCALL(Service, HookService, OriginalService) \
        InterlockedExchange((PULONG)&SystemServiceTable[SYSCALL_INDEX(Service)], (ULONG)OriginalService)

BOOLEAN Hooked = FALSE;
MDL *Mdl = NULL;
PVOID *SystemServiceTable; 


NTSYSAPI
NTSTATUS
NTAPI
ZwTerminateProcess(
	IN HANDLE ProcessHandle,
    IN NTSTATUS ExitStatus
);

typedef NTSTATUS (NTAPI *NT_TERMINATE_PROCESS)
(
	IN HANDLE ProcessHandle,
    IN NTSTATUS ExitStatus
);

NT_TERMINATE_PROCESS PtrNtTerminateProcess;


NTSTATUS HookNtTerminateProcess(
    IN HANDLE ProcessHandle,
    IN NTSTATUS ExitStatus)
{
	DbgPrint(">> HOOK...\n");

	return STATUS_ACCESS_DENIED;
}

VOID DriverUnload(
	IN DRIVER_OBJECT *DriverObject)
{
	if(Hooked)
	{
		UNHOOK_SYSCALL(ZwTerminateProcess, HookNtTerminateProcess, PtrNtTerminateProcess);

		if(Mdl)
		{
			MmUnmapLockedPages(SystemServiceTable, Mdl);

			IoFreeMdl(Mdl);
		}
	}
}

NTSTATUS DriverEntry(
    IN DRIVER_OBJECT *DriverObject,
    IN UNICODE_STRING *RegistryPath)
{
    DriverObject->DriverUnload = DriverUnload;


	Mdl = IoAllocateMdl(
						KeServiceDescriptorTable.ServiceTableBase,                 // VirtualAddress
						KeServiceDescriptorTable.NumberOfServices * sizeof(ULONG), // Length
						FALSE,                                                     // SecondaryBuffer
						FALSE,                                                     // ChargeQuota
						NULL);                                                     // Irp

	if(Mdl)
	{
		MmBuildMdlForNonPagedPool(Mdl);

		Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;

		SystemServiceTable = MmMapLockedPages(Mdl, KernelMode);

		if(MmIsAddressValid(SystemServiceTable))
		{
			HOOK_SYSCALL(ZwTerminateProcess, HookNtTerminateProcess, PtrNtTerminateProcess);

			Hooked = TRUE;
		}
	}

    return STATUS_SUCCESS;
}
 #7258  by StriderH2
 Thu Jul 14, 2011 4:01 am
I get build errors:
1>c:\winddk\7600.16385.1\zwdriverkillre\projects\test\ho.obj : error LNK2019: unresolved external symbol __imp__ZwOpenThread@12 referenced in function _DriverEntry@8
1>c:\winddk\7600.16385.1\zwdriverkillre\projects\test\objchk_wxp_x86\i386\wcs.sys : error LNK1120: 1 unresolved externals
Code: Select all
#include "ntddk.h"
typedef struct ServiceDescriptorEntry {
        unsigned int *ServiceTableBase;
        unsigned int *ServiceCounterTableBase; /*Used only in checked build*/
        unsigned int NumberOfServices;
        unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
/*Very useful macros*/
#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
typedef DWORD (ULONG);
PMDL  g_pmdlSystemCall;
PVOID *MappedSystemCallTable;
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig )  \
       _Orig = (PVOID) InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig )  \
       InterlockedExchange( (PLONG) &MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
NTSYSAPI 
NTSTATUS 
NTAPI ZwOpenThread(OUT PHANDLE ThreadHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS NewZwOpenThread(OUT PHANDLE ThreadHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);

 typedef NTSTATUS (*ZWOPENTHREAD)(OUT PHANDLE ThreadHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId OPTIONAL);
/*OldZwOpenProcess points to the original function*/
ZWOPENTHREAD       OldZwOpenThread;        
     

NTSTATUS NewZwOpenThread(OUT PHANDLE ThreadHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId )
{
   HANDLE ProcessId; 
  OldZwOpenThread(ThreadHandle,AccessMask,ObjectAttributes,ClientId);
   __try /*we do this to avoid crashes*/
{
    ProcessId = ClientId->UniqueProcess;
}
__except(EXCEPTION_EXECUTE_HANDLER) /*we do this to avoid crashes*/
{
/*DbgPrint("Exception");*/
    return STATUS_INVALID_PARAMETER;
}
if (ProcessId == (HANDLE)1234) /*Check if the PID matches our protected process PID*/
{
   return STATUS_ACCESS_DENIED;
}
else
//DbgPrint("%d bad",pid);
// Needed.
ThreadHandle = NULL;
return OldZwOpenThread(ThreadHandle,AccessMask,ObjectAttributes,ClientId);

}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)  
{
        g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4);
   if(!g_pmdlSystemCall)
      return STATUS_UNSUCCESSFUL; //STATUS_UNSUCCESSFUL;
   MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
   /* Change the flags of the MDL*/
   g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
   MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);
   /* hook system calls*/
   HOOK_SYSCALL( ZwOpenThread, NewZwOpenThread, OldZwOpenThread);
   return STATUS_SUCCESS;
         return 0;
         }

 #7259  by EP_X0FF
 Thu Jul 14, 2011 4:22 am
Well you code is incorrect.
You double calling original handler BEFORE_PROCESSING and AFTER_PROCESSING. What is the point? Also there should ProbeForRead in try/except (google for ProbeForReadSmallStructure).
If function is undeclared in headers but exported in lib, you can declare it yourself. Or use alternative methods to get function address.