NeighTools / UnityDoorstop

Doorstop -- run C# before Unity does!
GNU Lesser General Public License v2.1
419 stars 62 forks source link

Add the ability to override the Unity's boot.config file path #59

Closed aldelaro5 closed 1 month ago

aldelaro5 commented 1 month ago

This covers some niche usecases I thought fit within doorstop, but it takes a bit of an explanation of what I wanted to do that lead me to add this feature.

Unity games have a file in their data folder called "boot.config" which is a simple key value pair file (kinda like a .ini, but without sections or comments) that configures various boot parameters. While this file is not documented, some simple reversing with ghidra revealed there's actually nothing that tells what is a valid key: it's just agreed upon by the file and uinity's player. It means the valid keys depends on the version and the player.

What I wanted to do was to have a unity 2018.4 game use the newer mono runtime this version supported. It's normally the default one, but for the specific game I was dealing with, it wasn't for historical reasons. Upgrading the runtime is already possible with doorstop: copy the MonoBleedingEdge folder from unity to the game, copy the corlibs and tell doorstop to look for them where you placed them. Easy....

...except there's one step left: in order for unity's player to even ATTEMPT to use MonoBleedingEdge instead of Mono, you HAVE to change the boot.config file in the data folder so it says:

scripting-runtime-version=latest

Instead of

scripting-runtime-version=legacy

There is no way around this one: I even checked with ghidra and it absolutely needs to be changed for this upgrade to work. The problem with this is doing this requires modifying a game's file which is intrusive for multiple reasons (the main one I can think of is this won't survive a Steam's survive integrity).

So I wanted to have a way to set this up without changing the original boot.config. This lead me to realise this file is loaded EXTREMELY early, WAY earlier than even mono. It means the only way I can do something is with doorstop by hooking into the player's call to loading the file.

And this is what leads me to this pr: I added hooks (tested on Windoes and Linux) that adds a config option where you can specify a custom path to an external boot.config. It hooks into CreateFileW/A and fopen/fopen64 to track when it tries to open the file and when it detects it, it will change the filename to call it with effectively redirecting the file path.

Since the exact options you can do varies per versions/players and I only needed this to change one key's value, it's unclear what are all the possibilities you can do with this, but my thinking is if I needed to mess with this for something like that, I could see this feature being useful here.

I also think it should be possible with a publicised set of unity's dll to actually read or set these values from the managed side (my ghidra reversing suggests they left bindings in an internal class which could be exposed after publicisation).