Giter Site home page Giter Site logo

neightools / unitydoorstop Goto Github PK

View Code? Open in Web Editor NEW
423.0 11.0 63.0 520 KB

Doorstop -- run C# before Unity does!

License: GNU Lesser General Public License v2.1

C 84.28% PowerShell 1.19% Shell 11.08% Batchfile 0.06% Lua 3.39%
unity mono in-memory bootstrapper

unitydoorstop's Introduction

Unity Doorstop

GitHub Workflow Status nightly.link artifacts


Doorstop is a tool to execute managed .NET assemblies inside Unity as early as possible.

This is a total rewrite of UnityDoorstop 3. See list of breaking changes for more information.

Features

  • Runs first: Doorstop runs its code before Unity can do so
  • Configurable: An elementary configuration file allows you to specify your assembly to execute
  • Multiplatform: Supports Windows, Linux, macOS
  • Debugger support: Allows to debug managed assemblies in Visual Studio, Rider or dnSpy without modifications to Mono

Unity runtime support

Doorstop supports executing .NET assemblies in both Unity Mono and Il2Cpp runtimes. Depending on the runtime the game uses, Doorstop tries to run your assembly as follows:

  • On Unity Mono, your assembly is executed in the same runtime. As a result
    • You don't need to include your custom Common Language Runtime (CLR); the one bundled with the game is used
    • Your assembly is run alongside other Unity code
    • You can access all Unity API directly
  • On Il2Cpp, your assembly is executed in CoreCLR runtime because Il2Cpp cannot run managed assemblies. As a result:
    • You need to include .NET 6 or newer CoreCLR runtime with your managed assembly
    • Your assembly is run in a runtime that is isolated from Il2Cpp
    • You can access Il2Cpp runtime by interacting with its native il2cpp_ API

Building

Doorstop uses xmake to build the project. To build, run build.bat, build.ps1 or build.sh.

Available build options:

  • -with_logging: build with logging enabled
  • -arch: the architectures to build for, separated by commas (e.g. -arch x86,x64)
  • -debug: build in debug mode (currently only for *nix)

Note: Initial build times are usually slower because the build script automatically downloads and installs xmake.
On Unix, xmake is built directly from the source code.

Minimal injection example

To have Doorstop inject your code, create Entrypoint class into Doorstop namespace. Define a public static Start method in it:

using System.IO;

namespace Doorstop;

class Entrypoint
{
  public static void Start()
  {
      File.WriteAllText("doorstop_hello.log", "Hello from Unity!");
  }
}

You can then define any code you want in Start.

NOTE: On UnityMono, Doorstop bootstraps your assembly with a minimal number of assemblies and minimal configuration. This early execution allows for some interesting tricks, like redirecting the loading of some game assemblies. Bear also in mind that some of the Unity runtime is not initialized at such an early stage, limiting the code you can execute. You might need to appropriately pause the execution of your code until the moment you want to modify the game.

Doorstop environment variables

Doorstop sets some environment variables useful for code execution:

Environment variable Description
DOORSTOP_INITIALIZED Always set to TRUE. Use to determine if your code is run via Doorstop.
DOORSTOP_INVOKE_DLL_PATH Path to the assembly executed by Doorstop relative to the current working directory.
DOORSTOP_PROCESS_PATH Path to the application executable where the injected assembly is run.
DOORSTOP_MANAGED_FOLDER_DIR UnityMono: Path to the game's Managed folder. Il2Cpp: Path to CoreCLR's base class library folder.
DOORSTOP_DLL_SEARCH_DIRS Paths where the runtime searchs assemblies from by default, separated by OS-specific separator (; on windows and : on *nix).
DOORSTOP_MONO_LIB_PATH Only on UnityMono: Full path to the mono runtime library.

Debugging

Doorstop 4 supports debugging the assemblies in the runtime.

Debugging in UnityMono

To enable debugging, set debug_enabled to true and optionally change the debug server address via debug_address (see configuration options).
After launching the game, you may connect to the debugger using the server address (default is 127.0.0.1:10000).
By default, the game won't wait for the debugger to connect; you may change the behaviour with the debug_suspend option.

If you use dnSpy, you can use the Debug > Start Debugging > Debug engine > Unity option, automatically setting the correct debugging configuration.
Doorstop detects dnSpy and automatically enables debugging without any extra configuration.

Debugging in Il2Cpp

Debugging is automatically enabled in CoreCLR.

To start debugging, compile your DLL in debug mode (with embedded or portable symbols) and start the game with the debugger of your choice.
Alternatively, attach a debugger to the game once it is running. All standard CoreCLR debuggers should detect the CoreCLR runtime in the game.

Moreover, hot reloading is supported for Visual Studio, Rider and other debuggers with .NET 6 hot reloading feature enabled.

