Results 1 to 1 of 1
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    SSDT Shadow Unhook in Ring0

    This source shows how to deal with kernel functions from the Ring0.
    Example, RestoreShadow.C
    Code:
    #include <ntddk.h>
    #include "RestoreShadow.h"
    #include "dbghelp.h"
    #include "LDasm.h"
    
    NTKERNELAPI
    NTSTATUS
    KeAddSystemServiceTable(
    			IN PULONG_PTR Base,
    			IN PULONG Count OPTIONAL,
    			IN ULONG Limit,
    			IN PUCHAR Number,
    			IN ULONG Index
    			);
    
    typedef struct _KSERVICE_TABLE_DESCRIPTOR
    {
    	PULONG_PTR	Base;
    	PULONG	Count;
    	ULONG	Limit;
    	PUCHAR	Number;
    }
    KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
    
    typedef struct _LDR_DATA_TABLE_ENTRY
    {
    	LIST_ENTRY InLoadOrderLinks;
    	LIST_ENTRY InMemoryOrderLinks;
    	LIST_ENTRY InInitializationOrderLinks;
    	PVOID DllBase;
    	PVOID EntryPoint;
    	ULONG SizeOfImage;
    	UNICODE_STRING FullDllName;
    	UNICODE_STRING BaseDllName;
    	ULONG Flags;
    	USHORT LoadCount;
    	USHORT TlsIndex;
    	union {
    		LIST_ENTRY HashLinks;
    		struct
    		{
    			PVOID SectionPointer;
    			ULONG CheckSum;
    		};
    	};
    	union {
    		struct
    		{
    			ULONG TimeDateStamp;
    		};
    		struct
    		{
    			PVOID LoadedImports;
    		};
    	};
    	struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
    	PVOID PatchInformation;
    }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
    
    
    
    PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow = NULL;
    
    PVOID	pWin32kBase = NULL;
    
    //===========================================
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);
    NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
    VOID DriverUnload(PDRIVER_OBJECT pDriverObj);
    #ifdef ALLOC_PRAGMA
    #pragma alloc_text(INIT, DriverEntry)
    #pragma alloc_text(PAGE, DispatchCreate)
    #pragma alloc_text(PAGE, DispatchClose)
    #pragma alloc_text(PAGE, DriverUnload)
    #endif // ALLOC_PRAGMA 
    //////////////////////////////////////////////////////////////////////////
    VOID GetWin32kBase(PDRIVER_OBJECT pDriverObj);
    VOID GetSSDTShadowBase();
    NTSTATUS RestoreShadow();
    ULONG RVAToRaw(PVOID lpBase,ULONG VirtualAddress);
    //==========================================
    NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
    {
    	NTSTATUS status = STATUS_SUCCESS;
    	UNICODE_STRING ustrLinkName;
    	UNICODE_STRING ustrDevName;
    	PDEVICE_OBJECT pDevObj;
    
    	dprintf("DriverEntry: %S\n", pRegistryString->Buffer);
    
    	// Create dispatch points for device control, create, close.
    	pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
    	pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
    	pDriverObj->DriverUnload = DriverUnload;
    	//
    
    	RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
    
    	status = IoCreateDevice(pDriverObj,
    		0,
    		&ustrDevName,
    		FILE_DEVICE_UNKNOWN,
    		0,
    		FALSE,
    		&pDevObj);
    
    	dprintf("Device Name %S", ustrDevName.Buffer);
    
    	if (!NT_SUCCESS(status))
    	{
    		dprintf("IoCreateDevice = 0x%x\n", status);
    		return status;
    	}
    
    
    	RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
    
    	status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
    	if (!NT_SUCCESS(status))
    	{
    		dprintf("IoCreateSymbolicLink = 0x%x\n", status);
    		IoDeleteDevice(pDevObj);
    		return status;
    	}
    
    	dprintf("SymbolicLink:%S", ustrLinkName.Buffer);
    
    	GetWin32kBase(pDriverObj);
    	GetSSDTShadowBase();
    	dprintf("Win32k Base : 0x%X",pWin32kBase);
    	dprintf("KeServiceDescriptorTableShadow : 0x%X", KeServiceDescriptorTableShadow);
    
    	return STATUS_SUCCESS;
    }
    
    
    VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
    {
    	UNICODE_STRING strLink;
    	RtlInitUnicodeString(&strLink, LINK_NAME);
    	//
    	// Delete the symbolic link
    	//
    	IoDeleteSymbolicLink(&strLink);
    	//
    	// Delete the device object
    	//
    	IoDeleteDevice(pDriverObj->DeviceObject);
    	dprintf("Unloaded\n");
    }
    
    NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    {
    	RestoreShadow();
    	pIrp->IoStatus.Status = STATUS_SUCCESS;
    	pIrp->IoStatus.Information = 0;
    	dprintf("IRP_MJ_CREATE\n");
    	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
    {
    	pIrp->IoStatus.Status = STATUS_SUCCESS;
    	pIrp->IoStatus.Information = 0;
    	dprintf("IRP_MJ_CLOSE\n");
    	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    	return STATUS_SUCCESS;
    }
    
    
    VOID GetSSDTShadowBase()
    {
    	UCHAR *cPtr;
    	UCHAR *pOpcode;
    	ULONG Length;
    	for (cPtr = (PUCHAR)KeAddSystemServiceTable;
    		cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
    		cPtr += Length)
    	{
    		Length = SizeOfCode(cPtr, &pOpcode);
    
    		if (!Length) break;
    
    		if ( *(PUSHORT)cPtr == 0x888D )
    		{
    			KeServiceDescriptorTableShadow = (PKSERVICE_TABLE_DESCRIPTOR)(*(ULONG *)((ULONG)pOpcode + 2));
    			break;
    		}
    	}
    }
    
    VOID GetWin32kBase(PDRIVER_OBJECT pDriverObj)
    {
    	PLIST_ENTRY pList = NULL;
    	PLDR_DATA_TABLE_ENTRY Ldr = NULL;
    	pList = ( (PLIST_ENTRY)pDriverObj->DriverSection )->Flink;
    	do {
    		Ldr = CONTAINING_RECORD(
    			pList,
    			LDR_DATA_TABLE_ENTRY,
    			InLoadOrderLinks);
    		if (Ldr->EntryPoint &&
    			Ldr->FullDllName.Buffer) {
    				if ( !_wcsicmp(Ldr->FullDllName.Buffer, L"\\systemroot\\system32\\win32k.sys") ) {
    					//Compare module name 
    					pWin32kBase = Ldr->DllBase;//Save the module base address
    					break;
    				}
    		}
    		pList = pList->Flink;
    	} while ( pList != ((LIST_ENTRY*)pDriverObj->DriverSection)->Flink );
    }
    
    
    NTSTATUS RestoreShadow()
    {
    	NTSTATUS status;
    	HANDLE hFile;				//File handle
    	OBJECT_ATTRIBUTES ObjAttr;
    	UNICODE_STRING ustrWin32k;
    	IO_STATUS_BLOCK ioStatus;
    	ULONG ulShadowRaw = 0;
    	ULONG ulShadowBase = 0;
    	PVOID PoolArea = NULL;
    	FILE_POSITION_INFORMATION fpi;
    	LARGE_INTEGER Offset;
    	ULONG OrigAddress = 0;
    	ULONG CurAddress = 0;
    	ULONG i = 0;
    	ULONG ulCount = 0;
    	PULONG pAddr;
    
    	if ( pWin32kBase == NULL ||
    		KeServiceDescriptorTableShadow == NULL)
    	{
    		dprintf("Error.");
    		return STATUS_UNSUCCESSFUL;
    	}
    	//Index?
    	
    	ulCount = KeServiceDescriptorTableShadow[1].Limit;
    
    	dprintf("Count Of Shadow : %d\n", ulCount );
    
    	ulShadowBase = *(ULONG*)&KeServiceDescriptorTableShadow[1].Base;//Get the base address
    
    	dprintf("ulShadowBase = 0x%X\n",ulShadowBase);
    
    	ulShadowRaw = ulShadowBase - (ULONG)pWin32kBase;
    	//ulShadowRaw = RVAToRaw(pWin32kBase,ulShadowBase);
    
    	dprintf("ulShadowRaw = 0x%X\n",ulShadowRaw);
    
    	RtlInitUnicodeString(&ustrWin32k, L"\\SystemRoot\\System32\\win32k.sys");
    
    	PoolArea = ExAllocatePool( PagedPool, sizeof(ULONG) * ulCount );
    
    	if (!PoolArea) {
    		dprintf("PoolArea is null\n");
    		return STATUS_UNSUCCESSFUL;
    	}
    
    	RtlZeroMemory(&ObjAttr, sizeof(ObjAttr) );
    
    	InitializeObjectAttributes(
    		&ObjAttr,
    		&ustrWin32k,
    		OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
    		NULL,
    		NULL);
    	//Open win32K.SYS
    	status = IoCreateFile(
    		&hFile,
    		FILE_READ_ATTRIBUTES,
    		&ObjAttr,
    		&ioStatus,
    		0,
    		FILE_ATTRIBUTE_NORMAL,
    		FILE_SHARE_READ,
    		FILE_OPEN,
    		0,
    		NULL,
    		0,
    		0,
    		NULL,
    		IO_NO_PARAMETER_CHECKING);
    
    	if ( !NT_SUCCESS(status) ) {
    		dprintf("IoCreateFile Error : 0x%X", status);
    		goto __exit;
    	}
    
    	//Set the file offset
    	Offset.LowPart = ulShadowRaw;
    	Offset.HighPart = 0;
    	//Read data
    	status = ZwReadFile (
    		hFile,
    		NULL,
    		NULL,
    		NULL,
    		&ioStatus,
    		PoolArea,
    		ulCount*sizeof(ULONG),
    		&Offset,
    		NULL);
    
    	if ( !NT_SUCCESS(status) ) {
    		dprintf("ZwReadFile Error : 0x%X");
    		goto __exit;
    	}
    
    	//Change the pointer type
    	pAddr = (PULONG)PoolArea;
    	//Comparing the original address
    	for (i=0;i<ulCount;i++) {
    		OrigAddress = *pAddr;	//Point to the original address
    		CurAddress = KeServiceDescriptorTableShadow[1].Base[i];	//Read the current address
    		if ( OrigAddress != CurAddress ) {
    			dprintf("ID:%-3d.OrigAddr : 0x%X CurAddr : 0x%X---Hooked!\n",i,OrigAddress,CurAddress);
    		} else {
    			dprintf("ID:%-3d.OrigAddr : 0x%X.CurAddr : 0x%X\n",i,OrigAddress,CurAddress);
    		}
    		pAddr++;//increase counter, Pointer to the next function
    	}
    
    __exit:
    	if (PoolArea) {
    		ExFreePool(PoolArea);
    	}
    	if (hFile) {
    		//close handle
    		ZwClose(hFile);
    	}
    	return status;
    }
    Driver and full VS project inside attachment.

    P.S. I don't know how the author of this stuff.

    Please register or login to download attachments.

    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

  2. The Following User Says Thank You to Dwar For This Useful Post:


Similar Threads

  1. [C++] SSDT HOOK source code
    By Dwar in forum C/C++
    Replies: 2
    Last Post: 2013-01-10, 07:08 AM
  2. Bypassing GameGuard SSDT hook's
    By Dwar in forum Anti-Cheat Systems
    Replies: 6
    Last Post: 2012-10-21, 10:28 AM
  3. [Novo jogo] shadow war
    By joeySW in forum Português
    Replies: 7
    Last Post: 2012-01-13, 04:42 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •