Skip to content

feat: release-readiness hardening for v3.9.0#136

Merged
tkhquang merged 3 commits into
mainfrom
release-readiness-3.9.0
Jun 21, 2026
Merged

feat: release-readiness hardening for v3.9.0#136
tkhquang merged 3 commits into
mainfrom
release-readiness-3.9.0

Conversation

@tkhquang

@tkhquang tkhquang commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses the v3.9.0 release-readiness audit: closes the P0 blockers and the high-value hardening items so the toolkit can be tagged. Version bump is a MINOR because the change set adds public API.

  • Bumps project(VERSION) to 3.9.0 so the version header, ConfigVersion, and the release validate-version gate agree; widens the DMK_VERSION integer encoding.
  • Makes on_dll_attach noexcept and fails closed through unwind_early_attach_failure, closing a DllMain UB hole when an allocation throws during attach.
  • Adds the MinGW x64 fault-guard arm to both string-xref window scanners, matching the scanner sweep and closing a host-crash window on a supported toolchain.
  • Adds the guarded per-frame write family (seh_write / seh_write_bytes / seh_write_chain / seh_write_chain_bytes) with no protection flip, i-cache flush, or cache invalidation; write_bytes is now setup/patch-only with a gated per-call log.
  • Hardens RTTI self-heal (reject string temporaries, latch only on success, reset on all-fail, reject duplicate offsets), the config notify-walk bounds and register_int range check, the scanner incomplete-scan fail-closed signal, and input wheel-counter drain on re-bind.
  • Pins MinGW GCC 13.2.0 across the PR/coverage CI lanes to match release, drops the LogMessage zero-fill, moves async-logger internals behind detail, and refreshes README/AGENTS/docs.

Summary by CodeRabbit

  • New Features

    • Added guarded write primitives for efficient per-frame memory operations on hot paths.
    • Introduced pointer-chain write utilities mirroring existing read capabilities.
    • Enhanced fault detection and reporting during memory scanning operations.
    • Improved configuration validation with better input range handling.
  • Bug Fixes

    • Fixed file monitoring bounds checking to prevent buffer overruns.
    • Strengthened initialization exception safety under loader lock.
    • Enhanced scanner completeness tracking to prevent silent partial results.
  • Documentation

    • Clarified memory operation behavior and toolchain fallbacks.
    • Updated reentrancy and teardown contracts.
  • Chores

    • Bumped version to 3.9.0 with updated version encoding scheme.
    • Updated CMake minimum requirement to 3.28.

@tkhquang tkhquang self-assigned this Jun 21, 2026
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@tkhquang, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 26 minutes and 36 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 83f68453-17d6-4843-adb6-28274a56f2ca

📥 Commits

Reviewing files that changed from the base of the PR and between da5f6e3 and ceacee3.

📒 Files selected for processing (4)
  • .github/workflows/pr-check.yml
  • include/DetourModKit/bootstrap.hpp
  • src/memory.cpp
  • tests/test_memory.cpp
📝 Walkthrough

Walkthrough

DetourModKit v3.9.0 adds SEH-guarded write primitives (seh_write*/seh_write_chain*) with MinGW VEH/VirtualQuery fallback paths, a per-thread scan-incomplete flag that makes scanner cascade fail-closed on faulted regions, RTTI TypeIdentity retry-on-miss and solve_fingerprint duplicate-offset rejection, bootstrap noexcept refactor, config integer parsing hardening, bounds-checked FILE_NOTIFY_INFORMATION parsing, event-dispatcher reentrancy logging, and a CI MinGW toolchain pinning to Chocolatey 13.2.0.

Changes

DetourModKit v3.9.0