Note that you can only debug managed code! Because the game code is unmanaged (i.e. Il2Cpp), you cannot directly debug the actual game code. Consider using native debuggers like GDB and visual debugging tools like IDA or Ghidra to debug actual game code.

Doorstop configuration

Doorstop is highly configurable based on your needs and the environment you want to use. There are two ways to configure Doorstop: via config and CLI arguments.

Via configuration file

Refer to doorstop_config.ini (Windows) or run.sh for all available configuration options.

CLI arguments

The following CLI arguments are available on both *nix, and Windows builds:

All Doorstop arguments start with --doorstop- and always contain an argument. The arguments can be of the following type:

  • bool = true or false
  • string = any sequence of characters and numbers. Wrap into "s if the string contains spaces
Argument Description
--doorstop-enabled bool Enable or disable Doorstop.
--doorstop-redirect-output-log bool Only on Windows: If true Unity's output log is redirected to <current folder>\output_log.txt
--doorstop-target-assembly string Path to the assembly to load and execute.
--doorstop-boot-config-override string Overrides the boot.config file path.
--doorstop-mono-dll-search-path-override string Overrides default Mono DLL search path
--doorstop-mono-debug-enabled bool If true, Mono debugger server will be enabled
--doorstop-mono-debug-suspend bool Whether to suspend the game execution until the debugger is attached.
--doorstop-mono-debug-address string The address to use for the Mono debugger server.
--doorstop-clr-corlib-dir string Path to coreclr library that contains the CoreCLR runtime
--doorstop-clr-runtime-coreclr-path string Path to the directory containing the managed core libraries for CoreCLR (mscorlib, System, etc.)

License

Doorstop 4 is licensed under LGPLv2.1. You can view the entire license here.
You can still access the source code to the original UnityDoorstop 3 source (licensed under CC0) from the legacy branch.

unitydoorstop's People

Contributors

aldelaro5 avatar bbepis avatar cptmoore avatar diehy avatar ghorsington avatar js6pak avatar maludwig avatar manlymarco avatar marshmello0 avatar mo10 avatar windows10ce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

unitydoorstop's Issues

Doorstop 4 debugger does not work on Bug Fables, but it works after upgrading Mono to MonoBleedingEdge

This one is half a bug and half a question because I have a good suspicion of what is happening, but I would still like to have more clarifications if that is the case. Basically, I tried to debug the game assemblies without changing any runtime files using Doorstop 4 and the best I got was the game would invoke the crash handler as soon as I try to connect and the connection closes. I have not been able to maintain a connection until I used Unity's files to upgrade the runtime of the game to the newer one this version of Unity ships with which allowed me to debug seamlessly.

Bug Fables (steamdb: https://steamdb.info/app/1082710/ ) ships with Unity 2018.4.12f1 which means it should support the debugging feature the new Doorstop 4 advertise as the readme says it should work past Unity 2017. However, this game has an interesting quirk: it does not actually uses the new Mono (called MonoBleedingEdge) because the game was originally developed for Unity 5.5.4 which only offered the older .net 3.5 compatible Mono 2.x. The only reason the engine was upgraded was to add support for consoles, but due to the fear of anything breaking, Moonsprout Games decided to not upgrade to the new runtime despite the old one being deprecated in that version.

This has proven to be very difficult for me to deal with because after a bunch of tests and research, I found that the only way for me to debug the game assemblies while preserving the runtime is to either use a Windows vm (I primarily use Linux) to generate full pdb files (not protable ones) from recompiled sources JUST to convert them to mdb or to use the Unity's original tooling. The later in particular have not been working as well as simply using the Unity files to upgrade the game to MonoBleedingEdge which is not only more stable, but also more compatible. FYI, the reason I use recompiled sources over dnSpyEx is due to it being very inefficient to decompile large functions which this game has.

The reason I am bringing this up is because I am both reporting it as a bug and also wants clarifications on the matter. Does Doorstop 4 supports the older Mono Unity shipped with despite the fact the game is a version above 2017? If the answer is no, I might as well ask in general: am I better off to upgrade the runtime even if it risks altering the behavior of the game?

Doorstop still doesnt work on first launch

version: v4.0.0 release
platform: Windows
game: BattleTech
distribution: Steam

Issue;
Doorstop uses ENV variables to keep track if it already ran, but dynamically set ENV variables are copied by steam during a restart of the games process.

Steps to reproduce:

  • make sure steam is not running
  • launch BATTLETECH directly via BattleTech.exe (have steam not running)
  • steam code detects that it needs to restart, that happens apparently after doorstop already ran
  • the game restarts with env variables set from the previous run, that includes env variables set dynamically by doorstop
  • thus doorstop thinks it doesnt need to run anymore

Workarounds not working:

  • ignore_disable_switch does not work, because the ENV variable DOORSTOP_INITIALIZED is set too, and that leads to skipping of calling the entrypoint
  • using a steam_appid.txt file so steam does not restart the game, however steamworks is broken and the game does not work properly (NRE etc..)
  • Always use the steam launcher: There are wrappers / launchers that ignore that and run the exe directly, and users who run the exe directly too.

Fix ideas?

  • Clear all dynamically set doorstop env variables if doorstop detects that it is in a new unmodified process, leading to doorstop to run again.

Reference for RogueTech Discord: #rogueticket-7596

Logs when using the ignore_disable_switch workaround:
log before restart
log after restart

UnityDoorstop can't work!

I find that UnityDoorstop can't work in sometime.
But I don't know why.
(This problem maybe cause as some optimization

My friend also has this problem.

I test the Example "Doorstop.dll". It's can't work too.
So I consider that it is the problem of UnityDoorstop.

Missing proxy.c and dllproxy.asm on master

Hi, I'm just sending this issue because these two files seem to be missing in the latest version of master, I had to revert to older versions to be able to build the library

UnityDoorstop 4.0.0-rc.7 not working on mac

Hello,

I'm trying to get UnityDoorstop 4 working on MacOS
Mac version: macOS Catalina 10.15.5
Zip: doorstop_macos_release_4.0.0-rc.7.zip
executable_name="Game.app"
target_assembly="Doorstop.dll"

Tried the entrypoint example to write file on .NET 5 with .netstandard 2.1 & .NET 6.
Works on Windows 11.

Error real mac:
dyld: could not load inserted library 'libdoorstop.dylib' because image not found
Error vm mac:
dyld: could not load inserted library ' ' because image not found

Result of echo "${doorstop_name}": libdoorstop.dylib

I'm not experienced with .sh files the only thing I was able to find is that the game is able to start by changing
export DYLD_INSERT_LIBRARIES="${doorstop_name}:${DYLD_INSERT_LIBRARIES}"
to:
export DYLD_INSERT_LIBRARIES="${doorstop_name}"

But it won't trigger the entrypoint or Mac can't write files with that script for some reason?

Please add that Doorstop.dll must be netstandard2.0 and not net7.0 in the documentation

Hi, I didn't test with all dotnet versions, but when I compiled my Doorstop.dll (with my default net7.0) it crashes with the log below (pasting it here for future google searches), I tested multiple games.
After a few hours of trying, it occurred to me to try with netstandard2.0 and then it worked. So please add some indication to this in the installation instructions. Thanks.

0x00007FFA0BAF4ED9 (KERNELBASE) RaiseException
0x00007FF9A0D26025 (mono-2.0-bdwgc) mono_dl_open
  ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF9A0D14D41)
0x00007FF9A0D14D41 (mono-2.0-bdwgc) (function-name not available)
0x00007FF9A0D52564 (mono-2.0-bdwgc) mono_class_num_properties
0x00007FF9A0D6078E (mono-2.0-bdwgc) mono_method_desc_search_in_image
0x0000000180003A2A (WINHTTP) WinHttpWriteProxySettings
0x00000001800037DE (WINHTTP) WinHttpWriteProxySettings
0x00007FF99EFFE4DF (UnityPlayer) UnityMain
0x00007FF99F006B3E (UnityPlayer) UnityMain
  ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF99EC716FA)
0x00007FF99EC716FA (UnityPlayer) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF99EC75AAB)
0x00007FF99EC75AAB (UnityPlayer) (function-name not available)
0x00007FF99EC7783B (UnityPlayer) UnityMain
  ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FF76D4311F2)
0x00007FF76D4311F2 (hollow_knight) (function-name not available)
0x00007FFA0CAF7034 (kernel32) BaseThreadInitThunk
0x00007FFA0E082651 (ntdll) RtlUserThreadStart

[question] Using self-compiled v4 Doorstop

Hey all, apologies for the noob question.

I'm trying to inject some basic code into the Unity game SkaterXL.

When I build the Doorstop project, I get build/windows/x86/release/doorstop.dll file. I renamed this file to winhttp.dll and copied it into the same directory as the game's executable, along with a doorstop_config.ini that looks like so:

# General options for Unity Doorstop
[General]
# Enable Doorstop?
enabled=true
# Path to the assembly to load and execute
# NOTE: The entrypoint must be of format `static void Doorstop.Entrypoint.Start()`
target_assembly=TestMod1.dll
# If true, Unity's output log is redirected to <current folder>\output_log.txt
redirect_output_log=false

TestMod1.dll is a compiled .NET 4.0 Project that contains the following code:

using System.IO;

namespace Doorstop
{
    class Entrypoint
    {
        public static void Start()
        {
            File.WriteAllText("doorstop_hello.log", "Hello from Unity!");
        }
    }
}

