64位內核第二講,進程保護.
一丶什么是保護.
什么是保護. 比如我們安裝了xxx殺毒軟件.那么此時你用任務管理器關閉.是關閉不了的.原因是內核已經做了保護.
那么去掉保護的前提就是你要給自己的軟件做保護.
比如我們給計算器做保護. 例如下圖.
做保護.以前的病毒作者.都是想要退出xxx殺毒軟件. 什么方法都能做. 所以殺軟為了防止這一情況發生,直接把打開進程的API進行HOOK即可.
但是別忘了.還可以拷貝句柄.所以殺軟防不住.只能在內核做保護.
二丶給軟件添加保護熟悉API和結構體
給軟件添加保護很簡單. 也是調用API進行操作.
API:
ObRegisterCallbacks 注冊進程和線程處理回調
NTSTATUS ObRegisterCallbacks( IN POB_CALLBACK_REGISTRATION CallBackRegistration, OUT PVOID *RegistrationHandle );
第一個是個結構體,我們想要進行的操作都放在這個結構中
第二個是個二級指針,我們給一個即可
結構體:
typedef struct _OB_CALLBACK_REGISTRATION { __in USHORT Version; //版本號 __in USHORT OperationRegistrationCount; //回調個數. 可以一次蹙着多個回調. 和最后一個參數綁定的. 如果一次注冊多個.則最后一個參數需要給數組保存,最后參數是一個結構體. __in UNICODE_STRING Altitude; // 指定的驅動程序的Uncode字符串. 可以看WDK文檔給. __in PVOID RegistrationContext; // 回調函數的參數.如果你給可以在這里給. __in OB_OPERATION_REGISTRATION *OperationRegistration;//回調函數信息結構體,如果個數有多個,你需要定義為數組. } OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;
結構體中回調函數結構體.
typedef struct _OB_OPERATION_REGISTRATION { __in POBJECT_TYPE *ObjectType; //對象的類型.你注冊回調函數的類型 PsProcessType 和 PsThreadType 分別是進程回調和線程回調. __in OB_OPERATION Operations; //注冊回調的操作方式, 一個是創建進程. 一個是拷貝進程句柄. OB_OPERATION_HANDLE_CREATEA ,OB_OPERATION_HANDLE_DUPLICATE __in POB_PRE_OPERATION_CALLBACK PreOperation;//創建之前回調函數的地址,在這里給. 每一個回調都包含什么信息在這個結構體中給出. __in POB_POST_OPERATION_CALLBACK PostOperation;//創建之后回調函數的地址. 和上面不一樣,一個是創建之前,你的回調回來,一個是創建之后你的回調函數回來. } OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;
回調函數原型
OB_PREOP_CALLBACK_STATUS ObjectPreCallback( __in PVOID RegistrationContext, //回調函數的參數,上面通過結構體給的. __in POB_PRE_OPERATION_INFORMATION OperationInformation //進程或者線程創建的信息結構體 );
進程或者線程信息結構體.
typedef struct _OB_PRE_OPERATION_INFORMATION { __in OB_OPERATION Operation; //句柄的操作類型, 是上面我們給的. union { __in ULONG Flags; struct { __in ULONG KernelHandle:1; __in ULONG Reserved:31; }; }; __in PVOID Object; //對象指針,如果你給的是監控進程,那么這個對象就是EPROCESS,如果是線程,那么這個對象就是ETHREAD __in POBJECT_TYPE ObjectType; //對象類型. 可能是PsThreadType 也可能是 PsProcessType __out PVOID CallContext; __in POB_PRE_OPERATION_PARAMETERS Parameters; //創建或者創建之后的參數信息結構體. } OB_PRE_OPERATION_INFORMATION, *POB_PRE_OPERATION_INFORMATION;
參數信息結構體
typedef union _OB_PRE_OPERATION_PARAMETERS { __inout OB_PRE_CREATE_HANDLE_INFORMATION CreateHandleInformation; //創建句柄,則成員會給這個賦值 __inout OB_PRE_DUPLICATE_HANDLE_INFORMATION DuplicateHandleInformation; //拷貝句柄,則給這個成員賦值. } OB_PRE_OPERATION_PARAMETERS, *POB_PRE_OPERATION_PARAMETERS;
創建句柄結構體
typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION { __inout ACCESS_MASK DesiredAccess; //創建的權限是什么. 如果我們給 0則沒有任何權限,則進程不能創建. __in ACCESS_MASK OriginalDesiredAccess; //原始的權限. } OB_PRE_CREATE_HANDLE_INFORMATION, *POB_PRE_CREATE_HANDLE_INFORMATION;
拷貝句柄結構體信息
__inout ACCESS_MASK DesiredAccess; //權限,我們自己控制 __in ACCESS_MASK OriginalDesiredAccess; //原始權限 __in PVOID SourceProcess; //拷貝句柄的時候,源對象指針. __in PVOID TargetProcess; //目的對象指針. } OB_PRE_DUPLICATE_HANDLE_INFORMATION, * POB_PRE_DUPLICATE_HANDLE_INFORMATION;
結構體看着挺多,其實挺簡單的.
三丶給軟件添加權限保護代碼.
代碼直接拷貝編譯就可以.我是使用的 WDK7600. 因為沒有硬編碼的方式.所以高版本WDK只要支持這些函數.就可以編譯.
#include <ntddk.h> //很多驅動的結構體函數的聲明呀.都包含在這里面 #include <ntdef.h> #include <wdm.h> NTKERNELAPI NTSTATUS PsLookupProcessByProcessId( __in HANDLE ProcessId, __deref_out PEPROCESS *Process ); PVOID g_pRegistrationHandle; NTKERNELAPI UCHAR * PsGetProcessImageFileName(__in PEPROCESS Process); EXTERN_C void InstallHook(); OB_PREOP_CALLBACK_STATUS ObjectPreCallback(__in PVOID RegistrationContext, __in POB_PRE_OPERATION_INFORMATION OperationInformation); OB_PREOP_CALLBACK_STATUS ObjectPreCallback(__in PVOID RegistrationContext, __in POB_PRE_OPERATION_INFORMATION OperationInformation) { PEPROCESS Process; UCHAR *pszImageName = NULL; #define PROCESS_PROTECT 0x1 Process = (PEPROCESS)OperationInformation->Object; pszImageName = PsGetProcessImageFileName(Process); if (strstr(pszImageName, "calc") != NULL) { if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) { if ((OperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_PROTECT) == PROCESS_PROTECT) { OperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_PROTECT; } } if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) { if ((OperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess & PROCESS_PROTECT) == PROCESS_PROTECT) { OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= ~PROCESS_PROTECT; } } } return OB_PREOP_SUCCESS; } void InstallHook() { NTSTATUS status; OB_CALLBACK_REGISTRATION obReg; OB_OPERATION_REGISTRATION obOper; DbgPrint("begin protect calc"); obOper.ObjectType = PsProcessType; obOper.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; obOper.PreOperation = NULL; obOper.PostOperation = NULL; RtlInitUnicodeString(&obReg.Altitude, L"60000"); obReg.Version = OB_FLT_REGISTRATION_VERSION; obReg.OperationRegistrationCount = 1; obReg.RegistrationContext = NULL; obOper.PreOperation = (POB_PRE_OPERATION_CALLBACK)&ObjectPreCallback; obReg.OperationRegistration = &obOper; status = ObRegisterCallbacks(&obReg, &g_pRegistrationHandle); DbgPrint("begin protect calc end"); } VOID DriverUnLoad(PDRIVER_OBJECT pDriverObject); NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) { pDriverObject->DriverUnload = DriverUnLoad; DbgPrint("Load Driver Sucess"); //InstallHook(); InstallHook(); //設置通訊的方式 return STATUS_SUCCESS; } //驅動卸載 VOID DriverUnLoad(PDRIVER_OBJECT pDriverObject) { ObUnRegisterCallbacks(g_pRegistrationHandle); DbgPrint("Unload MyDrive\n"); }
通過上面的代碼,我們的計算器則會被保護.那么此時我們編譯之后安裝驅動那么軟件就和剛開始那樣,不能進行關閉進程了.
你如果關閉計算器,重新打開則打開不了了,
如果你啟動計算器之后,在安驅動,那么計算機就同上圖所示,關閉不了了.
四丶去掉保護.
去掉保護,那么我們就要逆向 設置對象回調的這個API了.
那么簡單的演示則是用PChunter去掉.我們的程序就可以關閉了.
如果有時間,則逆向一下,找到數組. 找到表,抹掉即可.
去掉之后則可以退出了. 包括xxx殺毒.
代碼下載地址: WDK7600 + Notepad++ +x64Check編譯. 你可以使用Free編譯.我沒用.
鏈接:https://pan.baidu.com/s/1JDBnsznailhCw513pKsbsQ
提取碼:3uhq