[Bug 27431] New: GetModuleFileNameW behaves unexpectedly when applications use a hardcoded hmodule=0x10000000
wine-bugs at winehq.org
wine-bugs at winehq.org
Thu Jun 9 07:27:15 CDT 2011
http://bugs.winehq.org/show_bug.cgi?id=27431
Summary: GetModuleFileNameW behaves unexpectedly when
applications use a hardcoded hmodule=0x10000000
Product: Wine
Version: unspecified
Platform: x86
OS/Version: Linux
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: kernel32
AssignedTo: wine-bugs at winehq.org
ReportedBy: rswarbrick at gmail.com
Created an attachment (id=35079)
--> (http://bugs.winehq.org/attachment.cgi?id=35079)
Log file as described in the report
SUMMARY:
========
Some code stupidly assumes that the hModule parameter describing the current
exe is always 0x10000000. On my system, at least, this isn't true. The software
then fails to work properly when it calls GetModuleFileName.
WHAT I FOUND / TO REPRODUCE:
============================
I'm trying to get the Onzo energy meter software [1] working and was confused
by messages like:
12:55:57: Debug: src/helpers.cpp(140): 'CreateActCtx' failed with error
0x0000007b (no more data available).
appearing on the stderr. It turns out that this is a wxPython message from a
failing call to CreateActCtx. The Onzo software is closed-source, but the code
in helpers.cpp that's calling CreateActCtx is probably what you get from
downloading something at [2]. In particular, it might well be the following:
static ULONG_PTR wxPySetActivationContext()
{
OSVERSIONINFO info;
wxZeroMemory(info);
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&info);
if (info.dwMajorVersion < 5)
return 0;
ULONG_PTR cookie = 0;
HANDLE h;
ACTCTX actctx;
TCHAR modulename[MAX_PATH];
GetModuleFileName(wxGetInstance(), modulename, MAX_PATH);
wxZeroMemory(actctx);
actctx.cbSize = sizeof(actctx);
actctx.lpSource = modulename;
actctx.lpResourceName = MAKEINTRESOURCE(2);
actctx.hModule = wxGetInstance();
actctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID |
ACTCTX_FLAG_RESOURCE_NAME_VALID;
h = CreateActCtx(&actctx);
if (h == INVALID_HANDLE_VALUE) {
wxLogLastError(wxT("CreateActCtx"));
return 0;
}
if (! ActivateActCtx(h, &cookie))
wxLogLastError(wxT("ActivateActCtx"));
return cookie;
}
After staring at debug logs for a bit, I realised that GetModuleFileName was
storing "" into modulename and returning 0. Note the bullet-proof code in
wxPython checking whether this happens...
Anyway, I then instrumented GetModuleFileName to find out what was going on (in
a rather low-tech way) adding a line
fprintf (stderr, "hmodule = %p; lpFN = %p; size = %d\n",
hModule, lpFileName, size);
near the start of the function and, once I'd realised that it was
LdrFindEntryForAddress that failed, also printing out a line of the form
fprintf (stderr, "nts = %x\n", nts);
just after it was called. The resulting debug log included lines looking like
this:
hmodule = 0x10000000; lpFN = 0x32daa0; size = 260
and it seems that wxGetInstance() is stupidly returning 0x10000000, which I
recognise from my 1990's Windows-using days and think is what you always used
to get, so maybe it's hardcoded somewhere. This is presumably either in
wxPython or in Onzo's code (the wxGetInstance() basically just returns the
value of a global variable that can be changed by wxSetInstance(), I think).
I'm going to attach a log that I created using this slightly-instrumented wine
build with the command
WINEDEBUG=+actctx,+file,+module /opt/wine/bin/wine onzo_uploader.exe 2>~/LOG
The lines I'm talking about are just above line 13630. The extra "Address
ranges searched" lines come from slightly instrumenting LdrFindEntryForAddress:
NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod)
{
PLIST_ENTRY mark, entry;
PLDR_MODULE mod;
fprintf (stderr, "Address ranges searched:\n");
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
{
mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
fprintf (stderr, " %p -> %p\n",
mod->BaseAddress,
mod->BaseAddress + mod->SizeOfImage);
...}}
which I did to check my guess was right about the base address being nonsense.
IDEAS FOR FIXING
================
I'm not sure what the correct way to go about fixing this is. I suppose one
thing is to check that this really is due to Onzo/wxPython doing something
stupid rather than Wine telling their software an incorrect base address
somewhere else. I'm not quite sure how to go about doing that.
If it is just a hard-coding that actually works on Windows (I presume that
Windows's ASLR doesn't mess it up?), maybe LdrFindEntryForAddress needs to
hardcode its answer for 0x10000000? But that's really really horrible...
Ideas??
Rupert
[1] http://download.sse.co.uk/OnzoDownloader/onzo_uploader_latest.msi
[2] http://www.wxpython.org/download.php
--
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.
More information about the wine-bugs
mailing list