However, when I run SkaterXL.exe, I never get an outputted doorstop_hello.log file.

Is there anything apparent that's wrong about my setup here? I'm not positive where I'm going wrong. Any help would be appreciated. Thanks!

Doorstop not working on first Steam Launch.

Hi, i'm still facing the issue #5 with Raft.

When opening the game through steam the first time, it does not load at all, i think it might be related, could we have a setting to toggle the double injection ? my code anyway checks if its already loaded.

--doorstop-mono-debug-suspend true

Hi, I'm starting by game process with the additional command line args:
--doorstop-mono-debug-enabled true --doorstop-mono-debug-address "0.0.0.0:55555" --doorstop-mono-debug-suspend true

All works as expected, I'm able to connect to the port 55555 from dnSpy and the process is suspended, the only loaded module is mscorlib.dll. My question is, how do I exist the suspend state on UnityDoorstop from dnSpy ? For the debugger the process is already in a running state.. so even if I pause and start it will continue to be suspended.

Error message unreadable (Error invoking code)

I'm having problems debbuging an error message.

Info:
Game: Little witch in the woods
OS: Win 10
Visual Studio 2019 (used to build the entrypoint [release mode])

Steps to reproduce:

Using the Example entrypoint class in the README.
Placed winhttp.dll and .ini files in the game's root directory
Placed entrypoint in LWITW_Mods/net5.0/LWITW_ModLoader.dll
Changed ini file to reflect the entrypoint location.
Run the game and get this error:

(changed private information to ...)

Assembly dir: ...\Little Witch in the Woods\LWIW_Data\Managed
Opening assembly: ...\Little Witch in the Woods\LWITW_Mods\net5.0\LWITW_ModLoader.dll
Opened Assembly DLL (4096 bytes); opening its main image
Image opened; loading included assembly
Assembly loaded; looking for Doorstop.Entrypoint:Start
Invoking method 00000298F8FE6D68
Error invoking code!
Error message: 祓瑳浥䤮â¹�楆敬潎䙴畯摮硅散瑰潩㩮䌠畯摬渠瑯氠慯â�¤æ¥¦æ•¬æ¼ â�²ç�¡æ•³æ‰­ç¥¬âœ ç¥“瑳浥䤮â¹�楆敬祓瑳浥‬敖ç�²æ½©ãµDone

As you can see, that error message is pretty much unreadable.

Note: not sure if this is worth anything, but the dll is not 4096 bytes in size, it's actually 5K, let me know if that is a problem

Any help?
Thank you

Doorstop on Linux logging to .config/mimeapps.list

Using Unix version of BepInEx 5 on Rhythm Doctor.

Whenever I launch Rhythm Doctor, doorstop seems to be logging to my .config/mimeapps.list file and it breaks all my default application handling! It adds the line Found UnityPlayer, hooking into it instead to the start of the file so my system can't parse the file.
It also makes a folder in the game directory called Found UnityPlayer, hooking into it instead in the game folder, with this file, minus the .txt extension.
profilerc.txt

It seems to be some error with how doorstop is trying to capture/redirect stdout, but for now I've compiled doorstop without logging to fix it.

output_log being written to C:\User\ouput_log.txt

Hi, on some system of my users or on my dedicated server running win server 2022, for some reasons the redirect output log redirects the output log to C:\User\output_log.

Any idea why this happens ? the doorstop dll is next to the game, works perfectly but for some reasons this happens.
Here's my full path in case it can help.
C:\Users\Administrator\Desktop\RM PLACE

Not loading mono.dll IL2Cpp on Windows 2019?

I have no idea if it's Doorstop or the mono runtime that comes with BepInEx that's the issue, but after building the verbose version of Doorstop 3 I get this when trying to run an IL2Cpp game (V Rising) on Windows 2019:

