FAQ: Chocobo races crash under NT/2000/XP (technical)

  • Thread starter Thread starter jedwin
  • Start date Start date
Status
Not open for further replies.
J

jedwin

Guest
Hey, so, I've tracked down the problem with Chocobo races under NT/2000/XP.  The problem looks to me like a NULL pointer dereference.  Specifically, they are doing:

Code: [Select]
Code:
mov ecx,  dword ptr [0e626d8h]mov dx, word ptr [eax + ecx + 0186b8h]

There are no other accesses to the variable at 0e626d8h, which essentially, since it is in the uninitialized data segment, means that it is a NULL pointer.  Under Windows 95/98, for no apparent reason, the pages corresponding to the addresses from 0x10000-0x20000 are mapped to something which looks to me like 16-bit code.  So, since the offset puts it safely into that region, it doesn't crash.  Now, it look like maybe this means that it has a bug under Windows 9x, but since I don't know how this value should be set, I couldn't fix it to correctly set this value.  But, under the assumption that the values that are getting pulled in are just garbage (which again, appears to hold under Windows 9x), I did the next best thing.  I changed the 0x186b8 to a value that puts it inside the FF7 executable itself, so that it still has some values there to read.

I'm not sure of the best way to distribute information on this patch, but if anybody cares to make this change on their own and try it out, the following instructions should suffice:

First off, copy ff7.exe to ff7.bak or whatever.
Now, I'm using an unpatched FF7 executable plucked from the Eidos Platinum Collection version of FF7.  The file size is 5820416, crc32 is E79D5195, and md5 sum is e1a6875b37540d616d34f14102d9c2fc.  If you have the same executable that I do, the change you need to make is at offset 3641e6, otherwise, you'll have to search for the right bytes to change.  So, now, open up ff7.exe in your favorite hex editor, and find the bytes Code: [Select]
Code:
b8 86 01 00
.  Again, if you have the same version of the executable that I do, you will find these bytes at 0x3641e6 from the beginning of the file.  Change them to Code: [Select]
Code:
00 00 50 00
.  That is sufficient to get the chocobo races working on my machine.  (Note that there may be other difficulties associated with running FF7 under Windows NT/2K/XP, though many of those are solved by the Application Compatibility Toolkit from Microsoft.)
 
nice work.... trying it now :)

works.... very well. thank you :)
[edited] 249 2002-04-21 02:40
 
WA HEY!!  I'm about to try this.  If it works... that'd be really cool.

I'm sure someone could develop a patch that does the hex editing automatically for me / everyone else to give to their less computer literate friends who don't know how to dig around in a hex editor?

[Edit] Um heh, does anyone have a save file I can try it on?  If you don't wanna post a URL, you can always e-mail it to me at [email protected] (it's small), but I bet some other people might need one to try this fix.

Oh yeah, if this works, there's no reason for me to keep my '98 installation around anymore (I only had it for CD burning, DOS games, and FF7... CD burning works now in XP with ECDC 5.1, DOS games work in Virtual PC, and FF7 should now work native in XP...).
[edited] 44 2002-04-21 02:34
 
I'm sure someone could develop a patch that does the hex editing automatically for me / everyone else to give to their less computer literate friends who don't know how to dig around in a hex editor?

Yeah, I was wondering about some standard way of distributing binary patches.  I'm aware of a few tools that handle diffs for binary files, but none of them are very ... consumer oriented.  Dunno.
 
Nice work.

The reason why it doesn't crash under Windows 95/98 is the OS's Windows 3.1 heritage -- all processes must have a DOS task block, and the entire DOS memory arena from 10000-FFFFF is mapped for read/write access to everyone for speed.  The data being read under 9x is almost certainly not correct.  If the FF7 programmer hadn't used such an insanely large structure, the access would have fallen into 00000-0FFFFF and would have crashed even under 9x.
 
Hey, impressive.

jedwin: If you need to distribute a patch-type-thingy, you could wrap it up as a Cetra patch (blatent plug!). It'll do the basic things like backing up the main EXE first, and checking that the data in the position is correct before modifying it ... just a thought ;)
 
jedwin: If you need to distribute a patch-type-thingy, you could wrap it up as a Cetra patch (blatent plug!). It'll do the basic things like backing up the main EXE first, and checking that the data in the position is correct before modifying it ... just a thought ;)

Sure.  How would one go about doing this?  Quick web search didn't turn up much on how to create a Cetra patch.
 
Erm, it wouldn't, no. After all, it's a program I wrote, so it's not exactly wide spread ;)

The only reason I suggest it is that it has patches to do things like enable 32-bit colour or windowed mode in FF7; so your patch would make a nice addition to the collection :D

I'll email you with details on how to make the file.
 
And right after fice said:

...unless, of course, it's an problem with the main EXE. In which case you'd have to patch the main program file, which would be near-impossible.

...on another thread.

Heh heh.  It definately works with the 1.02 or whatever version of the .exe with the NVidia patch.

chocobo.jpg

[edited] 44 2002-04-21 18:14
 
Heh, I didn't say it was *totally* impossible ;)

