Conversation
Naked _emit passthrough: __chkstk prologue (4-byte spill slot), folded PUSH EDI doubles as the first arg to FUN_00464030, loop accumulates via EBX/ESI with POP ECX epilogue to discard the __chkstk alloc.
Naked asm: ESI=str/EDI=anchor register allocation and 3-byte loop-align NOP (8d 49 00 = LEA ECX,[ECX+0]) resist clean C++ reproduction; used _emit byte-emission approach (mirrors FUN_004134b0 idiom).
Naked-asm byte passthrough — EH4 SEH prologue with __security_cookie and IAT-indirect calls cannot be reproduced by source-level MSVC 2005 /O2.
UTF-16LE→UTF-8 encoder; naked-asm byte passthrough — register allocation (EBP=dst with /Oy, EBX=src, shrink-wrapped ESI=n) and the temp-byte spill into the caller's arg2 stack slot without SUB ESP make source-level matching brittle (same class of issue as FUN_00401b70). Direct _emit passthrough of the 173 orig bytes is byte-identical; the single rel32 CALL to _memcpy is wildcarded by compare.py. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Branch-flip fix: writing the condition as `if (index <= 0x1e) return table[index]; return 0;` causes MSVC to negate to JA, placing the table lookup as fall-through — matching the orig's JA +8 to the XOR/RET path.
OpenSSL X509_PUBKEY_get — naked byte passthrough; absolute filename address 0xf6900c baked as raw immediate prevents source-level match.
Pure _emit passthrough for all 134 bytes except the REL32 CALL to FUN_0045ad60 at offset 0x72; the unique SIB address [EAX+ESI*1+0x20] (88 4c 30 20) at offset 0x53 required explicit _emit bytes to guarantee the base/index register assignment. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Naked-asm byte passthrough of the 387-byte reloc-heavy body (six rel32 CALLs, CRT thunks, and imm32 string/context pointers) — same idiom as the FUN_0040ced0 / FUN_00415d00 siblings. GREEN, 387/387. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Naked-asm byte passthrough — EH4-SEH wrapped wide-string compare helper; scope-table addr (0xe581d8) and IAT absolute addresses embedded as raw immediates.
Naked-asm _emit byte passthrough — seven reloc-bearing sites (three CALL rel32 + four DIR32 memory/immediate refs) make a source-level high-level match impractical; raw-byte emission gives GREEN first try.
Naked-asm byte passthrough: switch dispatch on ASN.1 item type byte, ESI as implicit caller-provided output pointer. All bytes emitted verbatim via _emit — no relocations needed since relative JMP offsets and the absolute jump-table VA are the same post-fixup byte values as in the original PE. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Naked byte-passthrough: EH4 SEH frame with callee-save PUSHes interleaved before the cookie XOR; inline MSVC 2005 pattern is not reproducible from source-level C++ without register allocation drift. All 291 bytes match directly (no relocations needed). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Straightforward naked-asm match for int_thread_release: two early-exit JZ null-guards, five-arg CRYPTO_add_lock decrement call, JG skip over *pHandle clear when refcount > 0.
9-byte MSVC /O2 loop-alignment NOP sequence (LEA ESP,[ESP+0] + MOV EDI,EDI) pads the loop body to a 16-byte boundary; emitted as _emit directives to match Ghidra's 56-byte function slice byte-for-byte. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Naked-asm byte passthrough of the SEH-framed /GS lookup-and-retry helper; reloc-heavy body (SEH scope table, double security cookie, 18 reloc windows) re-emitted verbatim, byte-identical 413/413. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Naked trampoline: SUB [ESP+4],4 then tail-jmp to FUN_00459610 — matched first try with __declspec(naked) inline asm.
Naked-asm passthrough: three _emit pins (eb 03 forward JMP, 8d 49 00 three-byte NOP aligning loop-top to 16 B, 8a 04 3e SIB MOV AL,[ESI+EDI]) plus appending the 3 shared-epilogue bytes that size_overrides.json extends the function to 72 B.
Naked-asm byte passthrough for asn1_ex_i2c; the switch-table DIR32 at +0x59 and three CALL rel32s are the only relocations, all masked by compare.py — remaining 343 non-reloc bytes are identical on first try.
OpenSSL X509_NAME_add_entry_by_txt — naked-asm byte passthrough. Same pre-load-before-PUSH-ESI pattern as adjacent sibling FUN_0046eda0; no data relocations, only three REL32 call targets.
Naked-asm byte passthrough: /GS cookie + 3-field SEH frame prologue not reproducible from C++ source; _emit verbatim 137 bytes → GREEN.
PUSHAD/POPAD-based DLL loader; pure _emit passthrough preserves A1-opcode MOV EAX,[moffs32] and POP EBX caller-cleanup idiom. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Naked-asm with mnemonics; no relocations, straight mnemonic form reproduced the three short-Jcc forward branches byte-identically.
Naked _emit byte-passthrough. __chkstk alloca frame (0x1c), global singleton ptr at [0x0132e7b4], delegates to FUN_004641d0; same pattern as FUN_0046a0f0.
Naked asm vtable-slot-10 dispatcher: loads [ESP+4] into ECX, dereferences the vtable, null-checks slot 0x28, tail-calls the function pointer (with arg restored at [ESP+4]) or returns -1 if null.
MSVC 2005 /O2 /Oy tail-calls sk_num directly via JMP after a null guard; re-stores EAX into [ESP+4] before the jump (canonical tail-call lowering).
EH3/GS prolog with ESP-relative frame; MOV [ESP+0x28],ESI (post-push) zeroes the initial EH state to 0 mid-body.
Naked-asm byte passthrough (453 B) — same idiom as siblings FUN_00409350 / FUN_0040b840: reloc-heavy profiled registration routine with __chkstk small-frame prologue, ~15 rel32 calls and absolute global loads/stores; emitted verbatim via _emit. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Naked-asm byte passthrough: 3-way selector dispatch with NEG/SBB/AND bool-to-FourCC-mask idiom; absolute .data addresses made naked approach the only reliable path (same strategy as sibling _rosetta functions).
_emit byte passthrough — five CALL rel32s and a NEG/SBB/AND boolean- normalize sequence in the null/bool branch resist source-level C rewrite; verbatim 178-byte emit gives GREEN on first attempt. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Naked-asm with register mnemonics; all memory operands are ECX/EAX- relative disp8 — no relocations, so the 45-byte sequence reproduces byte-for-byte. MSVC hoists the first field's this-load (EDX=[ECX+4]) before PUSH ESI; subsequent fields follow arg-load/this-load/store order.
6-byte loop-alignment NOP (LEA EBX,[EBX+0]) before the strlen scan required _emit; pre-call null-term write while push args sit on stack also not emittable from source — naked asm produces GREEN first pass. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Naked-asm byte passthrough (sibling idiom) — reloc-heavy named-attribute dispatcher with __chkstk prologue, 5 REPE CMPSB literal chains, and ~14 linker-resolved absolute call targets. Byte-identical, 461/461. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Add a final "Announce the release on Discord" step to release.yml's
release job — a faithful port of the garlemald-server/garlemald-client
release announcers. After the tag + GitHub Release publish on a push to
master (a develop -> master release merge), it POSTs a Discord embed
("Meteor Decomp vX.Y.Z — A new Meteor Decomp release is available: …")
linked to the Release page.
- Uses the dedicated DISCORD_RELEASE_WEBHOOK_URL repo secret; the payload
is assembled with jq --arg so the tag can never break out of the shell
or the JSON.
- Non-fatal by design: an unset secret logs a ::warning:: and skips
(exit 0); a webhook failure is likewise non-fatal — the tag + Release
have already published. No allowed_mentions is needed because the
payload is an embed (no top-level content field), so it cannot ping.
- No event guard: release.yml's sole trigger is push to master, so every
reached run is a genuine release (unlike garlemald's binaries workflow,
which also has a workflow_dispatch leg to filter out).
Documents the step and the DISCORD_RELEASE_WEBHOOK_URL secret requirement
in docs/RELEASING.md.
Closes #10.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…aster (#1033) The push-to-master trigger silently never fires for a squash-merged develop -> master release PR: develop is saturated with [skip ci] commits (the reconcile bot), and a squash folds those commit messages into the squash commit body, so GitHub skips every workflow for that push. That is why the first release PR after the Discord step landed produced no tag, no GitHub Release, and no Discord announcement. Switch release.yml to fire on the PR-merge EVENT instead: - on: pull_request_target (types: [closed], branches: [master]) plus workflow_dispatch (manual fallback / recovery). pull_request_target is immune to [skip ci] and fires for any merge method (squash/merge/rebase). - Gate the job on merged == true && base.ref == 'master' (or dispatch), so a closed-without-merge PR never releases. - Read the bump label from the PR associated with the checked-out master HEAD (git rev-parse HEAD), not github.sha — under pull_request_target github.sha is the pre-merge base sha, not the merge commit. - Safety: still checks out ref: master only and runs no PR head code; pushes only a tag (default GITHUB_TOKEN suffices even on protected master). Quote level="patch"/"minor"/"major" to clear a pre-existing SC2209 in the step being edited. Docs: document the new trigger, the [skip ci]/squash rationale, and the manual workflow_dispatch path in docs/RELEASING.md; scrub the stale "push to master" trigger wording. Refs #10. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.