executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
re-fp-runtime函数式语言运行时逆向(Haskell/OCaml):闭包/堆对象模型、调用约定、数据流优先策略。 触发词:Haskell逆向、OCaml逆向、GHC RTS、thunk、STG、OCaml runtime、闭包、函数式产物。
Independent GitHub snapshot · Automated classification · Original documentation governs
apt install ghc / brew install ghc / ghcup);Windows: ghcup(winget install ghcup 或官网安装器);验证: ghc --versionapt install ocaml / brew install ocaml);Windows: opam(winget install OCaml.opam)或官网安装器;验证: ocamlobjinfo 处理任意 .cmx 输出 CRC 与导入表file/xxd);Python 3 自带 struct按顺序执行;逆向着重数据流而非控制流(函数式产物控制流被打散,见坑 4)。每步产物存档(路径 + sha256,见 [[re-triage]])。
运行时识别:
readelf -s sample | grep -iE 'ghc|stg_|RTS|HsMain|_closure|_info' | head # GHC 特征
readelf -s sample | grep -iE 'caml_' | head # OCaml 特征
file sample # 字节码产物判别(脚本头)
main(C RTS 入口)+ RTS 运行时符号(stg_*/hs_*)+ 业务符号 Main_main_closure/Main_main_info(模块_名字_closure/info 形态)main → caml_main → caml_startup_common → caml_start_program → caml<模块>__entry;caml_startup/caml_startup_pooled 是供 C 嵌入调用的等价入口(签名同为 void (char_os **argv),区别在 pooling 标志与异常行为),勿误当主链;caml_* 运行时符号(caml_alloc/caml_apply2/3 等)caml_start_program 仅存在于 native 运行库(4.14.2 libasmrun.a 实测),是 native 特征;字节码判据用 caml_interprete(仅 libcamlrun.a 有);字节码产物判别用 file(ocamlrun script executable)/xxd 头(#!...ocamlrun\n 脚本头 + T/C 魔数 + 分节)main 并调用 caml_main(argv)(caml_main 定义于 startup_byt.c/startup_nat.c;原生链 main → caml_main → caml_startup_common → caml_start_program,4.14.2 实测地址见 [[examples]]);字节码运行库入口为 caml_main → caml_startup_aux → caml_interpretestg_* 机械符号群 + 模块_名_closure/info 对;OCaml 原生 = caml_* 群 + caml<模块>__<名>_<id>;OCaml 字节码 = #!ocamlrun 脚本头闭包与堆对象:
Main_main_closure 是 CAF,其 info 指向 thunk 求值代码调用约定:
_info 符号 = entry code)caml_applyN;原生代码调用闭包 = 寄存器装载 + caml_apply2/3 或直接跳 entrycaml_apply / stg 入口)再进用户逻辑;尾调用优化使递归变跳转(无增长栈帧),按循环读jmp 目标地址即函数入口,别按 call/ret 配对思维读分析策略(数据流优先):
构造器 C1 (tag 0, 2 字段) ← 分配点 A (caml_alloc2 / info 表)
字段0 ← 函数参数/常量(数据来源)
字段1 ← 字符串池引用
使用点: tag 比较 → 分支 B(业务逻辑)
字节码产物(OCaml 特有):
head -c 64 sample | xxd # #!...ocamlrun 脚本头 + 魔数 T/C + 长度
ocamlobjinfo sample # 直接解析字节码可执行文件(导入单位/CRC)
T + 代码区 + 各分节数据;分节名(CODE/PRIM/DATA/SYMB/CRCS 等 4 字符)与大端长度表在文件尾部 TOC,文件以 Caml1999X031 收尾(结构见 [[layout]],字节样例见 [[examples]])caml_start_program 仅 native 运行库有,是 native 特征;字节码判据用 caml_interprete)GHCziInternalziTopHandler_runMainIO1_info 难读;原因——z+小写转义特殊字符(GHC mangling:zi=. zu=下划线 zz=z zc=: zh=# 等);对策——按转义规则手工还原模块名(GHCziInternal → GHC.Internal),还原后与源码模块结构对应jmp 回函数自身地址 = 递归,按循环语义读,别找增长栈帧stg_ap_*/stg_upd_frame_info 等被当成业务逻辑分析;原因——STG 机械符号是求值机制;对策——先按 stg_/hs_ 前缀把 RTS 机械符号排除,业务代码集中在 模块_名_info 与调用 caml_applyN/caml_alloc* 的片段