Skip to content

docs: VBA 注入的 document-module 綁定陷阱 — codeName 缺失讓巨集「看似正常、執行全滅」(429/靜默 no-op) #138

Description

@kiki830621

Problem

Original text:
「幫我放進macdoc」
— Source: 使用者(2026-07-17,VBA 注入 no-op 之謎破案後)

zip 注入 vbaProject.bin 到 openpyxl 產的 xlsx 時,document-module 綁定缺失會讓 VBA 專案「看似正常、執行全滅」——巨集清單看得到、run VB macro 回成功,但沒有任何巨集真的執行。這個 gotcha 在網路上的 xlsm 注入教程幾乎沒人提,實戰花了一整個下午才破案,必須沉澱。

Type

docs

根因

vbaProject.binPROJECT stream(明文,MBCS 編碼)宣告 document modules:

Document=ThisWorkbook/&H00000000
Document=<carrier 的 sheet codeName>/&H00000000

綁定鍵在宿主端 XML:

bin 宣告 宿主綁定鍵 缺失時的後果
Document=ThisWorkbook xl/workbook.xml<workbookPr codeName="ThisWorkbook"/> 致命:ThisWorkbook 物件無法解析 → 任何巨集一觸碰它就拋 429「ActiveX 元件無法產生物件」
Document=<sheet> xl/worksheets/sheetN.xml<sheetPr codeName="..."/> 次要:配對未定義(懸空 module 通常無害)

openpyxl / LibreOffice 產的檔都不寫 codeName → 注入的 VBA 天生殘廢。

三個惡性疊加(為什麼難診斷)

  1. 429 被巨集自己的 On Error handler 吃掉 → 錯誤 MsgBox 一閃而過或被忽略,表面「執行完成」
  2. Mac Excel AppleScript run VB macro 對解析失敗靜默回 exit 0(對不存在的巨集名也一樣!);詭異的是帶 module 限定名(Module.Sub)反而能觸發真執行並暴露錯誤
  3. 輸出恰好等於預期值時,no-op 與成功不可區分——靜態預填值本來就正確,巨集沒跑也「全對」

修法(注入器一併縫,純檔案層)

# xl/workbook.xml
<workbookPr/><workbookPr codeName="ThisWorkbook"/>
# xl/worksheets/sheetN.xml(每張)
<sheetPr .../><sheetPr codeName="工作表N" .../>

注意 <sheetPr> 可能帶既有屬性或不存在——regex 要處理三種形態,且絕不能產生重複的 sheetPr 元素(schema 違規 → Excel 靜默拒開,又是一個無聲失敗)。

驗收方法論(本案最大教訓)

驗收必須要求可觀察的狀態改變,不能只驗「結果正確」:

改輸入(利率 1.75% → 3%)→ 跑巨集 → 輸出必須改變(且與獨立實作的理論值一致)
→ 改回 → 輸出必須復原

實測修復後:42,112 格中恰好 310 格如 Python 引擎理論預測地改變——雙實作逐格吻合才算驗證完成。「跑了沒報錯 + 結果正確」在這個 bug class 面前毫無鑑別力。

Expected

Impact

  • 沒有這頁,任何人(包括未來的 AI session)做 xlsm 注入都會掉進同一個「看似成功實為全滅」的洞,且平均要數小時才爬得出來
  • xlsm 的失敗模式可作為 docm/pptm 的研究假說;各格式的 host model、relationship、content type 與真實 fixture 必須另案驗證,不能由本案直接宣稱適用

Refs #135, #136

Priority

P2


Current Status

Phase: verified
Last updated: 2026-08-13 by idd-verify

Delivered

Evidence qualification

Blocking

  • (none)

Commits

  • authoritative:554b8a895d6d1faeaec3c66688c10263dd39649a

Verify

Platform capability status

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationplatform:cross含不依賴作業系統的格式、規格或實作範圍;不等於所有 runtime 已驗證platform:macos含 macOS 專屬行為、實作或已驗證範圍

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions