Verify V8 OutlineCommand ECX ABI in machine code
This commit is contained in:
@@ -95,7 +95,7 @@ jobs:
|
||||
print("legacy MPQ gate repair verified")
|
||||
PY
|
||||
|
||||
- name: Verify Outline native Lua asm wrappers
|
||||
- name: Verify Outline Lua ABI and native wrappers
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -110,10 +110,56 @@ jobs:
|
||||
'"{ecx}"',
|
||||
'"{edx}"',
|
||||
'0x6F39F0',
|
||||
'callconv(.{ .x86_thiscall = .{} })',
|
||||
):
|
||||
if required not in src:
|
||||
raise SystemExit(f"Missing native register wrapper piece: {required}")
|
||||
print("outline.dll source: native x86 register wrappers present")
|
||||
raise SystemExit(f"Missing Outline ABI/native wrapper piece: {required}")
|
||||
print("outline.dll source: ECX callback ABI + native x86 register wrappers present")
|
||||
PY
|
||||
|
||||
objdump -d -Mintel zig-out/variants/outline.dll > /tmp/outline.disasm
|
||||
python3 - <<'PY'
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
lines = Path("/tmp/outline.disasm").read_text(errors="replace").splitlines()
|
||||
|
||||
# registerFunction("OutlineCommand", &outlineCommand) compiles near a
|
||||
# mov eax,0x704120 followed by push <callback>; push <name>; call eax.
|
||||
callback = None
|
||||
for i, line in enumerate(lines):
|
||||
if re.search(r"mov\s+eax,0x0*704120\b", line, re.I):
|
||||
pushes = []
|
||||
for nxt in lines[i + 1:i + 8]:
|
||||
m = re.search(r"\bpush\s+0x([0-9a-f]+)\b", nxt, re.I)
|
||||
if m:
|
||||
pushes.append(int(m.group(1), 16))
|
||||
if len(pushes) >= 2:
|
||||
callback = pushes[0]
|
||||
break
|
||||
|
||||
if callback is None:
|
||||
raise SystemExit("Could not resolve OutlineCommand callback address from registration code")
|
||||
|
||||
start = None
|
||||
addr_re = re.compile(rf"^\s*{callback:x}:\s", re.I)
|
||||
for i, line in enumerate(lines):
|
||||
if addr_re.search(line):
|
||||
start = i
|
||||
break
|
||||
if start is None:
|
||||
raise SystemExit(f"Could not find callback body at 0x{callback:X}")
|
||||
|
||||
block = "\n".join(lines[start:start + 14])
|
||||
print(f"OutlineCommand callback @ 0x{callback:X}")
|
||||
print(block)
|
||||
|
||||
if not re.search(r"mov\s+esi,ecx\b", block, re.I):
|
||||
raise SystemExit("BAD ABI: OutlineCommand does not capture Lua state from ECX")
|
||||
if re.search(r"mov\s+esi,(?:DWORD PTR )?\[ebp\+0x8\]", block, re.I):
|
||||
raise SystemExit("BAD ABI: OutlineCommand still reads Lua state from [ebp+8]")
|
||||
|
||||
print("outline.dll machine code: Lua state is captured from ECX")
|
||||
PY
|
||||
|
||||
- name: Stage package
|
||||
@@ -134,7 +180,7 @@ jobs:
|
||||
cat > package/README_TEST.txt <<'EOF'
|
||||
WeirdUtils Safe Standalone Core Test V8
|
||||
|
||||
This build forces OutlineCommand's WoW Lua calls through x86 register assembly wrappers.
|
||||
This build receives OutlineCommand's Lua state from ECX (x86 thiscall ABI) and keeps the native x86 register wrappers for WoW Lua calls.
|
||||
|
||||
outline.dll
|
||||
- Keeps only the Player_LoadScriptFunctions hook required to register OutlineCommand.
|
||||
|
||||
Reference in New Issue
Block a user