Ah thanks crazyc! I saw that change originally and 3AM I completely forgot to add it! I just had cursor merge the change and then tested it to make sure it's still working. I also updated the binaries on github as well. @gho if the mingw approach is causing issues, I'm more than happy to reintroduce the msvc build process as well as an alternate compilation method. I just work so much in gcc world these days and some of the mingw changes make the code a little more explicit which I kinda like if...
Ah thanks crazyc! I saw that change originally and 3AM I completely forgot to add it! I just had cursor merge the change and then tested it to make sure it's still working. I also updated the binaries on github as well. @gho if the mingw approach is causing issues, I'm more than happy to reintroduce the msvc build process as well as an alternate compilation method. I just work so much in gcc world these days and some of the mingw changes make the code a little more explicit which I kinda like if...
Hey so it's been a million years and I realize this may no longer be relevant but I recently cleaned up the old 9xheap code and made a few changes: Everything builds with mingw now - way easier than forcing msvc The heap emulation appcompat code is now a static library with essentially the ms code - this means if we have to make compatibility changes in the future you don't have to screw around with recompiling the appcompat code, it's just ready to go. I took some notes from what others have done...
Hey so it's been a million years and I realize this may no longer be relevant but I recently cleaned up the old 9xheap code and made a few changes: Everything builds with mingw now - way easier than forcing msvc The heap emulation appcompat code is now a static library with essentially the ms code - this means if we have to make compatibility changes in the future you don't have to screw around with recompiling the appcompat code, it's just ready to go. I took some notes from what others have done...
its probably shim.c https://github.com/batteryshark/9xheap_public/blob/main/shim.c I'm making inline hooks for those functions and the win7 functions may have different sizes, prologues, or names. Since this code was written, Ive been more apt to use polyhook2 instead for cross compatibility.
Ill dig into my patch tomorrow and see if i can spot the issue. I'm away at the moment eith no access to my desktop for another two days, but I might be able to point out why.
And if you wanna go really psycho, you can make naked functions or cdecl and asm your own syscalls and bind against nothing, LOLOL https://github.com/batteryshark/ghostdmp/blob/955a03ac8f5fe5e1ab9a5fbc4724d405f4b1cd79/NtDirect.cpp
No worries! I generally only use nodefaultlib if im not binding against kernel32 but it still goes against ntdll, but you can go even more stripped if you want. When I was working on pdx, I used this as a guide: https://hero.handmade.network/forums/code-discussion/t/94-guide_-_how_to_avoid_c_c++_runtime_on_windows You do lose Dllmain though so you have to specify your entrypoint in the project config if you go that route :)
No worries! I generally only use nodefaultlib if im not binding against kernel32 but it still goes against ntdll, but you can go even more stripped if you want. When I was working on pdx, I used this as a guide: https://hero.handmade.network/forums/code-discussion/t/94-guide_-_how_to_avoid_c_c++_runtime_on_windows
Also, is there a discord or some type of chat? It might be faster than responding on the forum :D
Do you need to specify NODEFAULTLIB? I was able to compile the dll without requiring a link to the MSVC dlls by just changing "Runtime Library" under C/C++ -> Code Generation to "MT" instead of "MD".
Do you have a copy of the project? It will be faster for me to compile what you're trying to compile than recreating it.
You may want to consider doing what I did for pdx - making your libc functions into a minimal image and compiling that against nodefaultlib https://github.com/batteryshark/pdx/tree/master/src/windows/common/ntmin I made a barebones lib with some vc stuff because I didn't want to screw up hooks I had put in place. In this way, it only needs incredibly minimal dependencies that can be accounted for
You may want to consider doing what I did for pdx - making your libc functions into a minimal image and compiling that against nodefaultlib https://github.com/batteryshark/pdx/tree/master/src/windows/common/ntmin I made a barebones lib with some vc stuff because I didn't want to screw up hooks I had put in place. In this way, it doesn't need any dependencies at all.
You may want to consider doing what I did for pdx - making your libc functions into a minimal image and compiling that against nodefaultlib https://github.com/batteryshark/pdx/tree/master/src/windows/common/ntmin I made a barebones lib with some vc stuff because I didn't want to screw up hooks I had put in place.
one possibility I can think of is if OutputDebugString uses heap allocation - it probably ends up in an infinite loop. I had some alternatives to this when I was writing pdx - namely sending my log info to another process: https://github.com/batteryshark/logjam needs: https://github.com/batteryshark/afunix I don't recommend this in most cases, but it's useful to have a logging system that can mostly be called outside of the process. A good approach to figuring that out is to hook up apimonitor and...
DBG_printf is a formatter for OutputDebugString so I can use dbgview to troubleshoot :) EDIT: Whoops - didn't realize I never included that with the code, I generally reuse the one from pdx: https://github.com/batteryshark/pdx/blob/411cb1ef9d34dac47332a5eff63bbb9f67dce984/src/shared/dbg.c
DBG_printf is a formatter for OutputDebugString so I can use dbgview to troubleshoot :)
The Rtl calls are from ntdll - quite a few hooks in this case are never called directly by an application, but are required from third-fourth order functions (e.g. stuff like VirtualAlloc may end up calling these). This is part of why I hotpatched them originally instead of IAT-focused, because realistically we need to override exports or go deeper than standard IAT patching due to things other than the games calling them. The Microsoft shim engine is interesting - not only does it hook imports (and...
The long term goal would likely be to recreate the heap management code to not use the NT/XP src, although there are only so many variations one could make to keep compatibility. The other aspect of this is more interesting - there are countless mirrors of the heap management code publicly available on github and have existed for quite some time. It's highly likely that if Microsoft cared about takedowns with this data, they would have addressed that, but it seems unlikely. If that happened, maybe...
Updated the repository and release dll to not hotpatch by default. Instead, it exports all of the functions with an h_ prefix to not get mangled. https://github.com/stonefish-systems/9xheap/releases/tag/20220817
That makes sense - I'll throw a poc together
Oh absolutely - no problem at all! Thank you and everyone else working on dxwnd for all of these compatibility fixes... I've been working on some for years and it seems we do some parallel work sometimes :) I actually started a cross platform filesystem/registry redirection library a while ago - https://github.com/batteryshark/pdx Eventually, I want to expand it into network environment emulation too but that's for another time. I have been tweaking dxwnd dll lately because it's a bit cleaner with...
Honestly a part of the issue might be how I did the hooking... it might be worth taking a crack at 9xheap modified to use minhook or something similar and just patch IAT instead of hotpatching everything - it's also using hardcoded prologue padding which isn't real tolerant of other versions of kernelbase/kernel32 and ntdll. Realistically, in retrospect, I should have compiled the dll with the fixes, exported the functions that matter, and then let some independent hooking library do its thing for...
Honestly a part of the issue might be how I did the hooking... it might be worth taking a crack at 9xheap modified to use minhook or something similar and just patch IAT instead of hotpatching everything - it's also using hardcoded prologue padding which isn't real tolerant of other versions of kernelbase/kernel32 and ntdll
Honestly a part of the issue might be how I did the hooking... it might be worth taking a crack at 9xheap modified to use minhook or something similar and just patch IAT instead of hotpatching everything.
This game will not run without heap emulation: https://archive.org/details/ys-1-winj It's the one I used in the blog post as well... outside of the first town at the start, the transparent clouds + ddraw + lack of heap emulation will crash the game. Not sure of others but I'm sure there are better test cases :) Allegedly NFS5 needs it: https://www.pcgamingwiki.com/wiki/Need_for_Speed:_Porsche_Unleashed
This game will not run without heap emulation: https://archive.org/details/ys-1-winj It's the one I used in the blog post as well... outside of the first town at the start, the transparent clouds + ddraw + lack of heap emulation will crash the game. Not sure of others but I'm sure there are better test cases :)
fix_9xheap() is an empty function... it just serves as an import that I can add to an arbitrary dll or exe for linking, but the actual patching is in dllmain but yeah, that should work :) Realistically if you LoadLibrary the dll itself, you can get the same effect... the function itself is just for static import uses. Also, I made a statically linked version in the "Releases" section of github so it didn't need specific msvc versions.
fix_9xheap() is an empty function... it just serves as an import that I can add to an arbitrary dll or exe for linking, but the actual patching is in dllmain but yeah, that should work :) Realistically if you LoadLibrary the dll itself, you can get the same effect... the function itself is just for static import uses.
fix_9xheap() is an empty function... it just serves as an import that I can add to an arbitrary dll or exe for linking, but the actual patching is in dllmain but yeah, that should work :) Realistically if you LoadLibrary the dll itself, you can get the same effect... the function itself is just for static import uses.
fix_9xheap() is an empty function... it just serves as an import that I can add to an arbitrary dll or exe for linking, but the actual patching is in dllmain but yeah, that should work :)
Sure thing - the "FILL THIS IN" part was using the XP src documents... I originally didn't include them with the repo, but I have a mirror where they are included: https://github.com/stonefish-systems/9xheap
I did this for an Ys game a while back, it did involve using the shim from xp for heavy lifting, but it seems to work fine on Win10/11 with some of the tweaking I made: https://github.com/batteryshark/9xheap_public I also made a writeup about the changes I made to make it work: https://github.com/batteryshark/writeups/wiki/Time-Travel---Win9x-Heaps-for-the-2020s
I did this for an Ys game a while back, it did involve using the shim from xp for heavy lifting, but it seems to work fine on Win10/11 with some of the tweaking I made: https://github.com/batteryshark/9xheap_public
I did this for an Ys game a while back, it did involve lifting some potentially sensitive code to do it, but it seems to work fine: https://github.com/batteryshark/9xheap_public