首页
社区
课程
招聘
[翻译]Themida TIGER 系列虚拟机的虚拟命令提取方案研究
发表于: 1天前 79

[翻译]Themida TIGER 系列虚拟机的虚拟命令提取方案研究

1天前
79

这韩国佬分析Themida的都长得这么清纯啊,欧巴欧巴。


[招生]科锐逆向工程师培训(2026年11月13日实地,远程教学同时开班, 第57期)

最后于 1天前 被zZhouQing编辑 ,原因:
上传的附件:
收藏
点赞 ・1
打赏
分享
最新回复 (2)
雪    币: 309
活跃值: (2527)
能力值: ( LV12,RANK:229 )
在线值:
发帖
回帖
粉丝
2 楼

# MV Adimeht FISH VM 结构笔记

本文档记录了 mv_adimeht analyzer 所使用的 FISH VM 的抽象模型。
不在此文档中写入每个 trace 的实际值,如 address、offset、opcode 值和 row ID。
这些值保存在 docs/mv_adimeht/trace_notes/ 下的每个 trace 笔记中。

范围

本笔记描述了当前 analyzer 代码和分析过程中推断出的 working model。
这不是 Themida FISH VM 的完整规范。如果在多个 sample 中反复确认导致 VM 结构模型本身发生改变,则更新本文档。

相关实现文件:

  • plugins/mv_adimeht.py

  • plugins/TraceAdimehtFISH.py

  • plugins/TraceAdimehtLightFISH.py

  • plugins/TraceContext.py

  • plugins/TraceTaint.py

当前主分析 trace:

  • traces/themida_vm_add_fish_red_v3.0.3.0.trace32

  • Trace note: docs/mv_adimeht/trace_notes/themida_vm_add_fish_red_v3.0.3.0.md

整体模型

FISH VM 的执行被视为在 host x86 trace 中进入 VM scope,操作 VBR-relative state block,fetch VM bytecode,决定 virtual handler,然后 dispatch 到实现单个 virtual instruction 或其一部分的 host instruction 的流程。

Analyzer 不会试图一次性从 raw host code 中直接恢复 VM semantics。
而是通过以下 VM-specific storage class 来追踪 data provenance。

  • Virtual Bus slot: VB_...

  • VM bytecode fetch: VMBLOB_...

  • virtual handler table entry: VCH_...

  • Virtual Micro OPcode slot: VMOP_...

  • virtual program counter slot: VPC_...

  • virtual handler table pointer slot: VHTP_...

术语

  • VBR: Virtual Base Register。被视为 VM 内部 state 和 Virtual Bus slot 访问基准的 base register/base value。

  • VB: Virtual Bus。VB_0x... label 表示通过 VBR + offset 访问的 Virtual Bus slot。

  • VMOP: Virtual Micro OPcode。VMOP_0x... label 表示在 dispatch cycle 中存储解码后的 micro opcode byte 的 Virtual Bus slot。

VM Scope

当前模型将 host EBP 的值视为 VM base register carrier。将整个 trace 中最常出现的 EBP 值检测为 VBR。

过去的 lightweight 模型只查看每行的 EBP 是否与检测到的 VBR 相同来判断是否在 VM 内部。当前的 LightFISH 仅将此值作为结构证据之一。收集 VBR-relative access、VHTP-range access、稳定的 EBP == VBR row 来寻找实际观察到 VM 结构的区间,并包含其前后的 context-save prologue 和 restore epilogue,从而创建 vm_intervals。

具体来说,entry 侧优先查找第一个结构证据之前的 pushfd/pushf stack write,exit 侧优先查找最后一个结构证据之后 popfd/popf restore 之后的 ret。这个 full interval 用于 [VM] comment 和 UI 显示,provenance 追踪使用从第一个结构证据开始的 vm_tracking_intervals。这样可以在将像 black 系列那样 EBP 暂时变为非 VBR 值的 VM 进入/退出区间标记为 VM scope 的同时,避免将 host register 保存 stub 过度 seed 到 VM data-flow 中。

