您的位置:首页 > 编程语言 > C语言/C++

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代码收藏