计划执行与检查节点
executing-plans
按既定实施计划完成工作,保持过程检查和反馈。
re-zig【效率与协作】Zig 编译产物逆向:产物识别、comptime 展开、panic/错误处理路径、C ABI 边界。 触发词:Zig逆向、zig、comptime、zig 产物、panic。
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
_start → main 启动形态),需要还原错误处理路径、C ABI 边界、comptime 展开后的行为readelf -S 查异常表节;readelf -s/llvm-nm 查符号与可见性(Zig 业务函数多为 LOCAL 符号)cmpw + 分支)strings --version@errorName 错误名字符串、panic 消息、格式串定位brew install zig / Windows 官方安装器;验证: zig version按顺序执行,每步产物存档(路径 + sha256,见 [[re-triage]])。
产物识别:
readelf -s sample | grep -iE 'panicking|panicExtra|defaultPanic|zig' | head
readelf -S sample | grep gcc_except_table # 应无输出(Zig 产物常带 .eh_frame,不能作判别)
readelf -s sample | grep __gxx_personality_v0 # 应无匹配
readelf -s sample | grep -wE '_start|main' # 启动形态
debug.panicExtra/debug.panicking 等,版本相关)、std 符号模式(std.debug.print 等)、无 C++ RTTI/异常表(对比 [[re-cpp-abi]] 的 RTTI/异常密集特征).gcc_except_table + 无 __gxx_personality_v0 + 无 _ZTV*(RTTI vtable)→ 无 C++ 异常机制;.eh_frame 两者都有,不能单独作判据符号可见性与启动路径:
readelf -s sample | grep -E 'GLOBAL|LOCAL' | grep -cE 'FUNC'
readelf -s sample | grep -wE '_start|main' | head
_start(GLOBAL)→ 运行时初始化(std.start)→ main(LOCAL);Zig 的 main 是普通函数,入口经 std.start 包裹(exit 处理在包裹层)_start 与显式 export 的函数,业务函数是 LOCAL 符号(debug/ReleaseSafe 符号表仍在,ReleaseFast 可 strip)——nm 看得到不等于导出,hook/注入面按导出表算panic/错误处理路径:
readelf -s sample | grep -iE 'panic' | head # panic 链符号(版本相关命名)
@panic/断言失败 → panic 函数(打印 + abort)——定位 panic 调用点可找输入校验/不变量;panic 处理函数本身是"打印+退出",调用点才是业务校验!T 类型,布局按载荷大小分两种(小载荷 8 字节槽、错误码在高位;大载荷错误码在前、载荷按对齐内联——[[layout]] 有实测表);调用点检查 orelse/catch 分支(编译为错误码比较 + 分支)@errorName 字符串池还原@errorName(e) 的字符串在 __zig_tag_name_* 符号/字符串池——strings 里错误名与代码路径直接对应,是错误语义的第一手线索常量与字符串定位(行为分析入口):
strings -n 5 sample | head -30 # 格式串/错误名/panic 消息
readelf -S sample | grep -E 'rodata|data' # 常量区
std.debug.print 的格式串在只读数据区,交叉引用可回到调用点(错误输出路径)comptime 与泛型展开:
std.debug.print 等 std 函数大量内联(Release 模式),readelf -s 可能只剩启动与 panic 链C ABI 边界:
@extern / @cImport:Zig 调用 C 库(导入表清晰可查——readelf -d 的 NEEDED 与导入符号)export fn:Zig 侧导出给 C/宿主调用(GLOBAL 符号,导出表可见)extern / export 或显式 callconv(.c) 的边界上才是 C ABI——编译器自身的定义是「c 是本目标 C 调用约定的别名;标记为 extern 或 export 的函数默认获得该约定」,而普通 Zig fn 用的是 Zig 默认约定(定义原文:既非 export 也非 inline 时使用;不对栈对齐、寄存器等作任何保证,且只能在同一 Zig 编译单元内使用)。所以 callconv(.c) 是显式要求 C 约定,不是普通函数的默认值.c 在该 target 的映射,不代表 Zig 内部约定本身stripped/ReleaseFast 兜底:
strings -n 6 sample | grep -iE 'panic|error' | head # panic 消息/错误名(@errorName 字符串池)
catch/orelse 分支的错误码比较)nm 列表里函数一大堆,但 nm -g(全局)只有 _start;原因——Zig 默认不导出业务符号;对策——hook/注入按导出表算;分析按 LOCAL 符号仍可定位std.debug.panic 找符号找不到;原因——0.14+ 重构为 debug.panicExtra/defaultPanic 链(老版本 std.debug.panic 直接命名);对策——按 panic 调用点(@panic 编译产物:打印+abort 序列)定位,不依赖具体符号名