VBR And VB Slots

VBR 是 Virtual Base Register。在当前 trace 模型中,它被追踪为 VM 内部 state 和 Virtual Bus 访问的基准 base value。effective address 为 VBR + offset 形式的 memory access 被建模为 Virtual Bus slot。

text

VBR + offset -> VB_0x{offset}

一些 VB_... slot 在 detection 之后会获得更具体的 label。

  • VPC_0x...: virtual program counter slot

  • VHTP_0x...: virtual handler table pointer slot

  • VMOP_0x...: Virtual Micro OPcode slot

一般的 VB_... slot 可以是 Virtual Bus 上的 virtual register、temporary VM state、dispatch state、handler-local value 等。仅凭抽象 label 不能确定准确的 semantics,只具有作为基于 VBR 的 offset 访问的 Virtual Bus slot 的含义。

VPC

VPC 被视为被重复读取后像 VM bytecode fetch address 一样被反向引用的 VBR-relative slot。

当前的 detection heuristic:

  • 收集 VBR-relative slot 的 read/write。

  • 针对每个 slot,计算 read value 在短暂的 lookahead 内再次被用作 memory address 的比例。

  • 选择 pointer-dereference behavior 最强的 slot。

执行过程中的 VPC write 被标注(annotate)为 virtual program counter 的移动。arithmetic write 尽可能解释为相对于前一个 VPC 值或当前 VPC base 的 stride。

VPC provenance 的基本策略是保留 VPC_... 本身。即使使用了像 ADD [VPC], offset 这样由 bytecode 派生的 stride,该 stride 也仅在该 fetch row 上被标注为 vpc stride,而不视为在更新后的 VPC 值中继续存活的 provenance。因为 Program counter 更接近于表示下一个 fetch 位置的 cursor,如果持续 carry 过去的 offset source,会使后续的 fetch 和 VB offset annotation 被过度污染。

VMBLOB

如果 Memory read 使用了 VPC-derived address,则将访问的 concrete address 标记为 VM bytecode fetch。

text

VPC-derived read -> VMBLOB_0x{fetch_addr}

VMBLOB_... label 是 provenance marker。它是用于追踪哪个 bytecode byte 或 field 对后续的 VM state、handler index 计算、VPC 移动、VMOP assignment、branch decision 做出了贡献的名称。

Fetch row 可以带有反向 annotation。

  • fetch

  • vmop

  • vpc stride

  • vb offset

  • vhtp index

  • vtable offset

Fetch annotation 会一直保留,直到通过 VCH table entry load 确认 handler selection。VPC arithmetic update 可以在同一个 virtual instruction decode 流程中发生,因此不能仅仅因为 VPC 移动了就关闭 fetch row mapping。如果确认了 VCH load,就关闭相应的 fetch row mapping;如果之后再次 fetch 同一个 concrete bytecode address,则重新记录为新的 dynamic fetch row。

VHTP And VCH

VHTP 被视为与观察到的 VPC 值分离的 stable VBR-relative slot。在当前 sample 中,它被用作 handler-related indexing 的基准值,与其说是固定的 code-section 本身,不如说被解释为计算下一个 handler/dispatch 位置的 virtual PC 系列状态值。

如果在 VHTP-derived address 上发生 read,则建模为 virtual handler table access。

text

VHTP + index * entry_size -> VCH_0x{index}

VCH_... label 追踪由 VM bytecode-derived value 选择的 handler。如果 JMP 或 CALL 使用了携带 VCH_... label 的值,analyzer 会将那一行标注(annotate)为 handler transfer。

特殊 label VTABLE 可以在 VHTP-derived index 被解释为 root table position 而不是 concrete handler entry 时使用。

VMOP

VMOP 是 Virtual Micro OPcode slot。被视为在 Dispatch cycle 中存储解码后的 micro opcode byte 的 VBR-relative slot。

当前的 detection heuristic:

  • 从候选中排除 VPC 和 VHTP。

  • 必须有重复的 write。

  • 观察到的 nonzero value 必须在 1 byte 范围内。

  • reads-per-write 比例必须高。

  • 排除像 pointer 一样行为的 slot。

