[Bug 10280] Oblivion: Horse Armor Crash

wine-bugs at winehq.org wine-bugs at winehq.org
Tue Jul 20 04:10:18 CDT 2010


Tim <tccowper at yahoo.com.au> changed:

           What    |Removed                     |Added
                 CC|                            |tccowper at yahoo.com.au

--- Comment #34 from Tim <tccowper at yahoo.com.au>  2010-07-20 04:10:17 ---
Apologies in advance if this comment is a bit lengthy.  I have investigated
further, testing with Oblivion on my machine and can clarify a bit further:

1.  While the player is riding a horse with armour, Oblivion plays a number of
sound files.  One of these,
'data\sound\fx\npc\horse\foot\armor\npc_horse_foot_armor_01.wav', causes the

2.  As with the other sound files, the code path runs through mmio.c:

    (a)  the file is opened for reading via a call to
0x33f11c, 00010000, ansi) - this function is documented at

    (b) a custom I/O procedure is installed on the fly with a FOURCC code of "
WAV" via a call to MMIO_InstallIOProc(00564157, 0x6aaaa0, 00010000, ansi) - see

    (c) an internal buffer of 8192 bytes is allocated via a call to
MMIO_SetBuffer(0x5c5f420 (nil) 8192 0) - see
http://msdn.microsoft.com/en-us/library/dd757338%28VS.85%29.aspx; and

    (d) a call is then made to descend into the parent chunk of the file via
mmioDescend(0x37, 0x33f0c0, (nil), 0000) - see

3.  The actual crash occurs in the mmioDescend function when the code attempts
to make the following TRACE call, resulting in a buffer overflow
("wine_dbg_vprintf: debugstr buffer overflow"):

    TRACE("ckid=%4.4s fcc=%4.4s cksize=%08X !\n",(LPCSTR)&lpck->ckid, srchType
? (LPCSTR)&lpck->fccType:"<na>",lpck->cksize);

After separating this statement into its individual elements, recompiling and
doing another trace, we can be more specific and say that the crash occurs when
the attempt is made to cast the FOURCC &lpck->ckid as a string pointer then
pass this to TRACE to print, i.e. the following is what calls the crash:

    TRACE("ckid=%4.4s\n", (LPCSTR)&lpck->ckid);

At the time this call is made the value of lpck->ckid is 9FFEA1FE.

The FOURCC datatype
(http://msdn.microsoft.com/en-us/library/dd375802%28VS.85%29.aspx) consists of
4 bytes, 1 for each character.  There is no null-terminating byte, but as Eric
points out, this should not be a problem as the %4.4s format specifier in the
TRACE call should only print four characters.  A minor niggle with this
approach is that it does not respect byte order (assumes little endian), but
that's not the concern here.

What then is tripping the buffer overflow assertion in wine_dbg_vprintf and
causing the crash?  I don't know yet.  Could there be a bug in the
wine_dbg_printf function itself?

In any case, and somewhat oddly, if I include a standard function to convert
FOURCC codes into null terminated strings (also respecting byte order), then
feed these into the TRACE calls, there is no crash.

I have no idea why, but at least it's a workaround for this bug.  I've attached
a patch, along with a modified form of mmio.c and the trace it produces, which
shows the two approaches running side by side.

Another more simple way to work around this if you don't care about receiving
the mmio debug info is to just comment out or delete all the TRACE calls in the
mmioDescend function of mmio.c, recompile wine and run Oblivion with that.

Hope this helps someone, and thanks again to the Wine team for their amazing
effort in getting complex games like this to run on Linux.

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