https://bugs.winehq.org/show_bug.cgi?id=56136
Bug ID: 56136 Summary: ImageGetDigestStream does not behave the same as on windows Product: Wine Version: unspecified Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: imagehlp Assignee: wine-bugs@winehq.org Reporter: hkarlsson@gmail.com Distribution: ---
Created attachment 75814 --> https://bugs.winehq.org/attachment.cgi?id=75814 Isolated the function and ran it side by side with real windows function to test results
Just wanted to report that ImageGetDigestStream does not match the windows (11) version. I suspect this is very low prio and rarely used. It is used by Unreal's ShaderCompileWorker.exe as a way to verify dxcompiler.dll version (and a couple more dlls). The reason it is used is to get same version between signed and unsigned binaries. I tried fixing it up myself but got stuck on some weirdness related to .rsrc section when not having CERT_PE_IMAGE_DIGEST_RESOURCES set (which is a scenario Unreal is not using). Since our usecase is detouring system calls I ended up putting a specialized (and very limited) version of ImageGetDigestStream into our code to workaround the problem for Unreal (The notes section inside wine source code also says that this function is only tested with 32-bit so I suspect this code is very old and extremely rarely used
I've attached a hacked up version where my usecase works but there are lots of cases not working so I didn't want to create a pull request.
https://bugs.winehq.org/show_bug.cgi?id=56136
Fabian Maurer dark.shadow4@web.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |dark.shadow4@web.de
--- Comment #1 from Fabian Maurer dark.shadow4@web.de --- Do you think you could provide a simple sample that we could use to test? Right now it requires external DLLs that I don't have.
Goal would be to create a test case like we currently have in ImageGetDigestStream, I think.
https://bugs.winehq.org/show_bug.cgi?id=56136
--- Comment #2 from Henrik Karlsson hkarlsson@gmail.com --- You can just take a couple dlls from the system32 folder on any new windows version I suspect. I guess then you would need to extract the minimal repros from those files into binary blobs in the wine test code.
The problems found in the specific dlls I needed to work (dxcompiler.dll and dxil.dll) are coverered by the system32 dlls as well.
Or do you want me to paste the system32 dlls into here?
https://bugs.winehq.org/show_bug.cgi?id=56136
--- Comment #3 from Fabian Maurer dark.shadow4@web.de --- No, please don't attach copyrighted binaries.
Problem is, I don't think we can just extract data from windows dlls to use in out tests. I guess one could manually compare the difference between wine results and windows results.
I'll put this on my list of things I could work on, but if I do, it probably won't be anytime soon.
https://bugs.winehq.org/show_bug.cgi?id=56136
Eric Pouech eric.pouech@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |eric.pouech@gmail.com
--- Comment #4 from Eric Pouech eric.pouech@gmail.com --- We should probably craft our own test DLLs (imagehlp/tests/image.c already has some bits for building such files, potentially to be extended for this use case, didn't look into the details). (at least kernel32/tests/loader.c and dbghelp/tests/path.c also generate their own PE files for testing).
Note also that current imagehlp code (at least for ImageGetDigestStream, but likely for other APIs too) expects manipulated image bitness to match imagehlp DLL bitness, which is likely wrong. That should be tested as well.
https://bugs.winehq.org/show_bug.cgi?id=56136
Zeb Figura z.figura12@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |z.figura12@gmail.com
--- Comment #5 from Zeb Figura z.figura12@gmail.com --- What are you imagining we should test that would require us to build a test DLL, rather than using e.g. kernel32.dll?
https://bugs.winehq.org/show_bug.cgi?id=56136
--- Comment #6 from Henrik Karlsson hkarlsson@gmail.com --- I would write code that can traverse through all dlls in system32 and make sure that works.
Then try to write some custom dlls that covers the various cases. I have no idea which parts of the dlls that trigger what behavior though.. When I was messing around with this it really felt very arbitrary, so I think this would be quite hard.
Even though it would be great to have full unit test coverage I think it is more important to just make it work with the dlls in system32 folder once. It is a tricky domain to make unit tests without copying binary data from windows.
https://bugs.winehq.org/show_bug.cgi?id=56136
--- Comment #7 from Zeb Figura z.figura12@gmail.com --- Creating a test DLL isn't hard. We don't even need to do it manually like in kernel32:loader. Tests are compiled with mingw, and we have build system support for adding a custom DLL as a resource (cf. msi, setupapi for examples).
I'm just confused about why we need a dedicated test DLL. As far as I can tell the function just extracts imports and resources [which we could test against any system module, or the test exe itself] and debug info [which I don't think we can meaningfully test and probably don't even need to implement].
https://bugs.winehq.org/show_bug.cgi?id=56136
--- Comment #8 from Eric Pouech eric.pouech@gmail.com --- (In reply to Zeb Figura from comment #7)
Creating a test DLL isn't hard. We don't even need to do it manually like in kernel32:loader. Tests are compiled with mingw, and we have build system support for adding a custom DLL as a resource (cf. msi, setupapi for examples).
I'm just confused about why we need a dedicated test DLL. As far as I can tell the function just extracts imports and resources [which we could test against any system module, or the test exe itself] and debug info [which I don't think we can meaningfully test and probably don't even need to implement].
I does more than that. The callback is called with (each line = 1 call): - DOS header - PE header - PE sections (one call per section?) PE header (in callback) is modified from file version (eg zeroeing some fields). Still to be understood for the resources how many calls are generated. From Henrik's comments, it looks like the handling of this is not straightforward (didn't look into it). We also have to be sure if the passed data to the callback are the exact version of the image or a modified version thereof.
Note: in the context of #1, we may have to replicate the same number of callbacks with data (potentially modified) and size. If a digest is computed from the callback bits (and how the data are feed to the hash algo, and the hash algo itself), it may generate different results.
There's already a test in imagehlp/tests/image.c with a hand crafted generated DLL for ImageGetDigestStream. So that should be extended.
https://bugs.winehq.org/show_bug.cgi?id=56136
--- Comment #9 from Henrik Karlsson hkarlsson@gmail.com --- yes, it is not intuitive. The number of callbacks differ depending on the dll.. if you just flush through all the dlls found in system32 you will see a bit of different behaviors.
So you have all the permutations of 1. signed or not signed dll 2. flag options for ImageGetDigestStream 3. dll content seem to cause different number of callback counts/ordering
And then also, 32-bit vs 64-bit :)
Fun stuff