Files
whitemagic/openspec/changes/whitemagic-foundation/specs/managed-assembler/spec.md
T
kbeandClaude Opus 4.8 4405af15fd Add whitemagic-foundation OpenSpec design; isolate reference libs
Design-only foundation for WhiteMagic, a .NET 8 x64 library unifying the
four studied process-manipulation libs. Adds proposal, design (7 decisions),
7 capability specs, and TDD task breakdown; all validate strict.

Move Blackmagic, Blackmagic-old, GreyMagic, MemorySharp, fasm into
reference/ (gitignored) — studied, not built here; each has its own
upstream repo and nested .git. Rewrite plan doc paths to reference/.

Corrects two factual defects found in review:
- current BlackMagic has no D3D EndScene hook; MainThreadPump is net-new
  built on DetourManager, not a port
- no BlackMagic.slnx exists; task 1.3 creates a fresh solution

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 16:50:03 +02:00

2.4 KiB

ADDED Requirements

Requirement: IAssembler abstraction with no native dependency

WhiteMagic SHALL define an IAssembler seam that produces machine code, with a default backend that has no native or third-party dependency. FASM MUST NOT be referenced by the default configuration.

Scenario: default backend is dependency-free

  • WHEN WhiteMagic is built in its default configuration
  • THEN no reference to FASM or ManagedFasm MUST be present in the output

Scenario: backend is replaceable

  • WHEN an alternate IAssembler implementation is supplied
  • THEN execution and injection MUST use it without other code changes

Requirement: Hand-emitted calling-convention stubs

The default StubAssembler SHALL emit call trampolines for the cdecl, stdcall, thiscall, and fastcall conventions — pushing/placing arguments, calling the target, cleaning the stack per convention, and returning — for both x86 and x64 targets.

Scenario: cdecl stub encoding

  • WHEN a cdecl call stub for a function with N 4-byte arguments is emitted (x86)
  • THEN the bytes MUST push the arguments in reverse order, call the target, add esp, N*4, and ret

Scenario: stdcall omits caller cleanup

  • WHEN a stdcall stub is emitted
  • THEN it MUST NOT emit a caller-side stack cleanup (the callee cleans)

Scenario: x64 uses register argument order

  • WHEN an x64 call stub is emitted
  • THEN the first integer arguments MUST be placed in the platform argument registers before the call

Requirement: Byte emitter primitives

StubAssembler SHALL provide little-endian emit primitives (EmitU8, EmitU32, EmitU64) used to hand-assemble stubs deterministically.

Scenario: little-endian 32-bit emit

  • WHEN EmitU32(0x11223344) is called
  • THEN the appended bytes MUST be [0x44, 0x33, 0x22, 0x11]

Requirement: Optional Iced backend for arbitrary assembly

WhiteMagic SHALL provide an optional IcedAssembler backend that assembles arbitrary x86/x64 mnemonic text to machine code for callers who require runtime text assembly.

Scenario: arbitrary mnemonics assembled

  • WHEN the Iced backend assembles "push 0\nadd esp, 4\nret" at a given origin
  • THEN it MUST return the corresponding machine code bytes

Scenario: origin-relative encoding

  • WHEN assembly containing a relative jump is assembled at a specified origin address
  • THEN the encoded relative offsets MUST be correct for that origin