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

EmulateHeap infections #238

Open
BEENNath58 opened this issue Nov 17, 2023 · 27 comments
Open

EmulateHeap infections #238

BEENNath58 opened this issue Nov 17, 2023 · 27 comments

Comments

@BEENNath58
Copy link

As you know, or may not know, the EmulateHeap shim has caused havoc since Windows 11 22H2, and will affect anything, and mostly WASAPI sessions (Mmdevapi.dll, dsound.dll, winmm.dll).

I am taking references of 3 games: Lord of the Realms, Superbike 2001 by EA, Last Bronx by Sega

Lord of the Realms causes a fault in sound engine, Superbike 2001 is same + faults from CoreMessaging and other services, Last Bronx does double harm in sound as well as graphics.

I wonder if DxWrapper is willing to touch this part anytime, since there seems to be no alternates.

@elishacloud
Copy link
Owner

This is probably a bit beyond what I can do at this time.

Have you tried disabling EmulateHeap and instead using Compatibility Fix FaultTolerantHeap (This can sometimes substitute for the broken EmulateHeap).

@BEENNath58
Copy link
Author

This is probably a bit beyond what I can do at this time.

Have you tried disabling EmulateHeap and instead using Compatibility Fix FaultTolerantHeap (This can sometimes substitute for the broken EmulateHeap).

Yes I have tried substituting with FTH. In most cases, the app crashes sooner or later again. In other cases, only the faulty part crashes (such as the sound stack) and the rest of the program remains stable, but it is just a rarity.

@elishacloud
Copy link
Owner

I would love to fix this but I don't really have the time at present and secondly, I probably don't have the correct skills.

Besides enabling FTH, you could try enabling HandleExceptions.

If this mostly happens in WASAPI sessions, why not replace the WASAPI code/dlls with ones that don't have this issue?

@BEENNath58
Copy link
Author

Besides enabling FTH, you could try enabling HandleExceptions.

Seeing that th exception handler is based on Disasm.dll from DxWnd, I had tried it previously. In Last Bronx this resulted in the game to run with black background and no sound. In Superbike 2001 it freezes at the intro credits. Lord of the Realm falls in a loop.

Other games have other effects

If this mostly happens in WASAPI sessions, why not replace the WASAPI code/dlls with ones that don't have this issue?

Well the problem doesn't start from wasapi initially. For example, in one of the games it started from Windows Core Services dll, then went to some text to speech dll, and so on. At a point I reached winmm.dll, then winmmbase.dll and after that I had no other file replaceable that wouldn't crash. It was like Windows has some kind of execution protection regardless of thr file.

@elishacloud
Copy link
Owner

I understand. I wonder if there is a way to shimmy in a hot fix for these games by hooking only the API they call when the problem starts? Maybe we can fix some inappropriate behavior the game does that way?

@BEENNath58
Copy link
Author

BEENNath58 commented Dec 6, 2023

I understand. I wonder if there is a way to shimmy in a hot fix for these games by hooking only the API they call when the problem starts? Maybe we can fix some inappropriate behavior the game does that way?

The violation doesn't occur when NTheap is used. It starts when 95heap is used. I assume the apps create memory stacks where Windows 11 22H2+ no longer wants to, or prevents from creating there. I talked to ghotik on relocating the heap somewhere, but apparently he already had one setting called Virtual Heap doing the same which didn't help much since the relocation happened late, late enough that the errors already occured. In this way the hook needs to happen even before the program is executed...

@elishacloud
Copy link
Owner

The violation doesn't occur when NTheap is used. It starts when 95heap is used.

Interesting. Sorry for my ignorance here, but why can't we just force the game to use the NTheap?

@BEENNath58
Copy link
Author

The violation doesn't occur when NTheap is used. It starts when 95heap is used.

Interesting. Sorry for my ignorance here, but why can't we just force the game to use the NTheap?

Well you can use NTheap and it is the one used by default always, but the app will crash. If you try the Superbike 2001 game on Win11 22H2 or later, you should see it crash when it is starting up.

@elishacloud
Copy link
Owner

elishacloud commented Dec 6, 2023

he already had one setting called Virtual Heap doing the same which didn't help much since the relocation happened late, late enough that the errors already occured. In this way the hook needs to happen even before the program is executed...

Sound like a job of the loader. I thought DxWnd had a separate executable that can be used as a loader? With that he should be able to load the game binary into memory in a suspended state. Then setup the Virtual Heap and then start the game loading. This way the Virtual Heap is setup before any of the game code is allowed to run.

To create a process in a suspended state you can call the CreateProcess() function in Windows, and set the dwCreationFlags parameter to include the CREATE_SUSPENDED flag. This flag will create the process in a suspended state, allowing you to modify its memory before resuming its execution. You can then use functions like WriteProcessMemory() to modify the process's memory before resuming its execution with ResumeThread().

