首页
社区
课程
招聘
[分享]老瓶装新酒:0xCC+SEH实现HOOK任意地址指令!
发表于: 2010-4-20 16:42 16615

[分享]老瓶装新酒:0xCC+SEH实现HOOK任意地址指令!

2010-4-20 16:42
16615

看了“hook 任意函数,任意位置 【共享资源】 soucre ”一文,还以为实现了我想要的“HOOK任意地址指令”功能,遗憾的是还是和以前的HOOK代码类似,都有局限性,5个字节的跳转要求使我们总不能想HOOK啥地址就HOOK啥地址,要选一些没有相对转移的位置来实施HOOK大法。一个字节0xCC的软中断是我们理想的选择,不用考虑什么跳转不跳转,直接中断下来干点什么坏事才转回去正是我们经常用OD干的事情,为什么不能用它来HOOK呢,哈哈!搜了下,已经有前辈写过类似的利用SEH实施API hook的文章,我就不重复了,我写的不是HOOK API而是HOOK任意地址,比如给游戏开个远程线程,给它的主线程安装个“HOOK任意地址”的SEH,干点什么想干的事,那是多么惬意的事情啊,哈哈!废话少说,高手请飘过,测试代码如下:

EXCEPTION_DISPOSITION _cdecl cc_handler
( struct _EXCEPTION_RECORD *ExceptionRecord,
        void * EstablisherFrame,
        struct _CONTEXT *ContextRecord,
        void * DispatcherContext )
{
  if (ExceptionRecord->ExceptionCode==STATUS_BREAKPOINT)
  {
    AfxMessageBox("不用调试器,自己处理断点!");
    //ContextRecord里想改啥改啥,EAX,EBX,ECX啥的,甚至EIP都可以改,嘿嘿!
    *(LPBYTE)(ContextRecord->Eip)=0x90;//0xCC处改成NOP,不然就一直在这里面打转了!
    return ExceptionContinueExecution;  
  } 
  else
    return ExceptionContinueSearch;
}

void CHookAnyAddrDlg::OnButton1() 
{
  // TODO: Add your control notification handler code here
    AfxMessageBox("start");

    __asm
    { 
        // 创建EXCEPTION_REGISTRATION结构:
        push offset cc_handler// handler 函数的地址
        push DWORD PTR FS:[0]  // 前一个handler函数的地址
        mov FS:[0],ESP // 安装新的EXECEPTION_REGISTRATION结构
   
        __emit 0xcc//触发INT3异常

        // 移去我们的EXECEPTION_REGISTRATION结构
        pop DWORD PTR FS:[0]
    add esp, 4 // 将我们的EXECEPTION_REGISTRATION弹出堆栈
    } 

  AfxMessageBox("end");  
}

是不是很简单,简单得不可思议,能简单实现的事情为什么要弄复杂呢,哈哈!

开一个远程线程实现下任意地址写0xcc,把SEH处理程序弄到全局范围内,一个远程“HOOK任意地址”就实现了。


[注意]APP应用上架合规检测服务,协助应用顺利上架!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (18)
雪    币: 419
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
我来看看...............
2010-4-20 16:47
0
雪    币: 153
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
如果原来程序的函数里面已经装了try_catch的话,是到不了你的SEH里面的。
2010-4-20 16:52
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
顶礼膜拜
2010-4-20 17:14
0
雪    币: 75
活跃值: (828)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
我觉得用seh来完成这个任务比较困难,从两个方面来说
1)seh是建立在当前函数的栈帧上.若是开个远程线程来完成楼主所说的功能,这个seh也只是建立在远程线程里面的某个函数的栈帧上,并不能影响到被你改成0xcc位置所在的函数的seh链表,从而此seh不会得到执行.

2)从mov fs:[0],esp来看,seh链是与当前线程的TEB的第一个参数.在远程线程里创建的seh只会改变远程线程的teb里的seh链表,并不会改变当前进程其他线程teb的seh链表.所以即使成功在其他线程里写下了0xcc,但并未修改它们的seh链,该seh也是不能得到执行.
2010-4-20 17:36
0
雪    币: 419
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
无效果 VC 2005 编译
2010-4-20 18:17
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
7
看来还不完善,等新酒发酵变陈酒
2010-4-20 18:26
0
雪    币: 952
活跃值: (1971)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
可用用 AddVectoredExceptionHandler?

LONG WINAPI VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
        if ( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT )
        {
                ExceptionInfo->ContextRecord->Eip++;
                return EXCEPTION_CONTINUE_EXECUTION
        }
        return EXCEPTION_CONTINUE_SEARCH;
}