Doorstop started!
EXE Path: C:\vrserver\VRisingServer.exe
App dir: C:\vrserver
Working dir: C:\vrserver
STDOUT handle at 0000000000000060
Pointer to GetFinalPathNameByHandleA 00007FF9BBDB2560
STDOUT handle path: 
DLL Path: C:\vrserver\WINHTTP.dll
Doorstop DLL Name: WINHTTP
Looking for original DLL from C:\vrserver\WINHTTP_alt.dll
Looking for original DLL from C:\Windows\system32\WINHTTP.dll
Proxy loaded
CONFIG: UnityDoorstop.enabled = true
CONFIG: UnityDoorstop.ignoreDisableSwitch = false
CONFIG: UnityDoorstop.redirectOutputLog = false
CONFIG: UnityDoorstop.targetAssembly = BepInEx\core\BepInEx.IL2CPP.dll
CONFIG: UnityDoorstop.dllSearchPathOverride = 
CONFIG: MonoBackend.runtimeLib = mono\MonoBleedingEdge\EmbedRuntime\mono-2.0-sgen.dll
CONFIG: MonoBackend.configDir = mono\MonoBleedingEdge\etc
CONFIG: MonoBackend.corlibDir = mono\Managed
CONFIG: MonoBackend.debugEnabled = false
CONFIG: MonoBackend.debugSuspend = false
CONFIG: MonoBackend.debugAddress = 127.0.0.1:10000
Config loaded
Doorstop enabled!
Installing IAT hook
Hook installed!!
Got il2cpp_init at 00007FF8BD4A0000
Loaded all runtime functions
Starting IL2CPP domain "IL2CPP Root Domain"
Mono lib: C:\vrserver\mono\MonoBleedingEdge\EmbedRuntime\mono-2.0-sgen.dll
Mono mscorlib dir: C:\vrserver\mono\Managed
Mono confgi dir: C:\vrserver\mono\MonoBleedingEdge\etc
Loaded mono.dll: 0000000000000000
Failed to load mono.dll! Skipping!

But on Windows 10 and 11 using the exact same files I get this and it works fine:

Loaded mono.dll: 00007FF874560000
Loaded mono.dll functions

Doorstop does not work on Valheim

Valheim is a 64bit Unity 2019.4.16 game.
With Doorstop_x64_3.0.2.2, the game just crashes immediately
With Doorstop_x64_3.1.0.0, the game starts, but the targetAssembly appears to not be running at all
I have tested with BepInEx (with the newer 3.1.0.0 dll) and the example Doorstop.dll (moved to the game folder per the path in doorstop_config.ini), doorstop_is_alive.txt did not appear
I have tested Doorstop as winhttp.dll and version.dll, neither worked
Doorstop itself appears to work, setting redirectOutputLog=true does result in an output_log.txt, just not the targetAssembly

Couldn't Open Process

Library: UnityMono (x86)
Version: 4.0.0 (from release page)
Unity Version: 2018.4.36-mbe
Game: PrincessConnectReDive (JP)
dll_search_path_override=
debug_enabled=true
debug_address=127.0.0.1:10000
debug_suspend=true
Behaviors:
(1) Game start with original Assembly-CSharp.dll and mono-2.0-bdwgc.dll
    (1) Game start directly but does not get suspended with debug_suspend=true 
    (2) Game does not start by dnSpy
        (1) dnSpy get an "Couldn't Open Process" error and quit itself see attached image
        (2) Game start after dnSpy is quit and game is not suspended
        (3) dnSpy cannot find process with "Attached to Process" option
(2) Game start with dumped and restored Assembly-CSharp.dll (dumped by CheatEngine and restored by filling the offsets) and debug build mono-2.0-bdwgc.dll (mono-2.0-bdwgc.dll is built by following the dnSpy archived repo)
    (1) Game start directly but does not get suspended with debug_suspend=true 
    (2) Game does not start by dnSpy
        (1) dnSpy get an "Couldn't Open Process" error and quit itself see attached image
        (2) Game start after dnSpy is quit and game is not suspended
        (3) dnSpy cannot find process with "Attached to Process" option

image

Would it be possible to use this to override the behaviour of the Unity editor (not for games built in Unity)?

I am trying to build something that needs to load before the Unity editor starts importing assets on launching a project. The gist is that I want to intercept any file system API calls which the Unity editor makes and capture some information when it does. I could override the calls to the file system API via reflection, but the editor does not seem to way to hook into the editor launch pipeline.

Unity does have an [InitializeOnLoad] functionality, but that only starts executing after the asset database refresh completes, so it does not work for my use case. I am wondering if I could use this to run code before the editor starts importing the project.

valheim linux dedicated server (valheim+ mod) - unable to stop server via ctrl+c/sigint

Hi,

I'm opening this issue on both doorstop and BepInEx as I'm not sure on which of these the actual problem is.
The regular Valheim server can be stopped via ctrl+c or by sending a sigint to the PID.
After installing the Valheim+ mod, which contains BepInEx and Doorstop, the server starts as usual but neither control+c on the console or sending a sigint works to gracefully stop the server.
Killing the server via sigterm/sigkill can leave the world data corrupted.

Let me know if you need any additional data, I'm happy to help where possible.

Mono search paths - multiple overrides and replace full mono search path

Allow multiple directories for mono_dll_search_path_override and allow to remove the target_path_folder and root_dir.

Maybe something like this (inspired by AssemblySearchPaths in csproj):

mono_dll_search_paths=Z:\MostImportant;{override};{target};{root};D:\Fallback
mono_dll_search_paths=A:\TheOneAndOnly
mono_dll_search_paths=

