Skip to content

Fix cross-platform injection and launcher compatibility - #110

Open
mohui666 wants to merge 4 commits into
NeighTools:masterfrom
mohui666:fix/open-issues-compatibility
Open

Fix cross-platform injection and launcher compatibility#110
mohui666 wants to merge 4 commits into
NeighTools:masterfrom
mohui666:fix/open-issues-compatibility

Conversation

@mohui666

Copy link
Copy Markdown

Summary

This consolidates the reproducible cross-platform compatibility fixes from the current issue backlog.

  • scope Unix stdout/fclose hooks to UnityPlayer so inherited LD_PRELOAD no longer breaks shell command substitution or file redirection
  • preserve empty target assemblies for debug-only mode and allow dnSpy/debug hooks without a managed entrypoint
  • resolve Unix executable, target, and Mono search paths relative to run.sh
  • isolate DYLD_INSERT_LIBRARIES from the Apple Silicon arch helper
  • use guarded dyld interposition for modern chained-fixup Mach-O images while keeping unsafe slot guessing fail-closed
  • preserve pre-existing Windows GetProcAddress IAT hooks and harden PE/CLI/path parsing
  • support restart-marker opt-out, localhost debugger normalization, and the documented Windows proxy alternatives

Fixes #88.
Addresses #24, #34, #47, #67, #73, #84, #94, #98, #102, #107, and #108.

Safety and compatibility

The macOS chained-fixups path no longer maps import ordinals to guessed GOT indices. dlsym, boot.config access, and stdout protection use dyld interposition instead; stdio interception checks that the direct caller is UnityPlayer, so inherited injection does not affect launchers or shells.

Missing target assemblies now skip only managed entrypoint execution. They no longer disable independent debugger, boot.config, and search-path functionality.

Verification

  • Windows regression tests
  • Windows x86 and x64 Release builds
  • Linux x64 Release build
  • Linux process-level LD_PRELOAD, shell redirection, UnityPlayer dup2, path, and restart-marker regressions
  • Unix shell syntax checks and strict C fixture compilation
  • git diff --check

CI additionally runs the real macOS dyld interposition smoke test and the normal Linux x86 build in its multilib runner.

@ManlyMarco
ManlyMarco requested a lite review from Copilot August 17, 2026 07:53

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ManlyMarco

ManlyMarco commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Does this PR obsolete #109?

Looks like the mac build is failing, can you look into it?

@mohui666

Copy link
Copy Markdown
Author

这个 PR 是否会使 #109 过时?

看起来 Mac 构建失败了,你能调查一下吗?

#110 fully supersedes #109, so #109 can be closed once #110 is merged.

The macOS failure is caused by mach-o/dyld-interposing.h not being part of the Xcode SDK. I’ll inline the DYLD_INTERPOSE macro in src/nix/entrypoint.c and let CI catch any further macOS-specific issues.

<mach-o/dyld-interposing.h> is part of the dyld source tree but is not
shipped in the Xcode SDK, so the include failed on CI runners. Vendor the
stable macro definition instead; the generated __DATA,__interpose tuples
are identical.
-lUnityPlayer only resolves lib-prefixed library names, while the caller
check requires the image basename to start with UnityPlayer. Link the
dylib by explicit path so its @rpath install_name is used instead.
load_mono_funcs/ load_il2cpp_funcs probe many optional symbols, leaving
the last failed probe in dlerror. Callers using the textbook
dlerror()-after-dlsym() pattern then see a phantom error even though
their own lookup succeeded. Drain the error state when the caller's
lookup succeeded; surfaced by the macOS interposition smoke test.
@mohui666

Copy link
Copy Markdown
Author

这个 PR 是否会使 #109 过时?

看起来 Mac 构建失败了,你能调查一下吗?

The macOS build failure is fixed. CI is now green on all three platforms (verified on the fork's identical workflow: https://github.com/mohui666/UnityDoorstop/actions/runs/32021379965).

Root cause and fixes, three commits:

  • 55b753a<mach-o/dyld-interposing.h> ships with the dyld source tree, not the Xcode SDK, so the include could never resolve on CI runners. DYLD_INTERPOSE is now defined locally in src/nix/entrypoint.c; the emitted __DATA,__interpose tuples are identical.
  • 9e93c56 — the smoke test linked with -lUnityPlayer, which only resolves lib-prefixed library names. Renaming the fixture dylib was not an option because the caller check requires the image basename to start with UnityPlayer, so the test now links the dylib by explicit path.
  • 3c397a4 — the first redirect through dlsym_hook runs load_mono_funcs, whose ~30 optional symbol probes clobber dlerror; callers using the textbook dlerror()-after-dlsym() pattern then see a phantom error. The hook now drains the probe residue when the caller's own lookup succeeded.

With these in place, the new run-macos-interpose-smoke.sh passes on a real runner: dlsym redirection to init_mono, the boot.config fopen override, and the dup2/fclose stdout protection are all exercised end to end.

Note: the workflow run on this PR shows action_required — a maintainer needs to approve CI for the fork PR. The workflow is identical to the one that passed above.

@mohui666

Copy link
Copy Markdown
Author

@copilot review

Copilot AI 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.

Pull request overview

Copilot reviewed 31 out of 31 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

tests/windows/config-util-regressions.c:3

  • Duplicate include of ../../src/bootstrap.h. While the header is include-guarded, this is unnecessary and can hide accidental copy/paste errors in test sources.
#include "../../src/bootstrap.h"
#include "../../src/bootstrap.h"

tests/windows/run-regressions.ps1:6

  • run-regressions.ps1 unconditionally resolves gcc.exe and throws if it isn't present. Since the script passes gcc-style flags, consider allowing override via an env var (e.g. CC) pointing to a gcc/clang-compatible compiler, and emit a clearer error when neither gcc.exe nor CC are available.
$compiler = (Get-Command gcc.exe -ErrorAction Stop).Source

Comment on lines +18 to 20
- name: Run Windows regression tests
run: ./tests/windows/run-regressions.ps1
- name: Build Release
@arrowmaster

Copy link
Copy Markdown
Contributor

I don't believe whichever LLM created this PR has enough context to make a meaningful contribution. I'm stronger with the shell script and build pipeline so I will focus there for now.

At 11c790d#diff-672ab20553b2eb1be64f57ff9b63eb32799c1ecfd10707b184f9da8b2ca331caL67, the comment pointing to #88 is removed and the PR description says that #88 is fixed, however the code block immediately after that comment is left intact. That code block only exists to work around #88 and should be removed and tested if it is truely fixed.

At 11c790d#diff-672ab20553b2eb1be64f57ff9b63eb32799c1ecfd10707b184f9da8b2ca331caR382 the DYLD_INSERT_LIBRARIES envvar is unset which is the literal fix to #107, it does not address the concerns over DYLD_LIBRARY_PATH also needing to be handled. It also does not address the problems from the loaded binaries not fully supporting all platforms as present when used with BepInEx. The script likely needs to have a way to be configured for exactly which architectures the game and modding framework support so that it can be configured per game. I have been brainstorming on this but have not made any changes yet as I dont have a mac to test the changes on.

There are also many unexplained changes to run.sh that I would like to know why they are being suggested. I believe they are related to #84 which is not a valid issue needing to be fixed.

The added unit tests are being run from standalone scripts calling compilers directly. The project uses xmake and any tests should be incorporated into the xmake configuration for consistent execution.

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.

Doorstop breaks output redirection in sh

4 participants