C++ Inline Hook 代码

来源:互联网 发布:软件 qa qc 编辑:程序博客网 时间:2024/05/17 02:53
#include <ntifs.h>#include <ntddk.h>#include <Ntstrsafe.h>#include "ldasm.h"#ifdef _WIN64#defineHOOKLEN15#defineProxyJmpCodeLength15#else#defineHOOKLEN5#defineProxyJmpCodeLength7//sizeof(0xEA,0,0,0,0 0x08,0x00) = 7#endifPVOID JmpOldFunCodeAddr = NULL;DWORD JmpCodeLength = 0;//去掉页面保护void  WPOFF(void){#ifdef _WIN64_disable();DWORD64 cr0 = __readcr0();cr0 &= 0xfffffffffffeffff;__writecr0(cr0);//_enable();#else__asm{climov eax, cr0and eax, not 10000hmov cr0, eax}#endif}//设置页面保护void  WPON(void){#ifdef _WIN64_disable();DWORD64 cr0 = __readcr0();cr0 |= 0x10000;__writecr0(cr0);#else__asm{mov eax, cr0or eax, 10000hmov cr0, eaxsti}#endif}//HOOKNTSTATUS 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 _WIN64UINT64 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);#elsechar 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);#endifKeLowerIrql(irql);WPON();return STATUS_SUCCESS;}//恢复hookNTSTATUS 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;}

0 0
原创粉丝点击