quick overview of what is happening currently:

    if (has_override) {
        strcat(mono_search_path, override_dir_full);
        strcat(mono_search_path, PATH_SEP);
    }
    strcat(mono_search_path, target_path_folder);
    strcat(mono_search_path, PATH_SEP);
    strcat(mono_search_path, root_dir);

The "fallback" case is there to avoid when future updates of the game suddenly introduce their own versions of the assemblies.
The "one and only" or "nothing" cases would allow using dynamic AppDomain.CurrentDomain.AssemblyResolve to programmatically resolve everything. (These are theoretical ideas that were not tested, so might not work well with Unity mono)

Doorstop segmentation fault with Rust (Linux)

Hi I've tried to make Doorstop work with Rust (ds), on Windows all works but on Linux I always get a segmentation fault.
Host system is a Debian 11, I'm using the supplied start script with Doorstop for Linux.
The game uses engine version 2019.4.7f1 (e992b1a16e65).
Any help would be appreciated, thanks.

==11338== Invalid read of size 8
==11338==    at 0x484A4C7: ??? (in /srv/rust/carbon/data/Steam/steamapps/common/rust_dedicated/libdoorstop.so)
==11338==    by 0x484A65D: ??? (in /srv/rust/carbon/data/Steam/steamapps/common/rust_dedicated/libdoorstop.so)
==11338==    by 0x484ABBE: plthook_open_by_handle (in /srv/rust/carbon/data/Steam/steamapps/common/rust_dedicated/libdoorstop.so)
==11338==    by 0x484998F: doorstop_ctor (in /srv/rust/carbon/data/Steam/steamapps/common/rust_dedicated/libdoorstop.so)
==11338==    by 0x400FFE1: call_init.part.0 (dl-init.c:72)
==11338==    by 0x40100E8: call_init (dl-init.c:30)
==11338==    by 0x40100E8: _dl_init (dl-init.c:119)
==11338==    by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.31.so)
==11338==    by 0x2: ???
==11338==    by 0x1FFEFFFEE6: ???
==11338==    by 0x1FFEFFFEF6: ???
==11338==    by 0x1FFEFFFF01: ???
==11338==  Address 0x1003e0003 is not stack'd, malloc'd or (recently) free'd

Hooks fail to run under RenderDoc/apitrace

When a game, Muck in this case, is run through RenderDoc or apitrace, doorstop's hooks fail to activate.
I confirmed that winhttp.dll loads in the game's process, but no environment variables from doorstop are created.
I built x64 VerboseRelease 3.4.1.0 and the resulting log is the same as a normal run except it just ends at "Hook installed!!", instead of continuing on with "Got mono_jit_init_version at XX" and so forth.

Debugging the assembly loaded by Doorstop

Is there a way to debug the assembly being loaded and executed by Doorstop 4? I have a game built with Unity 2021.3.2f1. I'm able to attach to and debug the game's assembly with dnSpy, though both dnSpy and Visual Studio fails to debug the assembly loaded by Doorstop because the symbols are not loaded.

Now that I know the game's assembly is obfuscated with ConfuserEx, though it is mainly string obfuscation, method renaming, and debugger detection. Even if it contains anti-debug, it should still be possible for me to debug since my assembly runs before Unity loads.

Cannot run on M1 Mac (ARM games)

Game: The Stanley Parable: Ultra Deluxe
Hardware: MacBook Air M1

I use libdoorstop.dylib compiled by github action.
It seems can be loaded, but it cannot hook any methods.

Basedir: /Users/test/Library/Application Support/Steam/steamapps/common/The Stanley Parable Ultra Deluxe
Executeable path: /Users/test/Library/Application Support/Steam/steamapps/common/The Stanley Parable Ultra Deluxe/TSPUD.app/Contents/MacOS/The Stanley Parable_ Ultra Deluxe
slide=bd3000
Image name: /Users/test/Library/Application Support/Steam/steamapps/common/The Stanley Parable Ultra Deluxe/TSPUD.app/Contents/MacOS/The Stanley Parable_ Ultra Deluxe
LC_SEGMENT_64
segname __PAGEZERO
vmaddr 0 vmsize 100000000
fileoff 0 filesize 0
maxprot 0 initprot 0
nsects 0 flags 0
LC_SEGMENT_64
segname __TEXT
vmaddr 100000000 vmsize 1000
fileoff 0 filesize 1000
maxprot 7 initprot 5
nsects 4 flags 0
LC_SEGMENT_64
segname __DATA
vmaddr 100001000 vmsize 1000
fileoff 1000 filesize 1000
maxprot 7 initprot 3
nsects 2 flags 0
LC_SEGMENT_64
segname __LINKEDIT
vmaddr 100002000 vmsize 8000
fileoff 2000 filesize 4ee0
maxprot 7 initprot 1
nsects 0 flags 0
LC_DYLD_INFO_ONLY
offset size
rebase 2000 8
bind 2008 18
weak_bind 0 0
lazy_bind 2020 20
export_bind 2040 20
LC_SYMTAB
symbol count: c
symbol offset: 2068
stf offset: 2138
str size: 110
LC_DYSYMTAB
itable offset: 2128
itable count: 4
LC_LOAD_DYLINKER
LC_UUID
LC_VERSION_MIN_MACOSX
LC_SOURCE_VERSION
LC_MAIN
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_LOAD_DYLIB
LC_FUNCTION_STARTS
LC_DATA_IN_CODE
LC_? (0x1d)
__DATA section __nl_symbol_ptr
__DATA section __la_symbol_ptr
Found lazy symbol pointers
Got base offset: 0
Symbol (0x10b94f2d0) 10 -> __Z10PlayerMainiPPKc
Failed to hook dlsym, ignoring it. Error: no such function: dlsym
Failed to hook fclose, ignoring it. Error: no such function: fclose
Failed to hook dup2, ignoring it. Error: no such function: dup2
Failed to hook jit_init_version, ignoring it. Error: no such function: mono_jit_init_version