@BEENNath58
Copy link
Author

he already had one setting called Virtual Heap doing the same which didn't help much since the relocation happened late, late enough that the errors already occured. In this way the hook needs to happen even before the program is executed...

Sound like a job of the loader. I thought DxWnd had a separate executable that can be used as a loader? With that he should be able to load the game binary into memory in a suspended state. Then setup the Virtual Heap and then start the game loading. This way the Virtual Heap is setup before any of the game code is allowed to run.

To create a process in a suspended state you can call the CreateProcess() function in Windows, and set the dwCreationFlags parameter to include the CREATE_SUSPENDED flag. This flag will create the process in a suspended state, allowing you to modify its memory before resuming its execution. You can then use functions like WriteProcessMemory() to modify the process's memory before resuming its execution with ResumeThread().

I had a chat about the situation here with him
https://sourceforge.net/p/dxwnd/discussion/general/thread/b5084adf41/?limit=25#ab36

@elishacloud
Copy link
Owner

elishacloud commented Dec 6, 2023

Thanks. I just read that thread and it is not clear from the text when he tried to load the alternative memory segment. It is after the process has been created then it is too late, unless you suspend the process first.

Also, I saw another interesting comment

Alternative plan: Is it possible to remove a execution prevention policy (DEP) from everywhere the heap is violated?
Recently I found that the "hook:DisableDEP" tweak works very well on "Westwood Monopoly" (1995 edition) so I wonder why this works in certain conditions and not others.

You can fully disable DEP (or other memory protection) for any process using Windows by setting the application to OptOut (or system override).

image

@BEENNath58
Copy link
Author

Thanks. I just read that thread and it is not clear from the text when he tried to load the alternative memory segment. It is after the process has been created then it is too late, unless you suspend the process first.

That part was to affirm my plan, if relocation was possible. He answered for both cases, a late hook and a suspended hook. In suspended hook, he still found some other, unmanageable unidentified, un-handleable sections that his setting didn't help.

About the other DEP error, he has solved the issue later

@elishacloud
Copy link
Owner

I see. That is about all I can think of at this point.

@BEENNath58
Copy link
Author

Okay thanks

The issue can be kept open, if you discover new ideas

@mirh
Copy link

mirh commented Dec 18, 2023

https://web.archive.org/web/20100619082456/http://technet.microsoft.com/en-us/ff625273.aspx
The EmulateHeap shim is 6000 lines of code. These few games likely wouldn't even need a tenth of that, but still.. whatever the special behaviour required is, it is gonna be a hell to pin down and figure out (it's so intricate that I wonder if it couldn't be claimed that even verbatim copying the entire monstrous length is still fair use because every single line is sure to have some eventual consequence for interoperability)

But if you are scrambling in the dark (and you have time to spare) there's always one thing: just blindly bisect.
Is W11 21H2 still good? If yes, not only you could start to mix and match more and more windows files between the fixed and broken versions, but there's also a lot of pre-release builds that could help further restricting the culprit.

p.s. what does the title exactly mean?

@BEENNath58
Copy link
Author

BEENNath58 commented Jan 15, 2024

@mirh I will look into the "mixing" suggestion with pre-release builds. I don't have the time right now, I actually did a mix between WIn10 and Win11 but I stopped when I had to tamper TrustedInstaller to move forward, next time I shall involve only VMs.

The title isn't good, but I was tired writing "Fixing emulateheap" everywhere

Edit: where can I download builds?

@mirh
Copy link

mirh commented Jan 15, 2024

Just try to google their name
A trainload can be found here

@BEENNath58
Copy link
Author

Just try to google their name A trainload can be found here

Also I got uupdump.net as a source.
Thanks

@BEENNath58
Copy link
Author

BEENNath58 commented Jan 15, 2024

@mirh I got to
10.0.22454.1000, Dev Channel : September 9, 2021 build and it crashes there lmao.

There's only one build behind this and I don't have it (nor do I think it is different)

@mirh
Copy link

mirh commented Jan 16, 2024

But for the absolute love of god, can you confirm that W11 21H2 RTM is instead good though?

@BEENNath58
Copy link
Author

BEENNath58 commented Jan 16, 2024

But for the absolute love of god, can you confirm that W11 21H2 RTM is instead good though?

Yes that is good enough. I will try a 21H2 and 22H2 mix directly (VMs aren't good enough).

Update: I tried the SysWOW64 DLL swap for DLLs that could be swapped (around 2800). I didn't touch the subfolders there. Somehow Wasapi crashes altogether for WinMM so EmulateHeap worked there, but ofc with no sound. DxWnd somehow revived WinMM so game started crashing, again the Exception handler there prevented the crash but with no sound. Also when I was mixing individual files, the crash module was always stuck at WINMMBASE.DLL regardless of old or new file

@mirh
Copy link

mirh commented Jan 16, 2024

If the issue is about EmulateHeap.. then you may be looking into replacing the AppPatch dlls first of all, rather than common ones? I'd be even skeptical if most of your problem here is in the 32-bit side (too bad you can't simplify the comparison like in W10 by just running x86 windows).

