Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DllMain: make game wait for us to finish, add SkipLauncher setting #51

Merged
merged 7 commits into from
Nov 10, 2023

Conversation

emoose
Copy link
Contributor

@emoose emoose commented Nov 7, 2023

ATM we use CreateThread from DllMain to spawn a thread for our Main to execute in, unfortunately while that thread is running it seems games main thread is also executing, which can cause a race between our patches being applied & the game running the code we're patching, seen this cause issues already with the texture buffer patch :/

Tried running our Main directly from DllMain instead and that seemed to work fine, but I know there's issues it can run into with loader lock etc, which is probably why CreateThread was used there instead.

In the past I've got around this by hooking one of the imports that are called near games entrypoint, GetSystemTimeAsFileTime / GetStartupInfoW etc are usually called by the VC runtime built into game exe very early on, but sadly it seems ASI loader is also hooking those, and some reason they're only unhooked after ASI plugins have been loaded, so they're still hooked by it during our DllMain ;_;

Luckily it looks like one of the funcs called by WinMain does call into memset imported from vcruntime140 very early on, checked all 3 games and they all shared the same call there, added stuff to hook the IAT for that instead and it all seems to work fine.

With this our Main func should fully run before the game does anything important, maybe we can remove the iInjectionDelay Sleep stuff now too, but haven't changed that in here in case it's needed for something.

Heard from a couple people that this helped fix the crashing with larger textures, hopefully all our hooks should still work fine too.

@emoose
Copy link
Contributor Author

emoose commented Nov 7, 2023

Ah just noticed games launcher.exe doesn't make use of vcruntime140, so the idea of hooking that & launching game EXE directly wouldn't work with this (did have something working for that too...)

Got an idea which might help keep it working though, maybe we can keep the CreateThread stuff we used but just make memset hook wait for that thread to finish before returning back to game code, hmm..

E: seem to have it working below, now our Main code will still run no matter whether EXE imports vcruntime140 or not, if the EXE does import vcruntime140 then the memset hook will be applied to make the game wait for us to finish.

@emoose emoose changed the title DllMain: hook games memset IAT to let us load in earlier DllMain: hook games memset IAT to let game wait for us to finish loading Nov 7, 2023
@emoose
Copy link
Contributor Author

emoose commented Nov 8, 2023

Got the launcher skip stuff working at https://github.com/emoose/MGSHDFix/commits/iat-hook-direct-launch too, with that you can set SkipLauncher = true, and then running game from Steam should boot up the game directly, the Region/Language settings there seem to work fine now that we can patch them earlier too, still need to work out the values for them though.

Also changed some of the string compares to use an enum instead, game seems to boot a little faster now, but that could just be placebo :P If that looks fine to you I could close this and make a PR for that instead.

@Lyall
Copy link
Owner

Lyall commented Nov 8, 2023

Got the launcher skip stuff working at https://github.com/emoose/MGSHDFix/commits/iat-hook-direct-launch too, with that you can set SkipLauncher = true, and then running game from Steam should boot up the game directly, the Region/Language settings there seem to work fine now that we can patch them earlier too, still need to work out the values for them though.

Also changed some of the string compares to use an enum instead, game seems to boot a little faster now, but that could just be placebo :P If that looks fine to you I could close this and make a PR for that instead.

This looks great. I just tested out the iat-hook-direct-launch branch and it works fantastically. All the hooks still work, thankfully there was nothing that depended on the injection delay to grab values late or anything. If you go ahead and put up a PR for that branch I'm happy to merge it.

On a side note, yeah it does seem to boot up faster for me too. MGS3 in particular seemed to stall for a bit on start-up sometimes before.

@emoose
Copy link
Contributor Author

emoose commented Nov 8, 2023

Rebased those commits to this branch, hopefully didn't break the PR lol.

@emoose emoose changed the title DllMain: hook games memset IAT to let game wait for us to finish loading DllMain: make game wait for us to finish, add SkipLauncher setting Nov 8, 2023
Removed double underscores from OsContext funcs since that's reserved for some compilers
@Lyall Lyall merged commit 044bcb6 into Lyall:master Nov 10, 2023
@ThirteenAG
Copy link

Sorry for late reply, but if I understand the issue correctly, you simply want to use InitializeASI() instead of dllmain.
E.g.
https://github.com/ThirteenAG/Ultimate-ASI-Loader/blob/master/source/demo_plugins/OverloadFromFolderDLL.cpp#L254

That's the default way for asi plugins to execute code for quite a while.

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