(63)0环与3环通信非常规方式 —— 0环InlineHook
生活随笔
收集整理的這篇文章主要介紹了
(63)0环与3环通信非常规方式 —— 0环InlineHook
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、回顧
在第37篇博客里,我們學習了0環-3環通信的常規方式,是通過設備的方式進行數據交互的。今天,我們來學習一種非常規方式,即通過HOOK API 的形式完成數據交互。
(37)0環與3環通信,PspTerminateProcess 關閉進程工具
二、原理
隨便找一個內核函數,參數至少要有4個,多一點也無所謂。用 Inline hook 改變它的執行流程,如果參數是合法的,就調用原來的函數,如果參數符合某種規則,就認為這是3環請求和驅動通信的。
舉個例子,我hook了 NtQuerySystemInfo,它的第一個參數不應該大于47,在鉤子函數里如果發現參數大于47,就知道這是要和驅動通信了。
// Hook NtQuerySystemInformation __declspec(naked) void HbgNtQuerySystemInformation(IN ULONG OpCode, IN PVOID InData, OUT PVOID OutData, IN OUT PULONG InOutDataLength) {__asm{push ebp;mov ebp, esp;sub esp, 0x50;}switch (OpCode){case OP_TEST:{DbgPrint("%s\n", InData); // hellomemcpy(OutData, "world", 6); // 返回數據給3環*InOutDataLength = 6;goto ExitNtQuerySystemInformation;break;}}// 正常調用 NtQuerySystemInformation__asm{add esp, 0x50;pop ebp;push 0x210;jmp g_HookRetAddressNtQuerySystemInformation;} ExitNtQuerySystemInformation:__asm{add esp, 0x50;pop ebp;retn 0x10;} }三、完整代碼
驅動
#include <ntddk.h> #include <ntstatus.h>//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------typedef NTSTATUS (__stdcall *NTQUERYSYSTEMINFORMATION) (IN ULONG SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength);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;UINT16 LoadCount;UINT16 TlsIndex;LIST_ENTRY HashLinks;PVOID SectionPointer;ULONG CheckSum;ULONG TimeDateStamp;PVOID LoadedImports;PVOID EntryPointActivationContext;PVOID PatchInformation; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------VOID DriverUnload(PDRIVER_OBJECT pDriver); NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path); VOID PageProtectOff(); VOID PageProtectOn(); VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize); PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress); void InlineHookNtQuerySystemInformation(); void UnsetInlineHookNtQuerySystemInformation(); void HbgNtQuerySystemInformation(IN ULONG OpCode, IN PVOID InData, OUT PVOID OutData, IN OUT PULONG InOutDataLength);//----------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------- #define OP_TEST 50PDRIVER_OBJECT g_Driver; NTQUERYSYSTEMINFORMATION NtQuerySystemInformation; ULONG g_HookRetAddressNtQuerySystemInformation;//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------// 驅動入口 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) {g_Driver = pDriver;pDriver->DriverUnload = DriverUnload;InlineHookNtQuerySystemInformation();return STATUS_SUCCESS; }// 卸載驅動 VOID DriverUnload(PDRIVER_OBJECT pDriver) {UnsetInlineHookNtQuerySystemInformation();DbgPrint("Driver unloaded.\n"); }// 關閉頁保護 VOID PageProtectOff() {__asm{cli; // 關閉中斷mov eax, cr0;and eax, not 0x10000; // WP位置0mov cr0, eax;} }// 開啟頁保護 VOID PageProtectOn() {__asm{mov eax, cr0;or eax, 0x10000; // WP位置1mov cr0, eax;sti; // 恢復中斷} }// 獲取內核基址,大小 VOID GetKernelBase(PDRIVER_OBJECT driver, PVOID *pKrnlBase, PULONG uKrnlImageSize) {PLDR_DATA_TABLE_ENTRY pLdteHead; // 內核模塊鏈表頭PLDR_DATA_TABLE_ENTRY pLdteCur; // 遍歷指針UNICODE_STRING usKrnlBaseDllName; // 內核模塊名RtlInitUnicodeString(&usKrnlBaseDllName,L"ntoskrnl.exe");pLdteHead = (PLDR_DATA_TABLE_ENTRY)driver->DriverSection;pLdteCur = pLdteHead;do {PLDR_DATA_TABLE_ENTRY pLdte = CONTAINING_RECORD(pLdteCur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);//DbgPrint("DllBase: %p, SizeOfImage: %08X %wZ\n", pLdteCur->DllBase, pLdteCur->SizeOfImage, &(pLdteCur->FullDllName));if (RtlCompareUnicodeString(&pLdteCur->BaseDllName, &usKrnlBaseDllName, TRUE) == 0){*pKrnlBase = pLdteCur->DllBase;*uKrnlImageSize = pLdteCur->SizeOfImage;return;}pLdteCur = (PLDR_DATA_TABLE_ENTRY)pLdteCur->InLoadOrderLinks.Flink;} while (pLdteHead != pLdteCur);return; }// 特征碼搜索 PVOID MemorySearch(PVOID bytecode, ULONG bytecodeLen, PVOID pBeginAddress, PVOID pEndAddress) {PVOID pCur = pBeginAddress;while (pCur != pEndAddress){if (RtlCompareMemory(bytecode,pCur,bytecodeLen) == bytecodeLen){return pCur;}((ULONG)pCur)++;}return 0; }// InlineHook NtQuerySystemInformation void InlineHookNtQuerySystemInformation() { // NtQuerySystemInformation 特征碼ULONG bytecode[] = {0x4589c033, 0xdc4589e4, 0x64fc4589 ,0x000124a1,0xe8858900, 0x8afffffd, 0x00014080 ,0x90458800};UCHAR ReplaceByte[5];PVOID KrnlBase;ULONG KrnlImageSize;// 通過特征碼獲取NtQuerySystemInformation函數地址GetKernelBase(g_Driver, &KrnlBase, &KrnlImageSize); NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)((ULONG)MemorySearch( \bytecode,sizeof(bytecode),KrnlBase,(PVOID)((ULONG)KrnlBase+KrnlImageSize)) - 15); //DbgPrint("%x\n", ((PULONG)NtQuerySystemInformation)[0]);// 設置裸函數返回地址g_HookRetAddressNtQuerySystemInformation = (ULONG)NtQuerySystemInformation + 5;// 計算替換指令ReplaceByte[0] = 0xE9;*(PULONG)(ReplaceByte + 1) = (ULONG)HbgNtQuerySystemInformation - g_HookRetAddressNtQuerySystemInformation;PageProtectOff();memcpy(NtQuerySystemInformation, ReplaceByte, 5);PageProtectOn(); }// 卸載鉤子 void UnsetInlineHookNtQuerySystemInformation() {UCHAR ReplaceByte[5] = {0x68, 0x10, 0x02, 0x00, 0x00};PageProtectOff();memcpy(NtQuerySystemInformation, ReplaceByte, 5);PageProtectOn(); }// Hook NtQuerySystemInformation __declspec(naked) void HbgNtQuerySystemInformation(IN ULONG OpCode, IN PVOID InData, OUT PVOID OutData, IN OUT PULONG InOutDataLength) {__asm{push ebp;mov ebp, esp;sub esp, 0x50;}switch (OpCode){case OP_TEST:{DbgPrint("%s\n", InData); // hellomemcpy(OutData, "world", 6); // 返回數據給3環*InOutDataLength = 6;goto ExitNtQuerySystemInformation;break;}}// 正常調用 NtQuerySystemInformation__asm{add esp, 0x50;pop ebp;push 0x210;jmp g_HookRetAddressNtQuerySystemInformation;} ExitNtQuerySystemInformation:__asm{add esp, 0x50;pop ebp;retn 0x10;} }3環
// 03通信非常規方式.cpp : 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <windows.h>//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------BOOL LoadDriver(PCWSTR lpszDriverName, PCWSTR lpszDriverPath); void UnLoadDriver(PCWSTR lpszDriverName);//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------typedef LONG (__stdcall *HBGCOMMUNICATION) (IN ULONG OpCode, IN PVOID InData, OUT PVOID OutData, IN OUT PULONG InOutDataLength);//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------HBGCOMMUNICATION HbgCommunication = NULL;#define DRIVER_NAME L"_03communication_apihook" #define DRIVER_PATH L"_03communication_apihook.sys"#define OP_TEST 50//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------int _tmain(int argc, _TCHAR* argv[]) {HbgCommunication = (HBGCOMMUNICATION)GetProcAddress(LoadLibraryA("ntdll.dll"),"ZwQuerySystemInformation");if (HbgCommunication == NULL) {printf("獲取函數地址失敗. %d\n",GetLastError());getchar();return 1;}LoadDriver(DRIVER_NAME,DRIVER_PATH);char OutData[10] = {0};ULONG InOutDataLength;HbgCommunication(OP_TEST, "Hello", OutData, &InOutDataLength);printf("%d %s\n", InOutDataLength, OutData);UnLoadDriver(DRIVER_NAME);getchar();return 0; }BOOL LoadDriver(PCWSTR lpszDriverName, PCWSTR lpszDriverPath) {// 獲取驅動完整路徑WCHAR szDriverFullPath[MAX_PATH] = { 0 };GetFullPathNameW(lpszDriverPath,MAX_PATH,szDriverFullPath,NULL);//printf("%s\n", szDriverFullPath);// 打開服務控制管理器SC_HANDLE hServiceMgr = NULL; // SCM管理器句柄 hServiceMgr = OpenSCManagerW(NULL,NULL,SC_MANAGER_ALL_ACCESS);if (NULL == hServiceMgr){printf("OpenSCManagerW 失敗, %d\n", GetLastError());return FALSE;}printf("打開服務控制管理器成功.\n");// 創建驅動服務SC_HANDLE hServiceDDK = NULL; // NT驅動程序服務句柄hServiceDDK = CreateServiceW(hServiceMgr,lpszDriverName,lpszDriverName,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,szDriverFullPath,NULL,NULL,NULL,NULL,NULL);if (NULL == hServiceDDK){DWORD dwErr = GetLastError();if (dwErr != ERROR_IO_PENDING && dwErr != ERROR_SERVICE_EXISTS){printf("創建驅動服務失敗, %d\n", dwErr);return FALSE;}}printf("創建驅動服務成功.\n");// 驅動服務已經創建,打開服務hServiceDDK = OpenServiceW(hServiceMgr,lpszDriverName,SERVICE_ALL_ACCESS);if (!StartService(hServiceDDK, NULL, NULL)){DWORD dwErr = GetLastError();if (dwErr != ERROR_SERVICE_ALREADY_RUNNING){printf("運行驅動服務失敗, %d\n", dwErr);return FALSE;}}printf("運行驅動服務成功.\n");if (hServiceDDK){CloseServiceHandle(hServiceDDK);}if (hServiceMgr){CloseServiceHandle(hServiceMgr);}return TRUE; }void UnLoadDriver(PCWSTR lpszDriverName) {SC_HANDLE hServiceMgr = OpenSCManagerW(0,0,SC_MANAGER_ALL_ACCESS);SC_HANDLE hServiceDDK = OpenServiceW(hServiceMgr,lpszDriverName,SERVICE_ALL_ACCESS);SERVICE_STATUS SvrStatus;ControlService(hServiceDDK,SERVICE_CONTROL_STOP,&SvrStatus);DeleteService(hServiceDDK);if (hServiceDDK){CloseServiceHandle(hServiceDDK);}if (hServiceMgr){CloseServiceHandle(hServiceMgr);} }總結
以上是生活随笔為你收集整理的(63)0环与3环通信非常规方式 —— 0环InlineHook的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (62)时钟中断切换线程,时间片管理,
- 下一篇: (64)句柄表,遍历所有进程的句柄表实现