You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PE打包器中不增大.text段的控制流混淆:如何识别跳转来源?

解决PE打包器跳转来源识别问题(无.text扩容、无call/异常方案)

核心思路

利用新建的.pack段存储专属stub入口和加密表,为每个被替换的跳转指令分配独立的stub小片段(硬编码来源标识),同时保证.text段仅替换同长度指令,完全不扩容。

可行实现方案

1. 专属Stub入口+硬编码来源地址

这是最直接且可靠的方案:

  • 构建阶段:
    • 扫描.text段时,为每个跳转指令(如jb 0x8F在0x6D处)记录三个关键信息:原指令地址src_addr、原指令长度len、原目标地址dest_addr,并将这些存入.pack段的加密表(可按src_addr哈希或直接索引存储)。
    • 为每个跳转指令生成一个极小的专属stub片段,硬编码其src_addr:
      BITS 64
      ; 为0x6D处的跳转生成的专属stub
      stub_src_0x6D:
          mov rcx, 0x6D        ; 硬编码原跳转指令地址
          jmp common_handler   ; 跳转到公共处理逻辑
      
    • 将原.text段的跳转指令替换为同长度的条件/无条件跳转,指向对应的专属stub入口(比如原2字节jb rel8替换为2字节jb stub_src_0x6D,确保字节数完全一致,不扩容.text段)。
  • 运行阶段:
    • 当条件满足触发跳转进入专属stub后,rcx已携带原跳转地址。
    • 公共处理逻辑用rcx查询加密表,取出原目标地址dest_addr。
    • 直接执行无条件跳转到dest_addr(因为能进入stub说明原跳转条件已满足)。

2. 反向计算原跳转地址(无需专属Stub入口)

如果想减少stub的数量,可通过CPU的RIP寄存器反向推导原跳转地址:

  • 构建阶段:
    • 替换跳转指令时,记录原指令地址src_addr、长度len、原目标dest_addr,存入加密表。
    • 替换后的跳转指令为同长度相对跳转,指向公共stub入口。同时,将替换后的跳转指令的相对偏移值(即stub_addr - next_inst_addr,next_inst_addr是原跳转指令的下一条地址)和原指令长度len关联存储。
  • 运行阶段:
    • 进入stub后,通过lea rax, [rip]获取当前RIP值。
    • 计算原跳转指令的下一条地址:next_inst_addr = RIP - rel_offset(rel_offset是替换后的跳转指令中的相对偏移值,需提前存入加密表)。
    • 原跳转地址src_addr = next_inst_addr - len。
    • 用src_addr查询加密表得到原目标地址,执行跳转。

关键注意事项

  • 必须严格保证替换后的跳转指令与原指令长度完全一致,避免破坏.text段的字节对齐和后续指令的正确性。
  • 条件跳转的处理:只有原条件满足时才会进入stub,因此stub中无需重复判断条件,直接跳转到原目标即可。
  • 加密表需做简单混淆(如异或、简单置换),避免静态分析直接获取原目标地址映射。

内容的提问来源于stack exchange,提问作者Alon Alush

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 13:44:51