Version.dll missing.

I seem to be misunderstanding how Doorstep is supposed to work. The instruction all say to copy version.dll to the game folder, but I do not see version.dll in any release for Doorstep.

In addition, when I build Doorstep in VS 2019, no version.dll is created. A proxy.dll is created, but I do not know what to do with that file. Should it be renamed to version.dll?

Also, I had to change the pre-build event because the paths in the arguments to the powershell script seemed to be missing quotation marks. The following is what I changed it to to get it to build without error (note the quotes on the -File, -projectPath, and -templatePath arguments):

powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File "$(SolutionDir)\scripts\genproxy.ps1" -projectPath "$(ProjectDir)" -templatePath "$(SolutionDir)scripts" -arch $(PlatformArchitecture)

I don't know if this would cause my issue or not.

For reference I am trying to mod the game 7 Days 2 Die.

"Step Over" bug

It's great that we can connect dnSpy without a patched mono.dll, but the "step over" bug still persists without it. Any chance to implement that fix into Doorstop?

Can't build "memcpy already defined"

I'm trying to build the solution with Visual Studio 2019, I receive the following error :

libvcruntime.lib(memcpy.obj) : error LNK2005: memcpy already defined in crt.obj
C:...\UnityDoorstop\Proxy\bin\x64\Debug\proxy.dll : fatal error LNK1169: one or more multiply defined symbols found

I can't figure out what is the issue, must be related to this in crt.h

extern void *memcpy(void *dst, const void *src, size_t n);
#pragma intrinsic(memcpy)

Have a release zip include all archs and versions

As part of the ModTek release, I include all ARCH variants. To make debugging easier, I would also like to include the verbose variants in a subfolder ready just for copy/pasting.

Right now as part of the build process of ModTek, it has to download three zips from here, and it would need to download three more for the verbose variants.

It would be simpler to just have one zip with all variants.

Windows 11 issues

Unable to run on windows 11. No errors just goes into an infinite crash like there is some policy preventing doorstop from injecting the code.. Not sure how to resolve.. Any Assistance would be much appreciated.

Support MacOS Apple Silicon (arm64)

A fairly high profile game, Valheim, just released a native Mac build. It is going to be featured at WWDC 2024, so it is likely to receive a lot of attention.

The Mac build of Valheim is still based on Unity and Mono, just like the Windows version, and they provide a "Universal Binary" of the game, which ships dual-architecture executables and libraries that are compiled for both Intel x64 and Apple Silicon arm64.

We have a way of running mods using BepInEx currently by forcing the game to run in Intel x64 mode, which kicks in Apple's Rosetta binary translator. Unfortunately, because Mono emits "new" native code all the time using its JIT compiler, Rosetta frequently causes the game to stutter or reduce FPS on some hardware. The Apple Silicon (arm64) native version of the game runs much faster because this binary translation layer is not needed.

Is it just a matter of recompiling UnityDoorstop to get it working for arm64, or would it require significant new code (e.g. in arm64 assembly) to get it to work?

Doorstop and a bizarre crash

Doorstop Version: 3.3.0.0
Game: Valheim (With unstripped unity files)

I am making a server mod for a few friends of mine, and for one of my friends the game just immediately crashes upon launch.

Originally i was thinking it was something with my mod, so i ended up building different versions of my loader dll targeting different versions of .NET. Nothing has worked so far and honestly I'm stumped. If i manually patch the files with dnSpy the game loads just fine with the mod.

Other things I've had them try before coming here.

  • Install and reinstall .NET Framework 4
  • Disable Windows Defender
  • Disable UAC
  • Checking file permissions
  • Running steam and Valheim as admin

