Commit Graph
6 Commits
Author SHA1 Message Date
kbeandClaude Opus 4.8 7c5e72e0e0 Harden memory layer: fix char sizing, ref structs, count guards, ReadString advance
Second-review fixes, each covered by a regression test in MemoryHardeningTests:

- MarshalCache: special-case char (Size=2; Marshal.SizeOf reports 1/ANSI but the
  blittable path reads a 2-byte UTF-16 unit). TypeRequiresMarshal now also trips on
  RuntimeHelpers.IsReferenceOrContainsReferences<T>() so reference-carrying structs
  route to the marshal path instead of throwing in MemoryMarshal.Read. Document that
  the MarshalAs scan is top-level only.
- MemoryBase.Read<T>(count): reject negative count (ArgumentOutOfRangeException) and
  guard elementSize*count overflow. Same overflow guard on Write<T>(values).
- MemoryBase.ReadString: advance by bytes actually read, not the requested amount, so
  a partial read no longer skips the unread tail of the window.
- ExternalReader: default to a minimal access set (not AllAccess, which over-requests
  and fails on protected processes); wrap Process.MainModule in try/catch so a
  bitness-mismatched or protected target yields ImageBase=Zero instead of throwing.
- NativeMethods: WaitForSingleObject and CreateRemoteThread's threadId are DWORD (uint),
  not int — the signatures no longer sign-flip.

Deferred: hoisting the identical ExternalReader/InProcessReader byte-IO into MemoryBase
(cosmetic; skipped to avoid colliding with concurrent Phase 3 edits).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:47:24 +02:00
kbe 68255f907c fix: IndexOfPattern alignment for multi-byte encodings
Stride the scan by pattern.Length (1 for ASCII/UTF-8, 2 for UTF-16,
4 for UTF-32) to avoid matching a misaligned null-terminator pattern
mid-character.
2026-07-21 19:34:01 +02:00
kbe 8374650aac fix 7 correctness and cleanup issues
Blocking fixes:
1. Read<T> now returns default(T) on failed/partial read instead of crash
   (applies to single Read<T>, array Read<T>, and ReadBytes)
2. InProcessReader uses ReadProcessMemory via handle instead of unsafe
   Buffer.MemoryCopy — fails soft on bad address instead of AV'ing
3. GetRelative now returns absolute - ImageBase (inverse of GetAbsolute).
   Fix round-trip test to validate at arbitrary offsets, not just ImageBase
4. ReadString reads in 64-byte chunks with encoding-aware null-terminator
   pattern matching (handles UTF-16's 2-byte null, UTF-32's 4-byte null)

Cleanup:
5. InProcessReader validates handle on open and uses RPM through it
   (handle is no longer unused)
6. Array marshal read: pin raw buffer once, PtrToStructure at offset
7. StructureToByteArray(Span) delegates to byte[] overload, no duplicate

New tests: 4 invalid-address grace tests (returns default/empty/false).
All 57 passing.
2026-07-21 19:24:18 +02:00
kbe 8219ac95a6 task 2.7-2.8: addressing helpers with tests
Add GetAbsolute/GetRelative with nint-based arithmetic (bitness-agnostic).
Add 6 tests: absolute resolution, relative computation, base-round-trip,
isRelative flag on Read/Write/ReadBytes.
Fix MemoryBase.cs: restore for-loop body damaged by prior edit, clean up
StructureToByteArray overloads.

All passing (total: 44).
2026-07-21 17:08:08 +02:00
kbe b2a5090533 task 2.5-2.6: string Read/Write with encoding tests
Add 8 tests for string IO: ASCII/UTF8/Unicode round-trip, null-terminator
stop, max-length truncation, auto-append of null terminator, empty string.
Fix ReadString null-terminator detection for multi-byte encodings (UTF-16):
decode string first, then find \0 in characters not bytes.

All passing (total: 38).
2026-07-21 17:06:34 +02:00
kbe 6b34e0fab8 task 2.3-2.4: implement MemoryBase + ExternalReader with tests
Add abstract MemoryBase base class with typed Read<T>/Write<T>, array
IO, string IO, and relative/absolute addressing. Uses MarshalCache<T>
to branch between blittable (MemoryMarshal) and marshal-required paths.

Add ExternalReader (out-of-process via ReadProcessMemory/WriteProcessMemory)
with SafeMemoryHandle lifecycle management.

11 new tests: ImageBase, Read/Write of int/byte/long/struct, byte array,
int array, struct array, invalid address, dispose, double-dispose.
All passing (total: 30).
2026-07-21 17:05:29 +02:00