Skip to content

v0.3.0 — ARM64, a PE reader and breakpoint control

Latest

Choose a tag to compare

@glslang glslang released this 17 Oct 19:32
· 3 commits to main since this release
Immutable release. Only release title and notes can be modified.

crates.io · docs.rs

[dependencies]
dbgscope = "0.3.0"

This release lets a breakpoint callback read its hit and decide whether the target stops, decodes ARM64 instructions in full and walks ARM64 kernel pools and user heaps, adds a PE reader and bounded reads and symbol reloads, and corrects how the pool and heap walkers read current Windows builds.

Highlights

  • Breakpoint callbacks receive a typed BreakpointHit — the breakpoint's id and address, and an engine stopped at the hit — and return a BreakpointAction (Default, Go or Break), so a callback can let a hit go past instead of only watching it. A callback that panics answers Default rather than unwinding into dbgeng.dll.
  • ARM64 operands, registers, effects, conditions, privilege, control flow and function extents are decoded, and decode_instruction decodes bytes with no session at all. The kernel pool walker and the heap queries accept ARM64 targets; a WoW64 process is refused rather than half-walked.
  • The new pe module reads a loaded image's sections, imports, import address table and export names through a reader that tolerates holes, which is enough to name the calls of a driver with no symbols.
  • read_memory_bounded reads a page at a time against a deadline, reload_symbols_bounded puts a watchdog around a reload, and a failed command keeps the engine's own explanation in DbgEngError::CommandFailedWithOutput.
  • New session queries: debuggee_type, dump_files, session_processes, kernel_connection_options, virtual_region, integer_register, current_thread_teb and current_thread_data_offset. end_session reports whether a live kernel was left running.
  • Pool and heap walks read current builds correctly: big-pool allocations are named from nt!PoolBigPageTable, user heaps are rooted from ntdll's heap list, LFH bitmaps and the VS free tree are read as nt and ntdll write them, page-aligned VS user blocks are placed where the allocator puts them, and reserved address space no longer counts against a heap walk's coverage. A pool walk that reached the end is cached, taking one live tier from 2,665 s to 1,032 s.
  • Break-ins still owed after a KD attach, or after a breakpoint every processor hit, are drained before qd, so a detach no longer leaves the guest frozen.

Migration from 0.2

  • BreakpointCallback is Box<dyn Fn(&BreakpointHit<'_>) -> BreakpointAction>. Register it with set_breakpoint_callback and remove it with clear_breakpoint_callback; create_debug_event_context_callbacks, set_breakpoint_event_callbacks and the public DebugEventContextCallbacks are removed.
  • end_session returns TargetLeft rather than (). KernelHalted means the session ended and the guest is probably still stopped at a break.
  • A command that fails returns DbgEngError::CommandFailedWithOutput where it returned CommandFailed. Match both, or read the engine's line through DbgEngError::output().
  • Public enums gain variants and public structs gain fields, among them five DbgEngError variants, Operand::Undecoded, PoolState::Uncommitted, Instruction::privilege and reads. Update exhaustive matches and struct literals.
  • HeapRoot::index is a position in ntdll's heap list rather than the PEB's ProcessHeaps, and every pool and heap layout fingerprint moves. Re-resolve anything cached by fingerprint.

See the full changelog for detailed behavior and limitations.

Changes: v0.2.0...v0.3.0