Layer / File(s) Summary
Version bump, CI toolchain pinning, and version macro encoding
CMakeLists.txt, include/DetourModKit/version.hpp.in, .github/workflows/pr-check.yml, tests/test_version.cpp, tests/test_platform.cpp
Project version bumped to 3.9.0; DMK_MAKE_VERSION encoding changed to major*1000000+minor*1000+patch; CI pins MinGW to Chocolatey 13.2.0 with a cache step and writes resolved toolchain versions to GITHUB_STEP_SUMMARY; version and platform test assertions updated.
SEH-guarded write API declarations
include/DetourModKit/memory.hpp, src/memory_internal.hpp, README.md, AGENTS.md, docs/misc/hot-path-memory.md
Declares seh_write_bytes, seh_write, seh_write_chain_bytes, seh_write_chain (span + initializer_list overloads); relabels write_bytes as setup/control-plane only; changes run_guarded_region contract to fail-closed (no longer runs fn unguarded) when handler unavailable; documentation extended for write-path selection and MinGW toolchain behavior.
MinGW VEH write implementation
src/memory.cpp
Adds virtualquery_validated_write mirroring the read path; introduces veh_write_bytes using veh_guarded_region or VirtualQuery fallback; strengthens VEH fault-claim conditions to require fault address inside the armed range; unifies guard record to VehAccessGuard; changes run_guarded_region to set completed=false rather than run unguarded; gates write_bytes debug logging on is_enabled(Debug).
Public seh_write_bytes and seh_write_chain_bytes + string xref guard migration
src/memory.cpp, src/string_xref.cpp
Implements public seh_write_bytes and seh_write_chain_bytes with MSVC __try/__except and MinGW veh_write_bytes paths; rewrites scan_window_narrow_guarded and scan_window_broad_guarded on _WIN64 to use Memory::detail::run_guarded_region, restoring pre-scan state on swallowed fault.
SEH write primitive tests
tests/test_memory.cpp, tests/test_memory_chain.cpp
Covers seh_write/seh_write_bytes typed round-trip, byte-span write, zero-byte no-op, null-source rejection, low-address rejection, PAGE_READONLY fault-closed, and PAGE_NOACCESS fault-closed; chain tests cover multi-level write, nested struct offsets, empty span, zero-byte, null source, implausible first link, and initializer_list equivalence.
Scanner incomplete-scan flag and cascade fail-closed
src/scanner_internal.hpp, src/scanner.cpp, src/scanner_cascade.cpp, tests/test_scanner.cpp, tests/test_string_xref.cpp
Adds scan_incomplete_flag() thread-local bool&; refactors scan_regions_filtered fault reporting into a lambda that sets the flag, logs, and emits diagnostics on early match and end of walk; extends count_pattern_hits_bounded with incomplete_out; makes try_prologue_shape return nullopt when count is incomplete; broadens guard test conditions to _MSC_VER || _WIN64.
RTTI TypeIdentity retry, constructor hardening, and solve_fingerprint duplicate rejection
include/DetourModKit/rtti.hpp, src/rtti.cpp, include/DetourModKit/rtti_dissect.hpp, src/rtti_dissect.cpp, tests/test_rtti_reverse.cpp, tests/test_rtti_dissect.cpp
Adds const char* constructor and deletes std::string&& constructor for TypeIdentity; changes vtable() to not latch m_resolved on failure so retry is possible; identify_pointee_type_or resets out to default on total failure; solve_fingerprint rejects duplicate nominal_offset as BadDescriptor; expanded hazard documentation for heal_landmark/heal_offset; new tests for late-bind retry, temporary rejection, out-reset, and duplicate-offset rejection.
Bootstrap noexcept, config hardening, config_watcher bounds checking, event dispatcher reentrancy logging, input intercept wheel drain
include/DetourModKit/bootstrap.hpp, src/bootstrap.cpp, src/config.cpp, src/config_watcher.cpp, include/DetourModKit/event_dispatcher.hpp, src/input_intercept.cpp, include/DetourModKit/async_logger.hpp, tests/test_config.cpp
on_dll_attach extracted to attach_core + noexcept wrapper with catch-all; CallbackConfigItem<int> parsing replaced with strtoll with range/consumption checks; Config::load callbacks wrapped in try/catch; FILE_NOTIFY_INFORMATION walk rewritten with cursor/end_ptr bounds checking; subscribe/unsubscribe call report_reentrant_rejection on reentrancy; install_wndproc drains s_wheel_count; LogMessage::buffer left uninitialized; config tests cover over/underflow, leading-zero decimal, and non-numeric inputs.
HookManager doc-only clarifications
include/DetourModKit/hook_manager.hpp
Expands two-phase teardown/quiesce contract notes for shutdown, remove_vmt_hook, remove_vmt_method, remove_vmt_from_object, remove_all_vmt_hooks, remove_hook, and remove_all_hooks, all stating that teardown must not be called from within with_*/try_with_* callbacks.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • tkhquang/DetourModKit#87: Adds the guarded read-chain primitives (seh_resolve_chain/seh_read_chain*) and their VEH/VirtualQuery MinGW machinery that this PR mirrors for write-chain variants.
  • tkhquang/DetourModKit#130: Introduces run_guarded_region and wires it into scan_region_guarded; this PR changes run_guarded_region's fail-closed contract and uses it in string_xref.cpp.
  • tkhquang/DetourModKit#131: Introduces the typed Diagnostics::scanner_faults event bus that this PR's report_faulted_regions lambda emits into via emit_safe.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main objective of this release-preparation PR: hardening improvements for v3.9.0.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/pr-check.yml:
