otavepto / gbe_fork

Fork of https://gitlab.com/Mr_Goldberg/goldberg_emulator
https://gitlab.com/Mr_Goldberg/goldberg_emulator
GNU Lesser General Public License v3.0
185 stars 54 forks source link

Load .dll Issue (Access Denied) (buffer overflow in `Steam_User::GetAuthSessionTicket` with new appticket) #143

Closed StormStrK closed 2 months ago

StormStrK commented 2 months ago

Hi, I want to report a small issue when injecting dlls. Trying to Load Goldberg's xlive64.dll on Forza Horizon4 with the latest build and the load_dlls folder gives a silent crash when you press start.

Tried steamclient's new dll inject instead and when enabling the errors on the ini file I get messages about failure to inject xlive64 due to error code:5 Access denied. Tried running as admin and made sure architecture matched, antivirus disabled as well as overlay.

Reverted to Apr10 version and it loads without issue via load_dll folder. Any idea if I'm doing something wrong here? Sorry to bother. Thanks.

otavepto commented 2 months ago

I just tried it and it's crashing with heap corruption error, the dll itself loads fine but it's doing something weird. I'll check the code difference with the release from 10 April Edit: didn't make a difference

Please attach a debug log without enabling the overlay, use either the experimental build or coldclient build

StormStrK commented 2 months ago

With the latest coldclient the game doesn't launch at all, No error, just nothing. If I set the ForceInjectSteamClient=1 then I at least get an error. Attaching the log for both respective scenarios.

[2 ms] [tid: 11604] SteamClient::Exe: C:\Games\Temp\Forza Horizon 4\ForzaHorizon4.exe
[2 ms] [tid: 11604] SteamClient::ExeRunDir: 
[2 ms] [tid: 11604] SteamClient::ExeCommandLine: 
[2 ms] [tid: 11604] SteamClient::AppId: 1293830
[2 ms] [tid: 11604] SteamClient::SteamClient: C:\Games\Temp\Forza Horizon 4\steamclient.dll
[2 ms] [tid: 11604] SteamClient::SteamClient64Dll: C:\Games\Temp\Forza Horizon 4\steamclient64.dll
[2 ms] [tid: 11604] SteamClient::PersistentMode: 0
[2 ms] [tid: 11604] SteamClient::ForceInjectSteamClient: 
[2 ms] [tid: 11604] SteamClient::ForceInjectGameOverlayRenderer: 
[2 ms] [tid: 11604] Injection::DllsToInjectFolder: C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls
[2 ms] [tid: 11604] Injection::IgnoreInjectionError: 
[2 ms] [tid: 11604] Injection::IgnoreLoaderArchDifference: 
[2 ms] [tid: 11604] Debug::ResumeByDebugger: 
[3 ms] [tid: 11604] Setting ExeRunDir to: C:\Games\Temp\Forza Horizon 4
[5 ms] [tid: 11604] Detected exe arch: x64
[5 ms] [tid: 11604] Detected loader arch: x64
[7 ms] [tid: 11604] Dll C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\xlive64.dll will be injected
[7 ms] [tid: 11604] Searching for load order file: C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\load_order.txt
[7 ms] [tid: 11604] Found previous registry entry (HKCU) for Steam
[7 ms] [tid: 11604] Found previous registry entry (HKLM) for Steam
[7 ms] [tid: 11604] Found previous registry entry (HKCS) #1 for Steam
[7 ms] [tid: 11604] Found previous registry entry (HKCS) #2 for Steam
[7 ms] [tid: 11604] spawning the requested EXE file
[10 ms] [tid: 11604] injecting 1 dlls
[10 ms] [tid: 11604] Injecting dll: 'C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\xlive64.dll' ...
[5850 ms] [tid: 11604] Injected!
[5850 ms] [tid: 11604] resuming the main thread of the exe
[5872 ms] [tid: 11604] restoring registry entries (HKCU)
[5872 ms] [tid: 11604] restoring registry entries (HKLM)
[5873 ms] [tid: 11604] restoring registry entries (HKCS) #1

Log file closed

