Skip to content

Full OS × arch interception parity: every combo loads, dispatches, and steps#175

Merged
sha0coder merged 11 commits intosha0coder:mainfrom
brandonros:parity10
Apr 12, 2026
Merged

Full OS × arch interception parity: every combo loads, dispatches, and steps#175
sha0coder merged 11 commits intosha0coder:mainfrom
brandonros:parity10

Conversation

@brandonros
Copy link
Copy Markdown
Contributor

This branch covers:

Unix x86_64 API interception (was missing)
Maps reorg to maps/{os}/{arch}/
macOS x86_64 + aarch64 stub dylibs
Waves 1-3: AArch64 routing, PE ARM64, ELF fixes, PIE rebasing
Linux stack layout fix (hello_linux_x64)
Windows ARM64 PE path unblocked (waiting on real DLLs)
The only remaining gap is maps/windows/aarch64/ needs real ARM64 DLLs (kernelbase.dll, kernel32.dll, ntdll.dll) — once you drop those in, hello_win_arm64 will un-ignore and pass. Both #160 and #173 are closeable.

brandonros and others added 9 commits April 11, 2026 16:19
…h, Linux ARM64 ELF loader

- PE loader: machine-aware dispatch using COFF Machine field (x86/x64/ARM64)
- Windows init: ARM64 sessions get PEB64/TEB64/LDR via is_64bits() instead of is_x64()
- macOS libsystem: arch-agnostic arg()/set_ret() helpers, implemented malloc/free/memcpy/
  memmove/memset/memcmp/strlen/strcmp/strcpy/strncpy/strcat/strchr/strrchr/strstr/strdup/
  sprintf/snprintf/read/open/close/mmap/munmap/mprotect + more
- macOS syscall_aarch64: implemented read/openat/mmap/munmap/mprotect/ioctl/brk/writev/
  lseek/fcntl/fstat/newfstatat/futex stubs
- Linux ARM64 ELF: real aarch64 libc.so.6 stub (cross-compiled), AArch64 relocation
  handling (R_AARCH64_GLOB_DAT/JUMP_SLOT), arch-aware stub path resolution
- ELF loader: unified load_elf64_dynamic_libs for both x86_64 and aarch64
- instruction_pointer: set_pc_aarch64 resolves symbols from both Mach-O and ELF maps
- PE shared: fixed export directory field offsets (address_of_names/ordinals)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
maps_linux       -> maps/linux/x86_64
maps_linux_aarch64 -> maps/linux/aarch64
maps_macos       -> maps/macos/aarch64
maps32           -> maps/windows/x86
maps64           -> maps/windows/x86_64
(new)            -> maps/macos/x86_64
(new)            -> maps/windows/aarch64

Updated all code references in loaders, tests, main.rs, maps.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tions

- Built x86_64 libSystem.B.dylib from shared source (maps/macos/libsystem_stub.c)
- Moved linux libc_stub.c to maps/linux/libc_stub.c (shared across arches)
- Added maps/windows/aarch64/.gitkeep for future use
- Stub .c files live at maps/{os}/ level, compiled binaries in maps/{os}/{arch}/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both macOS dylib stubs now built from maps/macos/libsystem_stub.c.
Verified all 220 tests pass with the rebuilt binary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ader parity

- Add Windows AArch64 branch to set_pc_aarch64() with emulate_winapi,
  skip_apicall, hook dispatch, and winapi64 gateway routing via LR
- Add aarch64_call64() method using AAPCS64 calling convention
- Make __libc_start_main arch-aware (AArch64 + x86_64)
- Make PE64 entry point setup arch-neutral (set_pc/pc instead of rip)
- Widen PEB system-dependent guards from is_x64() to is_64bits()
- Add WinApiAbi helper for Windows API arg/ret across x86_64 and AArch64
- Guard winapi64 gateway sanitize64() call for AArch64 safety
- Enhance Linux AArch64 syscalls: real brk allocation, uname struct write
- Un-ignore hello_mac_x64 and hello_win_arm64 tests (now passing)

222 tests pass, 0 failures, 7 ignored (was 220/9).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…2 PIE rebasing

- Fix ELF64 section permission mapping: skip non-SHF_ALLOC sections
  (.symtab/.strtab) that were overlapping .text with Permission::NONE
- Auto-detect maps_folder for PE32 (maps/windows/x86/) and PE64
  (maps/windows/x86_64/) when not explicitly set
- Fix ELF32 dynamic/PIE loader: rebase segments from vaddr 0 to
  ELF32_DYN_BASE, fix p_flags bit mapping (PF_R/PF_X were swapped),
  write-then-tighten section permissions
- Un-ignore hello_linux_arm64, hello_win_x86, hello_win_x64,
  hello_linux_x86 tests (all now passing)
- Update hello_linux_x64 ignore comment to reflect actual root cause

226 tests pass, 0 failures, 3 ignored (2 slow SSDT + 1 linux x64 stack setup).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…inates step()

- Add write_linux_stack_layout() to write argc/argv/envp/auxv to the stack
  before _start runs, matching what the Linux kernel provides (fixes the
  parity gap where _start read garbage and jumped to a stack address)
- Call it from load_elf64() for all ELF64 binaries (both static and dynamic)
- Move process_terminated into stop() so step() halts after exit()/abort()
  instead of continuing into post-_start garbage
- Un-ignore hello_linux_x64 test (last remaining parity gap)
- Update elf64lin_static_helloworld pos count (correct argc changes path)

227 passed, 0 failed, 2 ignored (SSDT slow tests only)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove the early return that blocked ARM64 PE loading; now calls
  load_pe64() with proper aarch64 init, maps folder, and DLL args
- Add maps/windows/aarch64/ auto-detection to maps_folder setup
- Add is_maps detection for windows/aarch64/ in load_pe64()
- Replace silent panic in init_win32_mem64() DLL loading with assert
  that names the missing file and maps_folder
- Update hello_win_arm64 test to assert entry point and step;
  ignored until real ARM64 DLLs are added to maps/windows/aarch64/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@brandonros brandonros marked this pull request as ready for review April 12, 2026 00:48
brandonros and others added 2 commits April 11, 2026 20:56
- ntdll LdrLoadDll (32-bit and 64-bit): replace broken hardcoded
  maps32/user32.bin paths with proper load_library() calls through
  the maps_folder config (the .bin files never existed)
- Update stale comments referencing maps32/maps64 to maps/windows/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- pe.rs: remove legacy maps32/maps64 is_maps fallbacks
- helpers.rs: rename maps64_folder() -> win64_maps_folder()
- maps.rs: update folder pattern matching for download helper
- READMEs (mwemu, libmwemu, pymwemu): update all paths
- pymwemu scripts: update all load_maps() paths
- trace_diff.py: update comment

Only remaining maps32/maps64 strings are the GitHub release
download URLs (the actual zip files are named that way).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sha0coder sha0coder merged commit 63ed84f into sha0coder:main Apr 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants