首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >VEH注入:从v1到v27 | 我花了一整天证明自己是个天才

VEH注入:从v1到v27 | 我花了一整天证明自己是个天才

作者头像
Ms08067安全实验室
发布2026-05-07 17:13:47
发布2026-05-07 17:13:47
900
举报

文章来源|MS08067 红队攻防小组

作者:Bomb

起因

免杀这个东西,做到后面你会发现常规路子基本都死了。

CreateRemoteThread?EDR盯着呢。QueueUserAPC?行为检测等着你。SetWindowsHookEx?更别想了,这玩意儿被盯了十几年了。

所以安全圈开始往异常处理这条路走。思路很简单:不走常规API,故意搞一个异常出来,让系统调用你注册的异常处理器,在处理器里执行payload。EDR只盯着那些敏感API调用,你根本没调,它拿你没办法。

VEH,Vectored Exception Handler,就是这条路的主角。全局注册,不跟栈帧绑定,理论上很优雅。

理论上

handler和stub

先说原理,不啰嗦。

VEH注入就两个东西。一个叫handler,一个叫stub。

handler是你雇的保镖。你把他安排好了,他就站在那等。一旦出事——也就是异常发生了——他第一个冲上去。处理完了跟你说没事了,你就继续干你的。

stub是那个故意摔跤的人。他先雇好保镖,注册handler,然后故意搞一个异常出来。保镖冲上来处理,处理完他拍拍灰站起来继续走。

就这么简单

我当时也是这么理解的。然后我就开始写了。

handler是保镖,stub是那个故意摔跤的人

偏移计算,人类的敌人

shellcode写好之后,有些位置需要运行时动态修改。函数地址啊、参数啊这些,写代码的时候还不知道,得跑起来再填。

最直接的办法:算好偏移,直接写过去。

我开始手算。

然后发现x64指令编码是个深渊。

你以为某个指令的机器码是这个,反汇编一看是那个。你以为偏移0x88是正的,CPU说不好意思这是-120。你改了一个字节,后面所有偏移全乱。

从v1到v5,我一直在跟偏移较劲。每次觉得这次算对了,一跑就崩。改,跑,崩。改,跑,崩。

五个版本

最后我认输了。

改用哨兵值方案——在shellcode里埋一个特殊标记,运行时扫到就替换成实际数据。就像在地图上插旗子,你不需要知道具体坐标,认得旗子就行。

从此偏移问题消失。

五个版本换来的教训:能自动化的别手算。人类不是为这种活设计的。

v1到v5,与偏移计算的残酷損失

那个该死的返回值

偏移搞定之后我信心满满。

v6,跑了。handler被调用了。payload执行了。然后进程死了。

进程保护?没有保护。那是什么问题?

v7,改了点东西,崩。v8,换个思路,崩。v9,v10,v11......全崩。

我开始怀疑是不是Windows更新改了什么行为。甚至想过是不是目标环境有问题。

从v6到v15,我在各种方向上排查。每改一个地方就编译一次,每次都满怀希望,每次都进程崩溃。

最后发现,handler返回了0

0是什么意思?EXCEPTION_CONTINUE_SEARCH。翻译成人话就是“我没处理这个异常,帮我找下一个人”。

系统说好我找。找了一圈没人处理。那就杀了吧。

而正确答案是-1EXCEPTION_CONTINUE_EXECUTION。“我处理好了,继续。”

一个0和一个-1,一个让进程活着,一个让进程去死

这是Windows异常处理入门第一页的东西。第一页。我翻到了第二页、第三页、第十页,唯独没看第一页。

v1到v27,十几个版本,一整天,败给了一个常量值。

说实话当时真的想砸键盘。

APC上下文,异常的禁区

返回值修好之后,下一个问题:怎么触发异常?

stub需要触发一个异常让handler被调用。常见的方式有几种,我选了一种,跑了,崩了。

换一种,崩了。

再换一种,活了

事后分析才知道,前两种方式在APC上下文中不能被VEH捕获。你的stub是通过APC注入到目标线程执行的,在这个上下文里,有些异常触发方式就是不管用,VEH看不见。

不是方式不对,是场景不对。

这个坑文档里不会告诉你。教程里不会提到。只有你亲自在APC上下文里跑一遍才会知道。

v27

v27通了。

那天晚上我看着屏幕上success的输出,没有兴奋,只有疲惫。十几个版本,一整天,最终败给了一个返回值写错。

但回头看,这些坑踩得也不算白踩。哨兵值方案是我最终留下来最有价值的东西,它彻底解决了偏移问题。APC上下文的限制让我对Windows异常分发机制有了更深的理解。handler返回值这个教训,我这辈子不会再犯。

如果你正在研究VEH注入,希望这篇文章能帮你省掉那一天。

从v1到v27,一条用代码铺成的路

记住三件事

1. handler返回-1,不是0。

2. APC上下文里不是所有异常都能被VEH捕获。

3. 能自动化的别手算。

就这三句,值一整天。你不用谢我,去写你的v1吧。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-05-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Ms08067安全实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章来源|MS08067 红队攻防小组
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档