[2 ms] [tid: 1588] SteamClient::Exe: C:\Games\Temp\Forza Horizon 4\ForzaHorizon4.exe
[2 ms] [tid: 1588] SteamClient::ExeRunDir: 
[2 ms] [tid: 1588] SteamClient::ExeCommandLine: 
[2 ms] [tid: 1588] SteamClient::AppId: 1293830
[2 ms] [tid: 1588] SteamClient::SteamClient: C:\Games\Temp\Forza Horizon 4\steamclient.dll
[2 ms] [tid: 1588] SteamClient::SteamClient64Dll: C:\Games\Temp\Forza Horizon 4\steamclient64.dll
[2 ms] [tid: 1588] SteamClient::PersistentMode: 0
[2 ms] [tid: 1588] SteamClient::ForceInjectSteamClient: 1
[2 ms] [tid: 1588] SteamClient::ForceInjectGameOverlayRenderer: 
[2 ms] [tid: 1588] Injection::DllsToInjectFolder: C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls
[2 ms] [tid: 1588] Injection::IgnoreInjectionError: 
[2 ms] [tid: 1588] Injection::IgnoreLoaderArchDifference: 
[2 ms] [tid: 1588] Debug::ResumeByDebugger: 
[3 ms] [tid: 1588] Setting ExeRunDir to: C:\Games\Temp\Forza Horizon 4
[5 ms] [tid: 1588] Detected exe arch: x64
[5 ms] [tid: 1588] Detected loader arch: x64
[6 ms] [tid: 1588] Dll C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\xlive64.dll will be injected
[6 ms] [tid: 1588] Searching for load order file: C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\load_order.txt
[7 ms] [tid: 1588] Found previous registry entry (HKCU) for Steam
[7 ms] [tid: 1588] Found previous registry entry (HKLM) for Steam
[7 ms] [tid: 1588] Found previous registry entry (HKCS) #1 for Steam
[7 ms] [tid: 1588] Found previous registry entry (HKCS) #2 for Steam
[7 ms] [tid: 1588] spawning the requested EXE file
[10 ms] [tid: 1588] injecting 2 dlls
[10 ms] [tid: 1588] Injecting dll: 'C:\Games\Temp\Forza Horizon 4\steamclient64.dll' ...
[5916 ms] [tid: 1588] Injected!
[5916 ms] [tid: 1588] Injecting dll: 'C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\xlive64.dll' ...
[5917 ms] [tid: 1588] Failed to inject the dll: C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\xlive64.dll
Failed to create/run remote thread with CreateRemoteThread()
Access is denied.

Error code = 5

[5917 ms] [tid: 1588] restoring registry entries (HKCU)
[5917 ms] [tid: 1588] restoring registry entries (HKLM)
[5917 ms] [tid: 1588] restoring registry entries (HKCS) #1

Log file closed

I also tried to inject the steamclient64 manually after the xlive using the load order and it crashed as well. It may be related to the second injection because the first seems to work fine. I've been getting some crashes with the Apr10 version during gameplay too but I'm not sure those are emu related, I'll test with an older release and confirm.

Edit: Seems like the crashes on the April 10th version were because I had a build_id.txt file on steam_settings, weirdly enough but probably unrelated to the main issue though as those crashes happened during gameplay at the start whereas the current version crashes during the press start screen or doesn't boot at all as with the cold client version. I'll try deleting lines from the config files next.

otavepto commented 2 months ago

As you can see, it can inject steamclient64.dll just fine

[10 ms] [tid: 1588] Injecting dll: 'C:\Games\Temp\Forza Horizon 4\steamclient64.dll' ...
[5916 ms] [tid: 1588] Injected!

And earlier it did inject your dll

[10 ms] [tid: 11604] injecting 1 dlls
[10 ms] [tid: 11604] Injecting dll: 'C:\Games\Temp\Forza Horizon 4\steam_settings\load_dlls\xlive64.dll' ...
[5850 ms] [tid: 11604] Injected!

Regarding the crash, the xlive emu has some problem in its dllmain(), as I mentioned earlier it's causing heap corruption whenever I use it, but nonetheless it is injected on my end just fine. I tested 3 dlls and they're all fine:

[31 ms] [tid: 2156] spawning the requested EXE file
[41 ms] [tid: 2156] injecting 3 dlls
[41 ms] [tid: 2156] Injecting dll: 'D:\Games\xxxx\steamclient64.dll' ...
[62 ms] [tid: 2156] Injected!
[62 ms] [tid: 2156] Injecting dll: 'D:\Games\xxxx\steam_settings\load_dlls\xlive64.dll' ...
[75 ms] [tid: 2156] Injected!
[76 ms] [tid: 2156] Injecting dll: 'D:\Games\xxxx\steam_settings\load_dlls\nt_file_dupe.dll' ...
[87 ms] [tid: 2156] Injected!
[87 ms] [tid: 2156] resuming the main thread of the exe

Notice my timing though, it takes only ~20ms to run the dllmain() of each dll, but in your logs the first dll always takes ~5 seconds, that's comically large, not even dlls packed with vmprotect would take that long for just the dllmain().

Something is definitely hooking the Win API LoadLibraryW() on your machine, both coldclient and the experimental emu build rely on this function. Could be an antivirus service, an overlay app like RivaTuner Tuner RTSS, etc...

Disable literally everything, also most antivirus programs have a real-time checking service that's always enabled even when you pause them, google how to disable that too.

As long as you keep seeing ~5 seconds, then the behavior is abnormal, keep disabling services and background apps until the injection time drops to 10ms-20ms like mine.

