博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VEH HOOK
阅读量:4110 次
发布时间:2019-05-25

本文共 2968 字,大约阅读时间需要 9 分钟。

相关函数

我们只需要用到 AddVectoredExceptionHandler 设置VEH异常捕获

PVOID WINAPI AddVectoredExceptionHandler(  _In_ ULONG                       FirstHandler,  _In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler);ULONG WINAPI RemoveVectoredExceptionHandler(  _In_ PVOID Handler);PVOID WINAPI AddVectoredContinueHandler(  _In_ ULONG                       FirstHandler,  _In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler);ULONG WINAPI RemoveVectoredContinueHandler(  _In_ PVOID Handler);

设置异常捕获后,我们的callback就能处理异常

_EXCEPTION_POINTERS 可以获得ExceptionRecord
ExceptionRecord中还有异常代码(ExceptionCode)和异常地址(ExceptionAddress)

VEH HOOK原理

1.将需要HOOK的函数入口内容改为0xcc中断,如果你不了解中断向量表和int软中断你可以理解为设置了个断点,这样运行时就会产生异常

2.由我们的异常处理函数捕获后,修改寄存器的值(原参数)和EIP
3.返回EXCEPTION_CONTINUE_EXECUTION,让程序重新跑起来,就能达到HOOK的效果了

下面是个DLL,你需要自己手动在DLL_PROCESS_ATTACH时运行VEH_HOOK_MessageBoxA();

编译后随便写个EXE载入DLL调用MessageBoxA试试吧

// Dll.cpp : 定义 DLL 应用程序的导出函数。//#include "stdafx.h"#include "Dll.h"#include 
#define BREAKPOINTLEN 1PVOID MessageBoxA_Addr;BYTE MessageBoxA_New_INT;BYTE MessageBoxA_Ole_INT;DWORD dwNewProtect = PAGE_EXECUTE_READWRITE;DWORD dwOldProtect;//修改参数char lpText[] = "Test Text! ";LONG NTAPI CALL_MessageBoxA(struct _EXCEPTION_POINTERS *ExceptionInfo){
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)//判断异常类型是否是断点 {
PVOID addr = ExceptionInfo->ExceptionRecord->ExceptionAddress;//获得异常地址 if (addr != nullptr/*(PVOID)0*/) {
//+0x8正常情况下是汇编中的第一个参数,+0x4为返回EIP //但是这里+0x8是汇编中的第二个参数,因为函数开头push ebp的代码被我们改成了0xcc,没有对esp进行压栈 //又由于所有参数从右到左依次入栈,所以顺序其实是反过来的 //+0xc 在MessageBox代码中是第二个lpText //+0x8 在MessageBox代码中是第三个lpCaption *(int*)((ExceptionInfo->ContextRecord->Esp) + 0x8) = (int)lpText; *(int*)((ExceptionInfo->ContextRecord->Esp) + 0xc) = (int)lpText; //修改状态 ExceptionInfo->ContextRecord->ContextFlags = CONTEXT_CONTROL; //查询控制寄存器组 ExceptionInfo->ContextRecord->Eip = /*(DWORD)&MessageBoxA;*/(DWORD)addr; /*修改TF标志位*/ ExceptionInfo->ContextRecord->EFlags |= 0x100; //恢复代码 VirtualProtect((void*)addr, BREAKPOINTLEN, dwNewProtect, &dwOldProtect); *(BYTE*)(addr) = MessageBoxA_Ole_INT;//把首个字节地址改回去 VirtualProtect((void*)addr, BREAKPOINTLEN, dwOldProtect, &dwNewProtect); //OutputDebugStringA("My::单步运行,取消断点"); printf_s("单步运行,取消断点\n"); //AddVectoredExceptionHandler(NULL,(PVECTORED_EXCEPTION_HANDLER)ExceptionInfo); return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_EXECUTE_HANDLER; } return EXCEPTION_EXECUTE_HANDLER;}void VEH_HOOK_MessageBoxA(){
AddVectoredExceptionHandler(0, CALL_MessageBoxA);//设置VEH异常捕获 MessageBoxA_Addr = (PVOID)&MessageBoxA;//MessageBoxA地址 MessageBoxA_Ole_INT = *(BYTE*)MessageBoxA_Addr; //MessageBoxA 首个字节 VirtualProtect((void*)MessageBoxA_Addr, BREAKPOINTLEN, dwNewProtect, &dwOldProtect); *(BYTE*)(MessageBoxA_Addr) = 0xcc;//首个字节内容改成0xcc(int 3)断点中断 VirtualProtect((void*)MessageBoxA_Addr, BREAKPOINTLEN, dwOldProtect, &dwNewProtect);}

关于Eflags|=0x100

看下面的图,程序状态字(标志寄存器),TF在8,但是开头是从0开始的,所以应该在从右向左第9个bit。

标志寄存器

转载地址:http://ttlsi.baihongyu.com/

你可能感兴趣的文章
论文翻译:《一个包容性设计的具体例子:聋人导向可访问性》
查看>>
基于“分形”编写的交互应用
查看>>
《融入动画技术的交互应用》主题博文推荐
查看>>
链睿和家乐福合作推出下一代零售业隐私保护技术
查看>>
Unifrax宣布新建SiFAB™生产线
查看>>
艾默生纪念谷轮™在空调和制冷领域的百年创新成就
查看>>
NEXO代币持有者获得20,428,359.89美元股息
查看>>
Piper Sandler为EverArc收购Perimeter Solutions提供咨询服务
查看>>
RMRK筹集600万美元,用于在Polkadot上建立先进的NFT系统标准
查看>>
JavaSE_day12 集合
查看>>
JavaSE_day14 集合中的Map集合_键值映射关系
查看>>
Day_15JavaSE 异常
查看>>
异常 Java学习Day_15
查看>>
JavaSE_day_03 方法
查看>>
day-03JavaSE_循环
查看>>
Mysql初始化的命令
查看>>
day_21_0817_Mysql
查看>>
day-22 mysql_SQL 结构化查询语言
查看>>
MySQL关键字的些许问题
查看>>
浅谈HTML
查看>>