ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SmmBackdoor周期性定时器解析:轮询机制的设计精髓

SmmBackdoor周期性定时器解析:轮询机制的设计精髓 SmmBackdoor周期性定时器解析轮询机制的设计精髓【免费下载链接】SmmBackdoorFirst open source and publicly available System Management Mode backdoor for UEFI based platforms. Good as general purpose playground for various SMM experiments.项目地址: https://gitcode.com/gh_mirrors/smm/SmmBackdoorSmmBackdoor 是首个开源的 UEFI 平台 SMM系统管理模式后门也是 SMM 实验的经典练习场。该项目最优雅的设计就是它的周期性定时器Periodic TimerSMI 轮询机制用户态代码只需原地空转固件定时器每 100 毫秒唤醒一次偷看CPU 寄存器状态从而完成最高特权级的请求。下面结合项目源码带你轻松看懂这套轮询机制的设计精髓。1️⃣ 背景用户态如何够到最高特权的 SMMSMM 是 CPU 中权限最高的运行模式普通用户态程序无法直接跳入只能通过触发SMI系统管理中断进入。SmmBackdoor 内置了两条通信通道通信通道触发方式使用方软件 SMI写 I/O 端口 0xCC主机端工具 SmmBackdoor.py经物理内存中转周期性定时器 SMI固件定时器心跳用户态 smm_call 程序轮询通道定时器参数定义在SmmBackdoor/SmmBackdoor.c中// SMM periodic timer register context (time in 100 nanosecond units) EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT m_PeriodicTimerDispatch2RegCtx { 1000000, 640000 };换算一下1,000,000 × 100ns 100ms 心跳间隔640,000 × 100ns 64ms 容差。也就是说SMM 定时器处理函数会以约每秒 10 次的频率被唤醒——这就是轮询的心跳。2️⃣ SmmBackdoor 轮询机制的三步走第一步用户态设置魔法值进入无限等待循环用户态程序smm_call的实现位于smm_call/smm_call.asm核心逻辑非常短; 设置魔法握手值R80x41...R90x42... mov r8, R8_VAL mov r9, R9_VAL ; RDI命令码RSI参数1RDX参数2 mov rcx, _loop jmp rcx ... _loop: nop jmp rcx它把 R8 置为0x4141414141414141、R9 置为0x4242424242424242这两个魔法值定义在SmmBackdoor/config.h把命令码和参数放进 RDI/RSI/RDX然后jmp rcx死循环空转。用户态不触发任何 SMI只是安静地等待。第二步定时器处理函数每 100ms 轮询一次寄存器SMM 侧的PeriodicTimerDispatch2HandlerSmmBackdoor/SmmBackdoor.c约 882 行在每次心跳到来时先自增m_PeriodicTimerCounter并写入共享结构体BACKDOOR_INFO.TicksCount心跳计数用于存活检测通过SmmCpu-ReadSaveState()读出当前 CPU 被中断时保存的 CR0、CR3、RDI、RSI、RDX、R8、R9 等寄存器检查 R8、R9 是否等于魔法值。第三步命中魔法值 → 处理请求 → 优雅退出循环一旦匹配成功SMM 侧完成三件事执行请求调用SmmCallHandle()分发命令码ping、读/写物理内存页、读/写虚拟内存页、调用子程序等命令码定义见SmmBackdoor/SmmBackdoor.h回写返回值把EFI_STATUS写入保存状态的 RAX用户态smm_call()函数直接以 RAX 作为返回值ret改写 RCX将保存状态的 RCX 减去 6MAX_JUMP_SIZE让下一次jmp rcx落到循环后的着陆区6 条 NOP 短跳指令从而跳出无限循环。整个握手流程示意用户态 smm_call SMM 定时器处理函数 │ R8/R9魔法值, RDI/RSI/RDX参数 │ │ jmp rcx 死循环空转 ──────────────────▶ │ 每100ms醒来 │ │ 读保存寄存器 → 匹配魔法值 │ │ 执行 SmmCallHandle() │ ◀────────────────── 回写 RAX状态码 │ │ ◀────────────────── 回写 RCX循环出口 │ RCX - 6 │ jmp rcx 落到着陆区 → ret 返回 │3️⃣ 为什么选择周期性轮询而非直接触发 SMI这是整个设计最精髓的部分四个理由设计考量说明可靠性定时器 SMI 由固件自身周期性发出不受操作系统对 SMI 端口、SMI 屏蔽等限制的影响在整个运行时阶段稳定可用彻底解耦用户态与 SMM 之间仅共享寄存器值这一信息通道无需共享内存、无需 I/O 端口映射攻击面最小可观测性TicksCount心跳计数让主机端随时可用SmmBackdoor.py --test验证后门存活、定时器是否在跳动⚖️开销可控命令码 5TIMER_ENABLE/ 6TIMER_DISABLE可随时开关定时器用SmmBackdoor.py --timer-enable / --timer-disable下发空闲时零开销此外smm_call/main.c用sched_setaffinity()把进程绑定到 CPU 0保证定时器 SMI 在 CPU 0 上醒来时轮询到的正是目标进程的寄存器快照。4️⃣ 点睛之笔RCX 倒带技巧传统做法是用户态主动敲门触发 SMI而 SmmBackdoor 反过来SMM 在每次心跳时主动巡逻发现魔法值后再替用户态修改下一条要执行的指令把 RCX 指回 6 字节之前让jmp rcx恰好落进着陆区跳出循环。相当于最高特权级的代码在替低特权级的程序拨号挂机——这是轮询式后门中非常优雅的人机机机交接设计。5️⃣ 关键文件导读建议先克隆仓库git clone https://gitcode.com/gh_mirrors/smm/SmmBackdoor然后按下面的路径精读SmmBackdoor/SmmBackdoor.c—— 定时器上下文注册、PeriodicTimerDispatch2Handler轮询主逻辑、SmmCallHandle命令分发SmmBackdoor/config.h—— 软件 SMI 值 0xCC 与 R8/R9 魔法寄存器值SmmBackdoor/SmmBackdoor.h——BACKDOOR_INFO结构体含TicksCount心跳计数与全部命令码smm_call/smm_call.asm—— 用户态无限等待循环与着陆区smm_call/main.c—— CPU 绑定与命令行参数解析SmmBackdoor.py—— 主机端--timer-enable/--timer-disable/--test控制命令6️⃣ 总结轮询设计的四个要点心跳即通道周期性定时器把被敲门变成定时巡逻天然稳定可靠魔法值握手R8/R9 双寄存器校验避免误触发简单又安全寄存器即接口无共享内存、无 I/O 端口请求与返回值都走保存状态寄存器RCX 倒带退出SMM 侧精准改写用户态下一条指令优雅跳出等待循环。这套100ms 心跳 魔法寄存器 RCX 倒带的组合用极少的代码实现了用户态到 SMM 的可靠双向通道堪称 SMM 后门设计中值得反复品味的经典范例。✨【免费下载链接】SmmBackdoorFirst open source and publicly available System Management Mode backdoor for UEFI based platforms. Good as general purpose playground for various SMM experiments.项目地址: https://gitcode.com/gh_mirrors/smm/SmmBackdoor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表