StormStrK commented 2 months ago

Thanks for your input. I think we may be looking at 2 different issues here. For clarification, the cold client version of the Apr10 Build also gives me the same errors (just tested). I disabled everything I can imagine, windows antivirus, exploit protection, firewall, all monitoring software and gamepad emulation, even tried a clean boot, the ms time remains the same. Weird, I'll try to look into that but the other issue is related to the experimental build.

On the experimental build on Apr 10 I get the game to run without issues, however the experimental version on the current build is the one that crashes once you "press start" on the screen. I thought it may have been injection related because I got that error on the current cold client version but it looks like that is also present on the Apr10 build of the cold client so that's probably completely separate. I'm attaching a log of the crashing build. STEAM_LOG.txt

Edit: Examining the event viewer, the crash has some info:

 Faulting module name: steam_api64.dll, version: 8.33.9.23, time stamp: 0x662a4621
Exception code: 0xc0000005
Fault offset: 0x0000000000791e3c

That error again... maybe it's sort of related after all, not sure why it does not happen on the Apr 10 experimental build for me.

otavepto commented 2 months ago

I see you have setup a crash printer in C:\Games\Temp\Forza Horizon 4\path\relative\to\dll\crashes.txt If that file exists please attach it. The game is crashing after Auth_Data::Serialize(), but I don't remember changing that really.

Also, it would help a lot if you attached the logs from the build on 10 April, thanks in advance.

By the way, just out of curiosity, if you are familiar with an assembly debugger like x64dbg, attach it to the game as early as possible before it crashes and check whether LoadLibraryW/LoadLibraryA have a regular function prologue or is the first instruction a jmp or push/ret pair to some trampoline/hook. You can ignore the above paragraph if you're not familiar with that.

otavepto commented 2 months ago

Oh I found why it's crashing, the game sends a buffer of 1024 bytes (1KB) in this line

[40655 ms, 40655139 us] [tid 9484] Steam_User::GetAuthSessionTicket() 1024

But due to the unhinged amount of DLCs, the final buffer is 4962 bytes (4 KB)

[40975 ms, 40975413 us] [tid 9484] Auth_Data::Serialize() final data (after signature) [4962 bytes]:

And we don't have a check for that! In your .ini file, set new_app_ticket=0 (disable it) in the section [main::general]

StormStrK commented 2 months ago

You are right, thank you very much now the current build is able to get past that screen and right into gameplay!

As a sidenote, the game crashed as soon as you regain control of the vehicle. The Apr10 build was also behaving like this until I deleted the build_id.txt file for some reason. I thought what the heck, and deleted the equivalent build_id line from ini and now it works like magic. A separate bug/incompatibility with this game perhaps?

Thank you. Now I'll try to figure out what's happening with the cold client.

otavepto commented 2 months ago

For the build ID, keep the problematic line in the .ini and let the game crash, then attach the logs. It might reveal another bug or something

StormStrK commented 2 months ago

Here's the log for the current experimental version with the ini build id line intact. STEAM_LOG.txt

The windows event viewer reports:

Faulting module name: ForzaHorizon4.exe, version: 1.478.564.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x000000000377f150

Hope it helps. Kind of hard to read with all the matchmaking entries. (is that normal?)

otavepto commented 2 months ago

Nothing seems unusual, but the last request was this [120857 ms, 120857222 us] [tid 11408] Steam_Apps::GetAppBuildId(), so it could be yet another trick to detect emus. In any case, I'm glad this was figured eventually, will have to fix that buffer overflow. I'd also recommend only enabling the settings you need and remove the others

StormStrK commented 2 months ago

Thank you very much for all your help. I've learned a couple tricks to read the logs better. It is probably the case that the build_id thing is a trick since this is the first game I've had issues with that line and I've tested LOTS. I'll try to enable only what I need, thing is... My default is that if I don't know what something does I probably just copy it as is from the example file since I assume those are a sort of "default" config but I'll just use the lines I know for sure I need and hope nothing breaks.

As for the Steam Client issue, I tested the latest build on a couple games and tried injecting some dlls, the timing is around 44ms which is much closer to your example and the games load without issue. I take it it's probably another particular thing about Forza 4 because I suppose if there were something on my system hooking LoadLibraryW() then I'd probably notice it regardless of the game.

Anyway thanks again for all your help!

Detanup01 commented 2 months ago

Please check your DLCs.txt becuase AppId 0-2465200 is compleletly unrealistic (AppId 0 not exist and 2465200 is Sons of the Forest DediServer)

otavepto commented 2 months ago

Oh no I screwed up actually, I totally forgot about that! One of the later changes I added was this and it's enabled by default https://github.com/otavepto/gbe_fork/blob/1b07a290f27e48fdc7a3d794f1a6e83f31a3f3e1/dll/settings_parser.cpp#L1212

Didn't even think of that scenario 🤦