Anyway, other interesting ideas could be trying to run W11 21H2 with updates (only available to education and enterprise builds today, but still). Alas mid 2021 was a really awful time to keep track of changes.

@BEENNath58
Copy link
Author

BEENNath58 commented Jan 16, 2024

If the issue is about EmulateHeap

What I figured out, it is not... it is rather a Windows security limitation (hopefully not as limiting as executing CLI/STIs). EVERY application comes around to winmmbase.dll crash in the end.

then you may be looking into replacing the AppPatch dlls first of all, rather than common ones?

You mean apphelp.dll, AcGenrl.dll, AcLayer.dll, AcSpecfc.dll... I did change them first with no benefits.

Anyway, other interesting ideas could be trying to run W11 21H2 with updates (only available to education and enterprise builds today, but still).

The site where I got the 22454 build mentioned that 21H2 and 22H2 were being parallel with two different teams, newer team leading 22H2.
Btw I switched 4 of the audio dlls in SysWOW64. One of them resulted in no sound but still no upgrades from the issue.

winMM still fails:

winmm.waveOutGetNumDevs: numdevs=0
winmm32.mciSendCommandA: > mciId=0 msg=0x803(MCI_OPEN) flags=0x2000(MCI_OPEN_TYPE) cback=0 devid=0 devtype=cdaudio elementname="" alias=""
winmm32.mciSendCommandA: ERROR res=0x10a(CANNOT_LOAD_DRIVER)

@mirh
Copy link

mirh commented Jan 16, 2024

Uhm, wait so.. Are you saying that all your EmulateHeap talking around the net was just off target, and it was instead just about such old games having some problem with the windows multimedia api?

@BEENNath58
Copy link
Author

and it was instead just about such old games having some problem with the windows multimedia api?

EmulateHeap when applied on apps, WinMM gets into trouble USUALLY ALWAYS... I look at winmmbase.dll first because it's common everywhere (since at least, most games will load winmm for any reason).

Uhm, wait so.. Are you saying that all your EmulateHeap talking around the net was just off target,

Well no other people also tested and returned back with same feedback so I definitely wasn't off target 😁

@mirh
Copy link

mirh commented Jan 18, 2024

I'm having a hard time trying to understand how you are diagnosing/distinguishing the issues..

Anyhow, is the theory that replacing winmm dlls helps because they themselves are the "right ones" which didn't catch whatever regression (yet they don't like getting replaced and unfortunately sound breaks)
Or is the theory that exactly because they are the wrong ones, they don't actually get to initialize the whole audio engine, which somehow ends up dying without doing the bad operations that then would instead lead to crashes?

@BEENNath58
Copy link
Author

BEENNath58 commented Jan 18, 2024

Anyhow, is the theory that replacing winmm dlls helps because they themselves are the "right ones" which didn't catch whatever regression (yet they don't like getting replaced and unfortunately sound breaks)

Replacing doesn't change anything.

Or is the theory that exactly because they are the wrong ones, they don't actually get to initialize the whole audio engine, which somehow ends up dying without doing the bad operations that then would instead lead to crashes?

Dead sound engine and crash happens parallelly. Either can happen. Windows has FTH that will prevent the crash but will kill the sound. Note that EmulateHeap is needed to cause it, without it this won't happen.

There are 4 "audio... .dll" in SysWOW64. Replacing one of them (I can't remember which one) breaks the sound engine, but it won't crash apps. Replacing winmm dlls have no effect, i.e. using EmulateHeap will crash it and not using it will still play sounds.

The problem doesn't seem to be in native WinMM. Reason is because the apps will run correctly when EmulateHeap is not used (those apps that can run without it). Take any app, let's say Interstate 76. Microsoft has a pre-applied EmulateHeap on it which will turn off the sound engine and in turn, the CD detection mechanism. EmulateHeap was never needed by it, also verified by @UCyborg on Vogons, so turning it off will bring back the CDaudio again. Since GOG doesn't use renamed executables so the problem resides there even.

Everything wrong happens when EmulateHeap is turned on, the crashing module comes back around to winmm somehow. Either something problematic takes place in sound part, like waveOut or mciSendCommand/mciSendString or..., or something happens in non-sound related winmm parts.

A good example of non-audio issue is in Last Bronx:
https://www.vogons.org/viewtopic.php?p=1193835#p1193835

The problem could be in Winmm -> EmulateHeap interaction or some Microsoft security feature (stuffs like Core Isolation, DEP and many others are turned off so it shouldn't be that).

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

No branches or pull requests

3 participants