如果 VM bytecode-derived value 被 write 到 VMOP,可以在对该值做出贡献的 fetch row 上标注(annotate) opcode byte。之后利用该 slot 的 read 和 comparison 来检测 dispatch decode point。

Dispatch And Decode

当前模型将许多 dispatch decision 视为 comparison 之后跟随 conditional branch 的形式。

Full mode 会更精确地追踪以下信息。Light mode 也可以标注(annotate) VMOP slot、VMOP write、简单的 VMOP-derived decode decision。

  • 对当前 VMOP 做出贡献的 bytecode fetch

  • flag-setting instruction 执行时点存在的 symbolic variable

  • 随后的 conditional branch 是否对应于 VMOP decode match

如果 Branch condition 意味着 equality match,analyzer 可以输出针对当前 VMOP value 的 decode annotation。

非 VMOP branch decision 如果 comparison 源自正在追踪的 VB_... 或 VMBLOB_... 值,也可以标注(annotate)。

Symbolic And Lightweight Modes

Full mode 即 TraceAdimehtFISH,通过 TraceContext 和 TraceTaint 使用 z3-backed symbolic expression。它可以表达 mixed provenance 并恢复更详细的关系,但成本更高。

Lightweight mode 即 TraceAdimehtLightFISH,将 provenance 作为 label set 来追踪。它是用于快速重复执行和 UI-friendly tracing 的 mode。主要结构概念与 full mode 相同,但不保留 full symbolic expression。

两种 mode 至少必须在以下大的结构上保持一致。

  • VM scope

  • VBR-relative slot

  • VPC fetch source

  • VHTP/VCH handler selection

  • bytecode-to-state provenance

如果两种 mode 产生不同结果,首先将 sample-specific evidence 记录到 trace 笔记中。在多个 sample 中反复确认模式之前,不改变此抽象模型。

Analysis Flow

Analyzer 目前大致按以下顺序运行。

  1. 从 Host EBP 的 dominant value 中检测 VBR。

  2. 检测 VPC、VHTP、full mode 的 VMOP 等 special VBR-relative slot。VPC 默认使用 20-row lookahead 查找,像 black 那样延迟 fetch 很大的情况,使用 1000-row lookahead fallback。

  3. 利用 VBR/VHTP/VB 访问和 prologue/epilogue 检测 VM interval。

  4. 解析每个 host instruction 和 operand。

  5. 判断当前 row 是否在 VM scope 内部。

  6. 将 VBR-relative slot access 注册为 VB_... 或 special slot。

  7. 将 VPC-derived memory read 注册为 VMBLOB_... fetch。

  8. 在 black 系列中,如果像 push [VMBLOB] 这样 fetch payload 先被存储到 host stack,则注册为 STACK_0x... temporary carrier,并在之后的 stack read/pop 中再次传播到 register 或 VB slot。

  9. 追踪 Fetch 的 bytecode data 传播到 VM slot、VPC movement、VMOP、VHTP indexing、handler transfer 的流程。

  10. 在 Trace row 上标注(annotate) symbolic disassembly 和 internal VM event。

  11. 保存要显示在 UI table 上的 row snapshot。

每个 Trace 的实际值

以下值不保存在此抽象笔记中,而是保存在每个 trace 的文件中。

  • 检测到的 VBR

  • VPC、VHTP、VMOP offset 和 concrete address

  • VHTP concrete value

  • 确认了含义的主要 VB_... slot

  • 重要的 VMBLOB_... fetch address 和 row ID

  • handler index 和观察到的 transfer row

  • decoded VMOP value 和 row ID

  • 仅在特定 sample 中成立的 assumption

添加新的 sample note 时,使用 docs/mv_adimeht/trace_notes/TEMPLATE.md。


1天前
0
雪    币: 12614
活跃值: (10175)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3 楼
感谢分享
1天前
0
游客
登录 | 注册 方可回帖
返回