More stepping through the code, comparing Windbg to gdb, and I found another landmine. Shrinker gets the address of the NTDLL procedure LdrAccessResource, and looks for this code:
FF74XXXX push [esp+X] E8XXXXXXXX call ....
Instead, it finds an unimplemented procedure in Wine. So now I will look at LdrAccessResource (and friends) to see what's involved in implementing it, whatever it is.
--Rob
Robert Baruch autophile@starband.net writes:
More stepping through the code, comparing Windbg to gdb, and I found another landmine. Shrinker gets the address of the NTDLL procedure LdrAccessResource, and looks for this code:
FF74XXXX push [esp+X] E8XXXXXXXX call ....
Instead, it finds an unimplemented procedure in Wine. So now I will look at LdrAccessResource (and friends) to see what's involved in implementing it, whatever it is.
Sounds much more problematic. LdrAccessResource itself is not too hard, but I doubt you'll get gcc to generate exactly the above code; and writing LdrAccessResource in assembly is not really an option.
On Mon, 24 Dec 2001, Alexandre Julliard wrote:
hard, but I doubt you'll get gcc to generate exactly the above code; and writing LdrAccessResource in assembly is not really an option.
Yes, but can't we write a trivial wrapper in assembly that simply calls an internal function (written in C) which does the actual work?
-- Dimi.
On Mon, 24 Dec 2001 16:51:30 -0500 "Dimitrie O. Paun" dimi@cs.toronto.edu wrote:
Yes, but can't we write a trivial wrapper in assembly that simply calls
an
internal function (written in C) which does the actual work?
(laughing) You spoke too soon, see my just-posted message.
--Rob
On 24 Dec 2001 12:33:50 -0800 Alexandre Julliard julliard@winehq.com wrote:
Instead, it finds an unimplemented procedure in Wine. So now I will
look
at LdrAccessResource (and friends) to see what's involved in
implementing
it, whatever it is.
Sounds much more problematic. LdrAccessResource itself is not too hard, but I doubt you'll get gcc to generate exactly the above code; and writing LdrAccessResource in assembly is not really an option.
Well, Shrinker is getting kind of ridiculous with its required checks for the genuine Microsoft NTDLL.DLL. Also I can't find LdrAccessResource documented anywhere. Smacks of anticompetitiveness and monopolistic intentions to me :) Is there a book on undocumented NT/2000?
I looked at the assembly of LdrAccessResource. All it is is push four args onto the stack, call an internal function, and return.
That internal function is more complicated, but it looks like it is getting a pointer to the RESOURCE entry of an image -- there are calls to RtlImageNtHeader and RtlImageDirectoryEntryToData.
So anyway, if we implemented this internal function (in C), then in theory it wouldn't be much of a big deal to code LdrAccessResource in assembly. Although it will raise a few eyebrows, we can always put in a comment similar to the one that will go in the assembler-coded EXC_CallHandler, that this code is required by Shrinker.
For those who are interested, here's the pseudo-code I've come up with for LdrAccessResource. The only missing piece is "call77F89D5F", and the exception clause -- I haven't traced those yet.
BOOL LdrAccessResource(arg1, arg2, hModule, arg4, arg5, arg6) { return _LdrAccessResource(hModule, arg4, arg5, arg6) }
BOOL _LdrAccessResource(hModule, arg2, arg3, arg4) { try { DWORD size; PIMAGE_RESOURCE_DIRECTORY *entry; PIMAGE_NT_HEADERS *ntheader; MEMORY_BASIC_INFORMATION meminfo; DWORD regionSize; void *ptr = 0; void *addr = 0;
entry = RtlImageDirectoryEntryToData( hModule, 1, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size);
if (!entry) throw STATUS_RESOURCE_DATA_NOT_FOUND;
if (arg2 < entry) hModule = LdrLoadAlternateResourceModule( hModule, 0); else { ntheader = RtlImageNtHeader(hModule&0xFFFFFFFE); if (ntheader) { if (!hModule & 0x01) regionSize = ntheader->OptionalHeader.SizeOfImage; else { ptr = ZwQueryVirtualMemory( -1, hModule&0xFFFFFFFE, 0, &meminfo, sizeof(meminfo), 0); regionSize = ptr<0 ? 0 : meminfo.RegionSize; } if (arg2 < regionSize || arg2 >= regionSize + hModule&0xFFFFFFFE) hModule = LdrLoadAlternateResourceModule( hModule, 0); } }
if (!hModule) throw STATUS_RESOURCE_DATA_NOT_FOUND;
entry = RtlImageDirectoryEntryToData( hModule, 1, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size);
if (!entry) throw STATUS_RESOURCE_DATA_NOT_FOUND;
if (hModule & 0x01) { hModule &= 0xFFFFFFFE; ntheader = RtlImageNtHeader(hModule); if (ntheader->OptionalHeader.Magic == 0x10B) addr = ntheader->OptionalHeader.DataDirectory[2].VirtualAddress; else if (ntheader->OptionalHeader.Magic == 0x20B) addr = ntheader->OptionalHeader.DataDirectory[4].VirtualAddress; else addr = 0;
if (!addr) throw STATUS_RESOURCE_DATA_NOT_FOUND;
ptr = hModule + (addr - entry);
if (!(section = RtlImageRvaToSection(ntheader, hModule, addr))) throw STATUS_RESOURCE_DATA_NOT_FOUND;
if (*arg2 > *(section+2)) { section2 = RtlImageRvaToSection(ntheader, hModule, *arg2); rtn = call77F89D5F(ntheader, hModule, *(section2+3)); ptr += *(section2+3) - *(section+3) - rtn; }
}
if (arg3) *arg3 = hModule + (*arg2 - ptr); if (arg4) *arg4 = *(arg2+1); return 0; } catch { // exception clause here } }
--Rob
Robert Baruch autophile@starband.net writes:
So anyway, if we implemented this internal function (in C), then in theory it wouldn't be much of a big deal to code LdrAccessResource in assembly. Although it will raise a few eyebrows, we can always put in a comment similar to the one that will go in the assembler-coded EXC_CallHandler, that this code is required by Shrinker.
But unlike EXC_CallHandler there is no good reason to do that, except to work around Shrinker stupidity. And for all we know there might be 20 more similar tests (and if not, they may be added in the next Shrinker version), which will lead to major code obfuscation. We will also most likely have a lot of trouble supporting the various -winver versions.
At this point I think it would be a better strategy to write an un-Shrinker tool that disables the most idiotic tests directly in the shrinkered binary. Thanks to the DMCA, this should probably be done by someone living outside the US...
On 26 Dec 2001 12:46:33 -0800 Alexandre Julliard julliard@winehq.com wrote:
But unlike EXC_CallHandler there is no good reason to do that, except to work around Shrinker stupidity. And for all we know there might be 20 more similar tests (and if not, they may be added in the next Shrinker version), which will lead to major code obfuscation. We will also most likely have a lot of trouble supporting the various -winver versions.
That was my initial worry. Altering Wine in specific ways just to trick Shrinker will just make Wine that much less understandable. I can imagine that other vendors could write their tools in a similar way, so that their tools check for Genuine(R) Microsoft(TM) Parts(SM). Eventually Wine code would be Microsoft code!
In addition, as you pointed out before, if there are other Shrinker versions, there could be more checks to make, and thus more changes to Wine.
At this point I think it would be a better strategy to write an un-Shrinker tool that disables the most idiotic tests directly in the shrinkered binary. Thanks to the DMCA, this should probably be done by someone living outside the US...
Well, there's still that SHRINKER.VXD thing under 95/98. If that VXD does not check for specific Microsoft code, then there could be success in emulating it and adding to Wine's "VXD toolbox". Of course, if that VXD contains the "copyright unprotection" code, then emulating it would also be a violation of the DMCA. But I'm up for a little civil disobediance :) OTOH, although IANAL, the interoperability clause of the DMCA (section 103f) could be an out.
--Rob
Robert Baruch wrote:
Well, Shrinker is getting kind of ridiculous with its required checks for the genuine Microsoft NTDLL.DLL. Also I can't find LdrAccessResource documented anywhere. Smacks of anticompetitiveness and monopolistic intentions to me :) Is there a book on undocumented NT/2000?
"Windows NT/2000 Native API Reference" by Gary Nebbett http://www.amazon.com/exec/obidos/ASIN/1578701996/ according to my friend who wrote one of the competitors to Shrinker.
- Dan
Hi Dan,
"Windows NT/2000 Native API Reference" by Gary Nebbett http://www.amazon.com/exec/obidos/ASIN/1578701996/ according to my friend who wrote one of the competitors to Shrinker.
I don't know... I looked at its index on amazon.com, and it had no reference to LdrAccessResource. So I suspect this book gives no information about the undocumented aspects of Windows, and probably regurgitates (like so many other API books) the online documentation.
There's also a book called "Undocumented Windows NT". That would probably be the best hope of understanding LdrAccessResource, but without being able to flip through it, I don't know if they cover it.
--Rob
On Wed, Jan 02, 2002 at 03:28:22PM -0500, Robert Baruch wrote:
Hi Dan,
"Windows NT/2000 Native API Reference" by Gary Nebbett http://www.amazon.com/exec/obidos/ASIN/1578701996/ according to my friend who wrote one of the competitors to Shrinker.
I don't know... I looked at its index on amazon.com, and it had no reference to LdrAccessResource. So I suspect this book gives no information about the undocumented aspects of Windows, and probably regurgitates (like so many other API books) the online documentation.
Nebbett's book is very good and almost unique as a reference on the specific area it covers (the API provided to user-mode by the NT kernel) but its focus is also very narrow and since LdrAccessResource is implemented purely by ntdll.dll I wouldn't have expected it to be covered.
There's also a book called "Undocumented Windows NT". That would probably be the best hope of understanding LdrAccessResource, but without being able to flip through it, I don't know if they cover it.
I own this book and it doesn't have any information on it. There is however an implementation in ReactOS: http://mok.lvcm.com/cgi-bin/reactos/ros-cvs/reactos/lib/ntdll/ldr/utils.c
On Wed, Jan 02, 2002 at 03:28:22PM -0500, Robert Baruch wrote:
Hi Dan,
"Windows NT/2000 Native API Reference" by Gary Nebbett http://www.amazon.com/exec/obidos/ASIN/1578701996/ according to my friend who wrote one of the competitors to Shrinker.
I don't know... I looked at its index on amazon.com, and it had no reference to LdrAccessResource. So I suspect this book gives no information about the undocumented aspects of Windows, and probably regurgitates (like so many other API books) the online documentation.
There's also a book called "Undocumented Windows NT". That would probably be the best hope of understanding LdrAccessResource, but without being able to flip through it, I don't know if they cover it.
Actually I just ordered both books (and also "Inside COM+ Base Services"), so I'll have it in case anyone needs info. But it'll take some 4 to 8 weeks (ground shipping).
And about Windows NT/2000 Native API Reference: AFAIK it is said to be very good and to contain lots of undocumented API things. www.google.com ""Windows NT/2000 Native API Reference" review" should help a lot :-)
At least I know that review(s) are good, otherwise I wouldn't have bought it.
Of course, one could do a search on Google for something like ""Undocumented Windows NT" ebook" and look at the bottom of the page.
Of course, that person better have already ordered a copy! :)
- Ender
There's also a book called "Undocumented Windows NT". That would probably be the best hope of understanding LdrAccessResource, but without being able to flip through it, I don't know if they cover it.
--Rob