win10下驅動進程保護

網上可以查到很多WIN7下的驅動後臺進程保護代碼,而那些代碼在WIN10下並不適用,故寫此篇來文章來總結我在編寫WIN10下後臺進程保護驅動程序的過程與經驗,因爲源碼文件結構比較雜亂,在此文章裏我粘部分代碼,在最後再給出完整項目的github地址。

首先說進程關閉,通常會用三種方法:
1.利用進程管理器關閉
2.打開CMD,調用taskkill指令關閉
3.調用taskkill加上-t參數,進行強行進程關閉

在代碼方面與網上其他大神在win7下的進程保護驅動的代碼與思路完全一致,都是調用 ObRegisterCallbacks()回調函數

OB_CALLBACK_REGISTRATION obReg;
	OB_OPERATION_REGISTRATION opReg;

	memset(&obReg, 0, sizeof(obReg));
	obReg.Version = ObGetFilterVersion();
	obReg.OperationRegistrationCount = 1;
	obReg.RegistrationContext = NULL;
	RtlInitUnicodeString(&obReg.Altitude, L"321000");
	memset(&opReg, 0, sizeof(opReg)); //初始化結構體變量

	//下面請注意這個結構體的成員字段的設置
	opReg.ObjectType = PsProcessType;
	opReg.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;

	opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall; //在這裏註冊一個回調函數指針

	obReg.OperationRegistration = &opReg; //注意這一條語句

	return ObRegisterCallbacks(&obReg, &obHandle); //在這裏註冊回調函數

preCall回調函數定義爲

OB_PREOP_CALLBACK_STATUS preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION pOperationInformation)
{
	//獲取pid,這裏的HANDLE保存的其實是一個進程pid
	HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object);
	char szProcName[16] = { 0 };
	UNREFERENCED_PARAMETER(RegistrationContext);
	strcpy(szProcName, GetProcessImageNameByProcessID((ULONG)pid));
	//比較字符串,返回0,則字符串相同
	if (!_stricmp(szProcName, "Project1.exe"))
	{
		//如果創建句柄
		if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
		{
			//OriginalDesiredAccess爲原本權限,DesiredAccess爲即將要更改的新權限
			//如果要結束進程,進程管理器結束進程發送0x1001,taskkill指令結束進程發送0x0001,taskkil加/f參數結束進程發送0x1401
			int code = pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess;
			if ((code == PROCESS_TERMINATE_0) || (code == PROCESS_TERMINATE_1) || (code == PROCESS_KILL_F))
				//給進程賦予新權限
				pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 0;
			//DbgPrint("hello %x", pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess);
			
		}
	}
	return OB_PREOP_SUCCESS;
}

要注意的是在這裏負責獲取進程名稱以用於比較的函數GetProcessImageNameByProcessID爲自定義的·,我會在結尾貼上代碼的github地址。
看到這就會有人發現我這裏的代碼與網上win7下的代碼別無二致,其實兩者區別的關鍵就是三個值:
PROCESS_TERMINATE_0,
PROCESS_TERMINATE_1,
PROCESS_KILL_F
這三個值在我的自定義頭文件myhead.h裏是這樣定義的

//進程管理器結束代碼
#define PROCESS_TERMINATE_0       0x1001
//taskkill指令結束代碼
#define PROCESS_TERMINATE_1       0x0001 
//taskkill指令加/f參數強殺進程結束碼
#define PROCESS_KILL_F			  0x1401

這就是我與網上win7下的代碼不一樣的地方,如果照搬網上win7下的代碼編譯後在win10下運行可能會出現被保護進程連打都打不開的現象

最後,程序雖然有了一定成果,但是還有不足,有待後續的改正,首先說說成果
1.可以成功防止cmd指令taskkill -pid xxx以及
taskkill -f -pid xxx來關閉進程
(pid爲9912)
效果圖:
在這裏插入圖片描述從此可以看出雖然指令行反饋爲成功,實際上後臺進程依然在運行,再看看taskkill -f -pid
在這裏插入圖片描述從此可以看出加上-f參數的強制關閉直接反饋拒絕訪問,進程管理器的後臺進程也是依然在運行的,說明沒有問題
再看看進程管理器結束進程的效果,在這裏我要分成兩種情況,一種是直接打開win10下的進程管理器顯示給我們的界面,也就是進程管理器菜單欄那一欄顯示“進程”的那個頁面,還有一種情況則是菜單欄顯示“詳細信息“的那一欄,爲什麼我要分爲兩種情況,因爲我剛剛提到的不足就在這裏,再“詳細信息”一欄關閉程序,驅動可以正常攔截並阻止進程的關閉,而在“進程”一欄的界面直接結束進程,則會出現被保護的用戶層程序突然出現CPU佔用爆炸的情況CPU佔用甚至可能會出現90%以上的現象,到底是爲什麼我也還沒有搞清楚,如果有大神可以指點一二小弟感激不盡,我在後續也會繼續進行調試研究,然後看效果圖:
在”詳細信息“一欄:
在這裏插入圖片描述可以看到彈出的拒絕訪問的錯誤彈窗,說明是沒問題的。
在“進程“一欄:
在這裏插入圖片描述
CPU佔用會高達90%,我用這個驅動程序去保護Qt編寫的運行在後臺的窗口程序,被保護的窗口程序也無法繼續在前臺正常運行最後崩潰停止運行,事實上這種情況感覺就好像是隨機發生的,有時會出現這種情況,有時又不會,讓人摸不着頭腦。

補充:
在Windows進程管理器下會出現CPU調用過高導致程序崩潰的原因是,內存資源已被強制釋放,而進程又沒被關閉,進程又沒有任何讀寫權限導致程序崩潰,解決此問題的辦法是,先捕獲結束進程返回碼0x1001 捕獲到此值後先將進程權限變爲0阻止進程被關閉,再進行捕獲返回碼0x1041如果捕獲到說明就是在是在“進程”頁面結束進程,所以在捕獲到0x1041後,再恢復進程的本來所有權限就能完美解決問題了。

代碼地址:
github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章