Hi all,
Uwe and I have been working on several executables which have been compressed by Shrinker. Basically, under win98 it tries to load a VXD which is disallowed. The prospects are better under nt40 mode, but it looks like Shrinker purposely causes read and write exceptions.
After looking at this for a little over a week, I've found that there are two problems which need to be solved.
The first is that the exception handler installed by Shrinker under Wine causes another fault and then a spin. Under WinDbg (in W2K/VMWare) the exception handler does not cause another fault, and execution continues nicely.
The second is that WinDbg finds a write fault where Wine does not. To fix this, Wine must set protections on the executable's image map. I came up with a patch to do this, and it worked for my Shrinkered exe, but not for Uwe's.
Uwe's exe loads MSVCRT20.DLL, and then Wine calls PE_fixup_imports, which attempts to write to that DLL's .idata section, which had been set read-only. Clearly Wine needs to write to that section to set up imports which haven't been implemented.
Now, my patch put the protections on the mapped image right at the end of map_image. This works when map_image is called (eventually) from PROCESS_InitWine, so that the initial executable gets its protections set right.
However, it doesn't work for PE_LoadLibraryExA (called by LoadLibraryExA) because it first checks to see if the library has already been loaded. If it has been loaded, it calls PE_fixup_imports. If it has not been loaded, it calls (eventually) map_image.
So if the library has already been loaded, it has already had its protections set up by map_image at some point in the past. Then when PE_fixup_imports is called, a protection violation occurs.
My current idea is to go into PE_fixup_imports, unprotect the .idata section, do the fixups, and reprotect the section.
The bad thing is that if someone else in the future writes some code that does additional fixups to other sections, they are also going to have to unprotect and reprotect. This might turn out to be a good thing, though, if it forces you to do that.
What does everyone think?
Thanks,
--Rob