AddVectoredExceptionHandler(1, VectoredHandler);
2010-4-20 18:37
0
雪    币: 260
活跃值: (47)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
SEH的确是线程相关的,是个链表结构,程序自己装了SEH对你HOOK没啥影响,和堆栈一样,我们控制好安装SEH的时机就可以避开,后安装的SEH先执行,我们的SEH先得到INT3异常处理了不传递给它本来的SEH处理就万事大吉了。在远处线程中(注入DLL实现SEH比较简单)用SetWindowsLong改下窗口过程到自己的函数,自己定义的窗口过程函数调用的这个时候FS:[0]不就是主线程的环境了吗?很容易处理,可能我表达得太简单了,没说怎么实现远处线程来操作主线程的SEH。
2010-4-20 19:45
0
雪    币: 260
活跃值: (47)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
VC高版本编译SEH记得链接的时候指定 /SAFESEH:NO即可!
2010-4-20 19:50
0
雪    币: 334
活跃值: (78)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
效率是问题, 这种方法比detours并没有什么优势
2010-4-20 20:36
0
雪    币: 75
活跃值: (828)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
12
利用seh来hook任何位置,还真不是那么容易就能处理,楼主实现一个demo让我们见识见识吧
2010-4-20 22:36
0
雪    币: 237
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
[QUOTE=droiyan;794138]看了“hook 任意函数,任意位置 【共享资源】 soucre ”一文,还以为实现了我想要的“HOOK任意地址指令”功能,遗憾的是还是和以前的HOOK代码类似,都有局限性,5个字节的跳转要求使我们总不能想HOOK啥地址就HOOK啥地址,要选一些没有相对转移的位置来实施HOOK大法。一个字节0xCC的软中断是我们理想的选择,不用考虑什么跳转不跳转,直接中断下来干点什么坏事才转回去正是我们经常用OD干的事情,为什么不能用它来HOOK呢,哈哈!搜了下,已经有前辈写过类似的利用SEH实施API hook的文章,我就不重复了,我写的不是HOOK API而是HOOK任意地址,比如给游戏开个远程线程,给它的主线程安装个“HOOK任意地址”的SEH,干点什么想干的事,那是多么惬意的事情啊,哈哈!废话少说,高手请飘过,测试代码如下:。。。
。。。。。。
SEH的确是线程相关的,是个链表结构,程序自己装了SEH对你HOOK没啥影响,和堆栈一样,我们控制好安装SEH的时机就可以避开,后安装的SEH先执行,我们的SEH先得到INT3异常处理了不传递给它本来的SEH处理就万事大吉了。在远处线程中(注入DLL实现SEH比较简单)用SetWindowsLong改下窗口过程到自己的函数,自己定义的窗口过程函数调用的这个时候FS:[0]不就是主线程的环境了吗?很容易处理,可能我表达得太简单了,没说怎么实现远处线程来操作主线程的SEH。
...[/QUOTE]

这也算hook任意地址? 怎么保证你的int3不被别的seh处理掉?,程序运行过程中创
建的线程如何“控制好安装SEH的时机”?要是没有窗口呢?SetWindowsLong
只是指定了新的窗口过程,原来的窗口过程呢?hook过去?
2010-4-20 23:03
0
雪    币: 622
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
脑子慢 不知道我这样理解对不对 异常处理都是 和进程或线程相关的 任意位置是不是这个进程的任意位置 再就是通过创建远线程的方法把 异常处理也 写进别的进程里 这样实现 为了保证 任意的 地址是不是要把异常处理写在 程序的 最前面 要不当出现一个int3的时候 不会保证异常链已经布置好了
2010-4-20 23:57
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
15
AddVectoredExceptionHandler 更具可行性.只是如果被hook的函数本身带有SEH结构就不会跑到我们设置的地方了.
如果不用inline hook,貌似希望使用这类一字节任意地址hook的,只能是额外开一个进程,以调试器方式处理,只有这样才能首先获得控制权.
2010-4-22 08:13
0
雪    币: 952
活跃值: (1971)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
不对吧? 有SEH AddVectoredExceptionHandler 也能捕捉到的 我还用这个写了一个简单调试器
2010-4-22 10:56
0
雪    币: 2242
活跃值: (488)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
17
Hook RtlDispatchException函数不行吗?
2010-4-22 11:04
0
雪    币: 75
活跃值: (828)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
18
支持16,17楼!!,veh比seh优先级高,即使有seh还是会先执行veh.
hook rtldispatchroutine比较彻底
2010-4-22 12:27
0
雪    币: 238
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
这个是正道。
2010-4-22 15:42
0
游客
登录 | 注册 方可回帖
返回
//