- Line 35: The GitHub Actions in the pr-check.yml workflow are using tagged
versions (`@v4`) instead of commit SHAs, which creates security and
maintainability risks. You need to either pin each action to a specific commit
SHA (replace `@v4` with the full commit hash like `@abc1234def5678`) for all
affected actions including actions/cache and any others on lines 29, 35, 50, 61,
and 148, or add a Dependabot configuration to .github/dependabot.yml with
package-ecosystem set to github-actions to automatically manage these updates.
Choose one approach and apply it consistently across all GitHub Actions in the
workflow file.

In `@include/DetourModKit/bootstrap.hpp`:
- Around line 85-90: The public docblock for the on_dll_attach function is
missing the required API-discipline safety label. Add one of the three required
labels (Callback-safe, Setup/control-plane only, or Best-effort) to the
documentation comment above the function declaration to classify the call-site
safety according to the coding guidelines for public APIs.

In `@src/memory.cpp`:
- Around line 2132-2143: The seh_write_chain_bytes function contains two
unguarded std::memcpy calls (one for reading intermediate pointers and one for
the final write) that can cause ASan false positives, whereas the similar
seh_write_bytes function conditionally uses __movsb under __SANITIZE_ADDRESS__
guards to avoid this issue. Wrap both std::memcpy calls in seh_write_chain_bytes
with conditional compilation guards using `#if` defined(__SANITIZE_ADDRESS__),
routing to __movsb with unsigned char* casts when ASan is enabled and falling
back to std::memcpy otherwise, matching the exact pattern used in
seh_write_bytes.

In `@tests/test_memory.cpp`:
- Line 2624: The constant kSentinel uses the k-prefixed Google naming style
which the repository avoids. Rename kSentinel to SENTINEL to follow the
UPPER_SNAKE_CASE convention that the codebase requires for all constants. Update
all references to kSentinel throughout the test_memory.cpp file to use the new
SENTINEL name to maintain consistency with the repository's coding guidelines.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 95cb91bd-9e1d-4216-b5d7-f44f86e951ee

📥 Commits

Reviewing files that changed from the base of the PR and between 00fd66d and da5f6e3.

📒 Files selected for processing (34)
  • .github/workflows/pr-check.yml
  • AGENTS.md
  • CMakeLists.txt
  • README.md
  • docs/misc/hot-path-memory.md
  • include/DetourModKit/async_logger.hpp
  • include/DetourModKit/bootstrap.hpp
  • include/DetourModKit/event_dispatcher.hpp
  • include/DetourModKit/hook_manager.hpp
  • include/DetourModKit/memory.hpp
  • include/DetourModKit/rtti.hpp
  • include/DetourModKit/rtti_dissect.hpp
  • include/DetourModKit/version.hpp.in
  • src/bootstrap.cpp
  • src/config.cpp
  • src/config_watcher.cpp
  • src/input_intercept.cpp
  • src/memory.cpp
  • src/memory_internal.hpp
  • src/rtti.cpp
  • src/rtti_dissect.cpp
  • src/scanner.cpp
  • src/scanner_cascade.cpp
  • src/scanner_internal.hpp
  • src/string_xref.cpp
  • tests/test_config.cpp
  • tests/test_memory.cpp
  • tests/test_memory_chain.cpp
  • tests/test_platform.cpp
  • tests/test_rtti_dissect.cpp
  • tests/test_rtti_reverse.cpp
  • tests/test_scanner.cpp
  • tests/test_string_xref.cpp
  • tests/test_version.cpp

Comment thread .github/workflows/pr-check.yml
Comment thread include/DetourModKit/bootstrap.hpp
Comment thread src/memory.cpp
Comment thread tests/test_memory.cpp Outdated
@tkhquang tkhquang merged commit eedadd8 into main Jun 21, 2026
4 checks passed
@tkhquang tkhquang deleted the release-readiness-3.9.0 branch June 21, 2026 11:46
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.

1 participant