Stacktrace from output_log.txt

========== OUTPUTTING STACK TRACE ==================

0x00007FFBBDDC7722 (UnityPlayer) UnityMain
0x00007FFBBDDC30D5 (UnityPlayer) UnityMain
0x00007FFBBDDDA9BB (UnityPlayer) UnityMain
0x00007FFBBDDCF9BB (UnityPlayer) UnityMain
  ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFBBD5AA28B)
0x00007FFBBD5AA28B (UnityPlayer) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFBBD5A2315)
0x00007FFBBD5A2315 (UnityPlayer) (function-name not available)
0x00007FFBBDD7BCC5 (UnityPlayer) UnityMain
0x00007FFBBDE4EE23 (UnityPlayer) UnityMain
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000244539705E9)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000244539705E9)
0x00000244539705E9 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 0000024453970523)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 0000024453970523)
0x0000024453970523 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000244539703FB)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000244539703FB)
0x00000244539703FB ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F294FD03)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F294FD03)
0x00000242F294FD03 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F294FE4B)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F294FE4B)
0x00000242F294FE4B ((<unknown>)) (function-name not available)
0x00007FFC0067DAD0 (mono-2.0-bdwgc) mono_get_runtime_build_info
0x00007FFC00602932 (mono-2.0-bdwgc) mono_perfcounters_init
0x00007FFC0060BB62 (mono-2.0-bdwgc) mono_runtime_invoke_array
0x00007FFC0060C2F9 (mono-2.0-bdwgc) mono_runtime_set_main_args
0x00007FFC0060BAF6 (mono-2.0-bdwgc) mono_runtime_invoke_array
0x00007FFC005B03A4 (mono-2.0-bdwgc) mono_lookup_internal_call
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F294FB70)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F294FB70)
0x00000242F294FB70 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F294E0AB)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F294E0AB)
0x00000242F294E0AB ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F294DFCE)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F294DFCE)
0x00000242F294DFCE ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F294362B)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F294362B)
0x00000242F294362B ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F29432D6)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F29432D6)
0x00000242F29432D6 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F2942F46)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F2942F46)
0x00000242F2942F46 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F2942D3B)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F2942D3B)
0x00000242F2942D3B ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F2942C5B)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F2942C5B)
0x00000242F2942C5B ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F2942B73)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F2942B73)
0x00000242F2942B73 ((<unknown>)) (function-name not available)
  ERROR: SymGetSymFromAddr64, GetLastError: 'The specified module could not be found.' (Address: 00000242F2942ACE)
  ERROR: SymGetModuleInfo64, GetLastError: 'A dynamic link library (DLL) initialization routine failed.' (Address: 00000242F2942ACE)
0x00000242F2942ACE ((<unknown>)) (function-name not available)
0x00007FFC0067DAD0 (mono-2.0-bdwgc) mono_get_runtime_build_info
0x00007FFC00602932 (mono-2.0-bdwgc) mono_perfcounters_init
0x00007FFC0060BB62 (mono-2.0-bdwgc) mono_runtime_invoke_array
0x00007FFC0062683F (mono-2.0-bdwgc) mono_unity_managed_callstack
0x00007FFC00626586 (mono-2.0-bdwgc) mono_unity_managed_callstack
0x00007FFC4E537034 (KERNEL32) BaseThreadInitThunk
0x00007FFC5009D241 (ntdll) RtlUserThreadStart

========== END OF STACKTRACE ===========

[question] about ignoreDisableSwitch

Hello,

First of all, I am totally new to modding unity games and also to doorstop, just found about it a few days ago when checking out bepinex.

I would like to ask where I can get more information about ignoreDisableSwitch. Checking the config file and the DOORSTOP_DISABLE documentation I understand that this config would ignore an env var that disables Doorstop.

But I have some questions:

  1. Why would I want to specifically disable it via an environment var? is there a known use case?
  2. What are the risks of enabling ignoreDisableSwitch? as there is an alert that suggests it has some risks

I recently had an issue where a steam game was restarting just after it launched and disabling bepinex, changing this config in doorstop to true made it work, but I am clueless about why would I want it as false, or if there is a risk around using it as true.

Thanks in advance

UnityDoorstop doesn't load when doorstop_config.ini is written in UTF-8 with BOM

Hi there,

Using C# targeting .NET 4.0 and 4.5 (tested separately), I used File.WriteAllText to write changes to my doorstop_config.ini.

With the following code, this writes as UTF-8 with BOM:

File.WriteAllText(path, contents, Encoding.UTF8);

And this broke UnityDoorstop. It just wouldn't load.

Changing the file write to UTF-8 without BOM (explicit) fixed it:

File.WriteAllText(path, contents, new UTF8Encoding(false));

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.