C++ Inline Hook 代码
2017-05-03 21:26
1676 查看
#include <ntifs.h> #include <ntddk.h> #include <Ntstrsafe.h> #include "ldasm.h" #ifdef _WIN64 #define HOOKLEN 15 #define ProxyJmpCodeLength 15 #else #define HOOKLEN 5 #define ProxyJmpCodeLength 7 //sizeof(0xEA,0,0,0,0 0x08,0x00) = 7 #endif PVOID JmpOldFunCodeAddr = NULL; DWORD JmpCodeLength = 0; //去掉页面保护 void WPOFF(void) { #ifdef _WIN64 _disable(); DWORD64 cr0 = __readcr0(); cr0 &= 0xfffffffffffeffff; __writecr0(cr0); // _enable(); #else __asm { cli mov eax, cr0 and eax, not 10000h mov cr0, eax } #endif } //设置页面保护 void WPON(void) { #ifdef _WIN64 _disable(); DWORD64 cr0 = __readcr0(); cr0 |= 0x10000; __writecr0(cr0); #else __asm { mov eax, cr0 or eax, 10000h mov cr0, eax sti } #endif } //HOOK NTSTATUS FuncModify(PVOID FuncAddr, PVOID FuncNewAddr, PVOID *JmpCodeAddr, DWORD *JmpCodeLength) { //定义变量 NTSTATUS status = STATUS_UNSUCCESSFUL; ULONG BackupLength = 0; UCHAR *cPtr, *pOpcode; ULONG Length; PVOID pJmpCodeBuf; //参数效验 if (FuncAddr == NULL || FuncNewAddr == NULL || JmpCodeAddr==NULL || JmpCodeLength==NULL)return status; //搜索hook点 for (cPtr = (UCHAR *)FuncAddr; cPtr < (UCHAR *)FuncAddr + PAGE_SIZE; cPtr += Length) { ldasm_data ld = { 0 }; Length = ldasm(cPtr, &ld, 0); BackupLength += Length; if (BackupLength >= HOOKLEN) break; } if (BackupLength<HOOKLEN) { return status; } pJmpCodeBuf = ExAllocatePool(NonPagedPool, BackupLength + ProxyJmpCodeLength); if (pJmpCodeBuf == NULL) { return status; } RtlZeroMemory(pJmpCodeBuf, BackupLength + ProxyJmpCodeLength); /////////////////////////////// *JmpCodeAddr = pJmpCodeBuf; *JmpCodeLength = BackupLength; // 保存原始API的头部 RtlMoveMemory(pJmpCodeBuf, FuncAddr, BackupLength); WPOFF(); KIRQL irql = KeRaiseIrqlToDpcLevel(); //JMP回原始函数的地址 #ifdef _WIN64 UINT64 tmpv; UCHAR jmp_code[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; UCHAR jmp_code_orifunc[] = "\xFF\x25\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; //跳转到没被打补丁的那个字节 tmpv = (ULONG64)FuncAddr + BackupLength; memcpy(jmp_code_orifunc + 6, &tmpv, 8); memcpy((PUCHAR)pJmpCodeBuf + BackupLength, jmp_code_orifunc, 14); tmpv = (UINT64)FuncNewAddr; memcpy(jmp_code + 6, &tmpv, 8); RtlZeroMemory(FuncAddr, BackupLength); memcpy(FuncAddr, jmp_code, 14); #else char jmp_code[ProxyJmpCodeLength] = { 0xEA, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 }; *((PULONG_PTR)(jmp_code + 1)) = (ULONG_PTR)FuncAddr + BackupLength; RtlMoveMemory((VOID *)((ULONGLONG)pJmpCodeBuf + BackupLength), jmp_code, ProxyJmpCodeLength); //HOOK操作 char nJmpCode[HOOKLEN] = { 0xE9, 0x00, 0x00, 0x00, 0x00 }; *(DWORD*)(nJmpCode + 1) = (DWORD)FuncNewAddr - ((DWORD)FuncAddr + HOOKLEN); RtlZeroMemory(FuncAddr, BackupLength); RtlMoveMemory(FuncAddr, nJmpCode, BackupLength); #endif KeLowerIrql(irql); WPON(); return STATUS_SUCCESS; } //恢复hook NTSTATUS FuncRestore(PVOID FuncAddr, PVOID pOriginalCode, DWORD Length) { //参数效验 if (MmIsAddressValid(FuncAddr) == FALSE)return STATUS_UNSUCCESSFUL; if (MmIsAddressValid(pOriginalCode) == FALSE)return STATUS_UNSUCCESSFUL; if (Length <= 0)return STATUS_UNSUCCESSFUL; WPOFF(); KIRQL irql = KeRaiseIrqlToDpcLevel(); RtlMoveMemory(FuncAddr, pOriginalCode, Length); KeLowerIrql(irql); WPON(); return STATUS_SUCCESS; } typedef NTSTATUS(__fastcall *FnNtOpenProcess)(HANDLE ProcessId, PEPROCESS *Process); NTSTATUS NewNtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) { if (ClientId->UniqueProcess==2216) { return STATUS_ACCESS_DENIED; } return ((FnNtOpenProcess)JmpOldFunCodeAddr)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); } VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) { return; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status; DriverObject->DriverUnload = DriverUnload; DbgBreakPoint(); FuncModify(NtOpenProcess, NewNtOpenProcess, &JmpOldFunCodeAddr, &JmpCodeLength); FuncRestore(NtOpenProcess, JmpOldFunCodeAddr, JmpCodeLength); return STATUS_SUCCESS; }
相关文章推荐
- Inline Hook(ring3)的简单C++实现方法
- # inline hook 的几种方式概述----简单介绍而已,没有代码
- kernel inline hook 绕过vice检测
- SSDT Hook的妙用-对抗ring0 inline hook
- 【转帖】SSDT Hook的妙用-对抗ring0 inline hook
- SSDT Hook 对抗ring0 inline hook
- SSDT Hook的妙用-对抗ring0 inline hook
- Visual C++ Inline Assembly 简介
- 【转】检测和恢复SSDT HOOK,INLINE SSDT HOOK
- Windows下Hook API技术 inline hook
- SSDT Hook的妙用-对抗ring0 inline hook
- rootkit应用之[三] inline hook
- Windows内核API HOOK 之 Inline Hook
- Inline Hook IofCallDriver 截获所有IRP
- 对付kernel / fsd inline hook/ssdt hook
- inline hook 框架笔记
- SSDT Hook的妙用-对抗ring0 inline hook
- SSDT Hook的妙用-对抗ring0 inline hook
- Ring0 inline hook For Delphi.
- Command Line Arguments in C++