Skip to content

Enforce W^X for generated code and enable exploit mitigations - #26

Open
Belonit wants to merge 5 commits into
masterfrom
fix/antivirus-false-positives
Open

Enforce W^X for generated code and enable exploit mitigations#26
Belonit wants to merge 5 commits into
masterfrom
fix/antivirus-false-positives

Conversation

@Belonit

@Belonit Belonit commented Aug 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Avoid explicit RWX allocations: write generated code to read/write memory, then switch it to read/execute before use.
  • Flush the target process instruction cache after writing generated code and runtime code patches.
  • Keep loader code on a separate page from writable exchange data.
  • Enable ASLR (/DYNAMICBASE), DEP (/NXCOMPAT), and stack protection (/GS) for Syringe.exe without forcing DEP on the target game.

Motivation

Syringe's previous RWX allocations and disabled exploit mitigations resembled common malware behavior and contributed to antivirus false positives. These changes tighten memory permissions and harden the executable without changing its intended DLL-loading behavior.

Validation

  • Debug and Release Win32 builds succeed.
  • All 94 automated checks pass in both configurations.
  • The new Syringe.exe was tested in CnCNet Yuri's Revenge with Phobos v0.5-alpha1.
  • The resulting PE has DYNAMIC_BASE, NX_COMPAT, and a GS security cookie.
  • Syringe no longer allocates PAGE_EXECUTE_READWRITE memory or contains RWX PE sections.

Some heuristic detections may remain because process debugging, code patching, and DLL injection are core Syringe features.

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

Nightly build for this pull request:

This comment is automatic and is meant to allow guests to get latest nightly builds for this pull request without registering. It is updated on every successful build.

@Metadorius

Copy link
Copy Markdown
Member

if this works - you'll be a hero

@Belonit
Belonit marked this pull request as draft August 21, 2026 23:29
@Metadorius

Copy link
Copy Markdown
Member

@Belonit I mean that doesn't mean anything. at release of 1.0.2 it was the same as you show for your new exe. then 1-2 more, and then MS Defender started detecting it and it was game over. you should compare a clean build of something else that is close to 1.0.2, not already released for a while version

@Belonit

Belonit commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

@Belonit I mean that doesn't mean anything. at release of 1.0.2 it was the same as you show for your new exe. then 1-2 more, and then MS Defender started detecting it and it was game over. you should compare a clean build of something else that is close to 1.0.2, not already released for a while version

Yes, you are right, this is a report from local build 1.0.2:
https://www.virustotal.com/gui/file/f5c01c20e68e11bfcd1f3281c729133021e9035acbef15b16a7ecce13b970277
image

@ZivDero

ZivDero commented Aug 21, 2026

Copy link
Copy Markdown

Review findings:

  1. [P1] W^X is not enforced in the debuggee. /NXCOMPAT in Debugger.vcxproj hardens Syringe.exe, but the VirtualAllocEx allocation is inside the child process. Under the Windows client OptIn DEP policy, a legacy 32-bit target without NX_COMPAT can execute PAGE_READWRITE memory, leaving the generated-code buffer effectively RWX while it is writable. Wine similarly forces readable mappings executable for non-NX images. Please create the child with PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY and PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE (consider DEP_ATL_THUNK_ENABLE for compatibility), or narrow the W^X claim. References: Microsoft DEP policy, child-process mitigation API.

  2. [P2] The 0x1000 code/data split is not a native W^X boundary on Apple-Silicon Wine/CrossOver. Wine tracks 4 KiB guest pages but combines their permissions within a 16 KiB host page. The RX loader at offsets 0..0xfff and the RW exchange fields starting at +0x1000 therefore produce an actual RWX host mapping. Please put loader code and exchange data in separate VirtualAllocEx reservations; GetSystemInfo still reports the guest granularity. References: Wine permission union and mprotect application.

The Debug and Release checks are green, including all 94 tests; I did not find additional build-configuration issues.

@Belonit
Belonit marked this pull request as ready for review August 23, 2026 20:13
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.

3 participants