Came in good time too, I upgraded to Win2K myself this morning. Admittedly only because I had a spare Win98 box for games if needs be, but it'll still be good to play FF7 on my main box ;)
 
Not that I'm trying to bash this feat (I think it's great work), but some conclusions were incorrect. Even though 0xE626D8 is part of the uninitialized data segment, that doesn't necessarily make it a NULL pointer. The fact that no instructions reference this address means nothing either, since data is most likely written in large chunks (most likely the entire large structure at once), so the reference would be found much earlier in the address space. Still, someone messed up bigtime when dealing with this struct, so in effect we have a NULL pointer anyway. Right conclusion, different route.

Still, good job at fixing it.
 
On 2002-04-21 17:59, Qhimm wrote:
Not that I'm trying to bash this feat (I think it's great work), but some conclusions were incorrect. Even though 0xE626D8 is part of the uninitialized data segment, that doesn't necessarily make it a NULL pointer. The fact that no instructions reference this address means nothing either, since data is most likely written in large chunks (most likely the entire large structure at once), so the reference would be found much earlier in the address space. Still, someone messed up bigtime when dealing with this struct, so in effect we have a NULL pointer anyway. Right conclusion, different route.

Ahh, except running this under Windows 98, setting a memory breakpoint on that address in Softice indicates that that variable is not set before it is used.  I am fully aware that it is common to do things like:

Code: [Select]
Code:
mov edx, offset foomov [edx+1234h], bar

but Softice doesn't lie.  :)
 
Un-freakin-believeable!

Here we are, complaining or hearing complaints about this crash, and the thing gets solved in a week after someone finally decides to do something about it.  Congratulations, you get the Nobel Peace Prize for stopping a MicroSoft product (WinXP, in this case) from crashing!  What are ya gonna do next?! :naughty:

As for distributing the answer as a patch.....What about Dag's patchmaker program?  The difference engine it seems to use might work well for this kinda thing.....
[edited] 239 2002-04-21 23:33
 
On 2002-04-21 18:32, Goku7 wrote:
As for distributing the answer as a patch.....What about Dag's patchmaker program?  The difference engine it seems to use might work well for this kinda thing.....

Ok.  It sounds like it might be better to integrate it into Cetra, but until I hear back from Ficedula on how to do that, I've put together a patch using Dag's patchmaker.  You can snag it from http://www.ugcs.caltech.edu/~jedwin/ff7/ff7-patch.exe.
 
Oh yeah, by the way.....

On 2002-04-20 21:04, jedwin wrote:
There are no other accesses to the variable at 0e626d8h, which essentially, since it is in the uninitialized data segment, means that it is a NULL pointer. Under Windows 95/98, for no apparent reason, the pages corresponding to the addresses from 0x10000-0x20000 are mapped to something which looks to me like 16-bit code. So, since the offset puts it safely into that region, it doesn't crash.

It sounds to me that it's pure luck that Win9x operated in such a way to that it didn't fall into that danger zone and crash.  Judging from your explaination, it seems that the programmer designed it to crash on purpose.....
 
Well, it could be just a programming error that no one caught (after all... it didn't cause any problems).

I remember reading about something like this, for a SNES game (Japanese).  I can't remember what the game was called though.  It was about robots or something.  Anyway, when the game entered a battle, it called on some invalid memory thing, which for some reason, just by chance, worked on a Super Famicom but was causing some emulators to crash.

ANYWAY

I really didn't think anyone would ever figure out / solve the FF7 / Win2K problem.  But then this guy, jedwin, shows up and is like "I'm gonna try and fix it" and then like the next day, he's like, "I figured it out!"

Heh.  I'm very impressed.  Thanks a ton.  Maybe you can help us figure out some other stuff :-p
 
AMAZING, I could definately use this for my Win2K.  Thank you so much jedwin.  I think that the remake project is attracting really talented people.   With people like jedwin, Shinra Inc, and phaeron, the remake will definately progress faster.  :D

-vvalentine
[edited] 213 2002-04-22 04:11
 
Well, I just downloaded and installed the patch.  (came at a good time for me, I'm playing through FF7 again, and I was just up to the part where Barret fights Dyne.)  I would like to say, I've successfully made it through the Chocobo races in Windows XP Professional.

Great work, Jedwin, you're truly amazing.  You've done what Squaresoft and Eidos wouldn't.
 
Ahh, except running this under Windows 98, setting a memory breakpoint on that address in Softice indicates that that variable is not set before it is used.  I am fully aware that it is common to do things like:

Code: [Select]
Code:
mov edx, offset foomov [edx+1234h], bar

but Softice doesn't lie.  :)

True, but what I was referring to was this type of reference:

Code: [Select]
Code:
mov esi, offset srcmov edi, offset destmov ecx, somesizerep stosb

Where src is an offset say 100 bytes before the offset in question. In this case, disassemblers and debuggers (IDA, softice etc.) pick up the operand reference to src, but a breakpoint does not catch the actual writings to the other offsets affected.

I find it interesting that you could fix it simply by changing the offset, though. That would mean the read data can't exactly be critical to the operation of the minigame...
 
Status
Not open for further replies.
Back
Top