feat(vm): 提升器按闭包边界切分函数 + 递归展开全部子程序
做了什么: - tdc_disasm.disassemble_cfg 增加 follow_closures 开关 (提升单函数时关闭, 避免"子函数体的可达性溢进父函数") - tdc_lift.run 递归提升所有被引用的闭包: 229 个独立函数 - 函数名统一为 sub_<target>, 便于按 pc 定位 为什么: - 原来整个程序挤在一个 function 里(闭包 body 与父函数地址连续), 无法按子程序阅读 - AGENTS.md §3.3 步骤5 明确要求"子程序调用(闭包创建)递归展开" 怎么验证: - .venv/bin/python tools/tdc_lift.py tcaptcha/core_js/tdc_sample.js -> lifted functions=229; XTEA 例程 = sub_9109, 内含 r2=(r2+2654435769) - .venv/bin/python tools/tdc_query.py .../tdc_sample.lifted.txt who r2 -> sub_9109 @9109: r2 = 0; @9285: r2 = (r2 + 2654435769);
This commit is contained in:
+39401
-2345
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -219,7 +219,7 @@ def _decode_one(z: List[int], pc: int) -> Tuple[Optional[int], List[int], Option
|
||||
return op, operands, note, pos
|
||||
|
||||
|
||||
def disassemble_cfg(z: List[int], entry: int = 0) -> List[dict]:
|
||||
def disassemble_cfg(z: List[int], entry: int = 0, follow_closures: bool = True) -> List[dict]:
|
||||
"""从 entry 出发按可达性反汇编; 返回按 pc 排序的指令列表。"""
|
||||
visited: Dict[int, dict] = {}
|
||||
work = [entry]
|
||||
@@ -244,9 +244,10 @@ def disassemble_cfg(z: List[int], entry: int = 0) -> List[dict]:
|
||||
continue
|
||||
if op == OP_PUSH_TRY and operands:
|
||||
work.append(operands[0]) # catch 目标可达
|
||||
if op == OP_CREATE_CLOSURE:
|
||||
if op == OP_CREATE_CLOSURE and follow_closures:
|
||||
# 57 的操作数 [0] 是闭包体入口: 该段代码在闭包被调用时才执行, 但它是**代码**,
|
||||
# 必须作为遍历根加入, 否则大半个程序都算不到。
|
||||
# (提升单个函数时应置 follow_closures=False, 避免子函数体溢进父函数)
|
||||
work.append(z[pc + 1])
|
||||
work.append(nxt)
|
||||
return [visited[k] for k in sorted(visited)]
|
||||
|
||||
+10
-1
@@ -79,6 +79,15 @@ class Lifter:
|
||||
self.out.append(f"// ===== lifted from tdc.js bytecode ({len(self.z)} bytes) =====")
|
||||
self.funcs[entry] = {"name": name}
|
||||
self._lift_func(entry, name)
|
||||
# 递归提升所有被引用到的闭包 (子程序展开)
|
||||
done = {entry}
|
||||
while True:
|
||||
todo = [t for t in self.funcs if t not in done]
|
||||
if not todo:
|
||||
break
|
||||
for t in todo:
|
||||
done.add(t)
|
||||
self._lift_func(t, self.funcs[t]["name"])
|
||||
return "\n".join(self.out)
|
||||
|
||||
def _func_name(self, target: int) -> str:
|
||||
@@ -87,7 +96,7 @@ class Lifter:
|
||||
return self.funcs[target]["name"]
|
||||
|
||||
def _lift_func(self, entry: int, name: str):
|
||||
insts = {i["pc"]: i for i in disassemble_cfg(self.z, entry) if i["pc"] >= entry}
|
||||
insts = {i["pc"]: i for i in disassemble_cfg(self.z, entry, follow_closures=False) if i["pc"] >= entry}
|
||||
# ---------- 第一遍: 沿执行流传播"求值栈快照"(DFS, 每 pc 记录首次到达时的栈) ----------
|
||||
state: Dict[int, List[Expr]] = {entry: []}
|
||||
seen: Dict[int, bool] = {}
|
||||
|
||||
Reference in New Issue
Block a user