首页
社区
课程
招聘
[原创]利用异常实现短期hook
发表于: 2019-10-12 01:05 8007

[原创]利用异常实现短期hook

2019-10-12 01:05
8007

场景1

https://blog.csdn.net/binhualiu1983/article/details/51646094 

调用目标call 需要跳过某些判断或者函数
场景2 
目标call 只需要部分指令执行

大概实现技术
设置线程上下文设置drX寄存器 实现硬件执行断点
主动调用目标call
通过硬件断点获取寄存器或修改eip

以上实现不改变crc且不通过驱动实现。只对当前执行线程有效,不使用线程句柄
调用call 的过程中有4个硬件断点随意修改call内部流程,适合在游戏主循环中使用.
---------------------------------------------------------------------------
已经通过hook方法 把所有读写call均在目标主线程调用。


通过主动调用1050F7A0这个call 但是不执行1050F805 
1050F805 此时的 ECX则是我需要得到的值



void __declspec(naked) _stdcall hook_handleEIP()
{
_asm
{
//E
popeax //目标地址有push,先平盏
moveax,ecx //得到数据后修改eax作为返回值 然后ret掉目标函数
retn    4
}
}

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext )
{
EXCEPTION_DISPOSITION ERet = ExceptionContinueSearch;
//判断异常是否为单步异常,硬件断点也是单步异常
if (ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP) 
{
//判断异常地址,不是目标地址则是第一次的单步
if ((DWORD)ExceptionRecord->ExceptionAddress != 0x1050F805)
{
//B
SetHardwareBreakpoint(ContextRecord,0x32D3F805,DR_3,CODE,SIZE_1);//设置硬件断点相关标志位
ERet = ExceptionContinueExecution;//告诉系统异常已处理
}else if ((DWORD)ExceptionRecord->ExceptionAddress == 0x1050F805)
{
//D
RemoveHardwareBreakpoint(ContextRecord,DR_3);//删除硬件寄存器标志位
//修改eip到自己的函数上
ContextRecord->Eip = (DWORD)hook_handleEIP;
ERet = ExceptionContinueExecution;//告诉系统异常已处理
}
}
return ERet;
}

DWORD ExecutionFunction()
{
//A
DWORD handler = (DWORD)_except_handler;//异常处理函数
_asm
{
pushhandler//注册异常处理函数
pushFS:[0]
movFS:[0],ESP
pushfd
pushfd
orDWORD PTR[esp],0x100//设置dr7单步标志
popfd //执行到这里会触发单步异常
nop
popfd
}
//以上是注册异常处理函数

//以下是主动调用目标函数
DWORD dwRet;
_asm
{
pushad
push0
moveax,1050F7A0h
calleax //C
mov[dwRet],eax
popad
}


//F
//删除异常接收函数
_asm
{
moveax,[ESP]
movFS:[0], EAX
addesp, 8
}
return dwRet;
}


void __declspec(naked) _stdcall hook_handleEIP()
{
_asm
{
//E
popeax //目标地址有push,先平盏
moveax,ecx //得到数据后修改eax作为返回值 然后ret掉目标函数
retn    4
}
}

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext )
{
EXCEPTION_DISPOSITION ERet = ExceptionContinueSearch;
//判断异常是否为单步异常,硬件断点也是单步异常
if (ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP) 
{
//判断异常地址,不是目标地址则是第一次的单步
if ((DWORD)ExceptionRecord->ExceptionAddress != 0x1050F805)
{
//B
SetHardwareBreakpoint(ContextRecord,0x32D3F805,DR_3,CODE,SIZE_1);//设置硬件断点相关标志位
ERet = ExceptionContinueExecution;//告诉系统异常已处理
}else if ((DWORD)ExceptionRecord->ExceptionAddress == 0x1050F805)
{
//D
RemoveHardwareBreakpoint(ContextRecord,DR_3);//删除硬件寄存器标志位
//修改eip到自己的函数上
ContextRecord->Eip = (DWORD)hook_handleEIP;
ERet = ExceptionContinueExecution;//告诉系统异常已处理
}
}
return ERet;
}

DWORD ExecutionFunction()
{
//A
DWORD handler = (DWORD)_except_handler;//异常处理函数
_asm
{
pushhandler//注册异常处理函数
pushFS:[0]
movFS:[0],ESP
pushfd
pushfd
orDWORD PTR[esp],0x100//设置dr7单步标志
popfd //执行到这里会触发单步异常
nop
popfd
}
//以上是注册异常处理函数

//以下是主动调用目标函数
DWORD dwRet;
_asm
{
pushad
push0
moveax,1050F7A0h
calleax //C
mov[dwRet],eax
popad
}


//F
//删除异常接收函数
_asm
{
moveax,[ESP]
movFS:[0], EAX
addesp, 8
}
return dwRet;
}

void __declspec(naked) _stdcall hook_handleEIP()
{
_asm
{
//E
popeax //目标地址有push,先平盏
moveax,ecx //得到数据后修改eax作为返回值 然后ret掉目标函数
retn    4
}
}

EXCEPTION_DISPOSITION
__cdecl
_except_handler(
struct _EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT *ContextRecord,
void * DispatcherContext )
{
EXCEPTION_DISPOSITION ERet = ExceptionContinueSearch;
//判断异常是否为单步异常,硬件断点也是单步异常
if (ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP) 
{
//判断异常地址,不是目标地址则是第一次的单步
if ((DWORD)ExceptionRecord->ExceptionAddress != 0x1050F805)
{
//B
SetHardwareBreakpoint(ContextRecord,0x32D3F805,DR_3,CODE,SIZE_1);//设置硬件断点相关标志位
ERet = ExceptionContinueExecution;//告诉系统异常已处理
}else if ((DWORD)ExceptionRecord->ExceptionAddress == 0x1050F805)
{
//D
RemoveHardwareBreakpoint(ContextRecord,DR_3);//删除硬件寄存器标志位
//修改eip到自己的函数上
ContextRecord->Eip = (DWORD)hook_handleEIP;

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-10-12 01:16 被mudebug编辑 ,原因: 修饰
收藏
免费 2
支持
分享
最新回复 (6)
雪    币: 433
活跃值: (1910)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
2
硬件断点,CRC,内存DLL。俗称看雪三大炒冷饭项目。
最后于 2019-10-12 02:30 被萌克力编辑 ,原因:
2019-10-12 02:28
0
雪    币: 83
活跃值: (1087)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2019-10-12 16:01
0
雪    币: 6124
活跃值: (4661)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
都过去15年了,能不能不要炒冷饭了。
最后于 2019-10-13 16:42 被黑洛编辑 ,原因:
2019-10-13 16:41
0
雪    币: 498
活跃值: (2324)
能力值: ( LV12,RANK:356 )
在线值:
发帖
回帖
粉丝
5
写的很好呀
2019-10-14 20:44
0
雪    币: 26205
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
6
感谢分享~代码可以高亮,可以试试
2019-10-17 14:43
0
游客
登录 | 注册 方可回帖
返回
//