It is currently Mon Dec 11, 2017 9:41 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sun Feb 12, 2017 4:19 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Snake's Revenge.7z <Snake's Revenge (U) [t4].nes> from GoodNES3.23b has the following header:

Code:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
4E 45 53 1A 10 00 23 64 65 6D 69 66 6F 72 63 65  NES...#demiforce


Usually, when signatures are present, they begin in byte 10; bytes 7, 8 and 9 have significant meaning. For instance, the upper nibble of the mapper number is in byte 7.

This can be resolved by hashing ROMs. But, this particular ROM is not present in NstDatabase.xml 1.47 or NesCarts (2012-10-22).xml. Yet, most emulators correctly recognize it as a Mapper 2 ROM, as opposed to the invalid Mapper 98. If it is not being hashed, how are emulators dealing with this signature issue on load?


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 4:32 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3076
Location: Brazil
This is the USA dump profile: http://bootgod.dyndns.org:7777/profile.php?id=738

You're asking something about "how do I load a bad dump within a dirty header"? I have a CRC32 check for a few special cases; other than that, my emulator warns about a dirty header. Plus, it's NOT mapper 2, but MMC1.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 4:35 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6509
Location: Seattle
Nestopia:
Checks for the NES2.0 signature
If it's NOT present, checks if any of the last four bytes are nonzero
If they are, it clears the last nine bytes.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 4:42 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
lidnariq wrote:
Nestopia:
Checks for the NES2.0 signature
If it's NOT present, checks if any of the last four bytes are nonzero
If they are, it clears the last nine bytes.


That's a good strategy. The last five bytes should actually be 0. Why does it use four?

Edit: Here's Nestopia's loading code:

Code:
         setup.version = ((header[7] & 0xCU) == 0x8 ? 2 : 0);

         if (!setup.version)
         {
            for (uint i=10; i < 16; ++i)
            {
               if (header[i])
               {
                  header[7] = 0;
                  header[8] = 0;
                  header[9] = 0;
                  result = RESULT_WARN_BAD_FILE_HEADER;
                  break;
               }
            }
         }


Byte 7 is still required to do the NES 2.0 check; so, it's not a flawless strategy. And, it clears 7--9, when any of 10--15 are nonzero.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 5:58 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3968
Here we have 'd' (0x64) as header byte 0x07. This would add 0x60 to the mapper number, and put the "NES 2.0" flag at 01, which is invalid. (only 10 and 00 are valid)
The header from byte 0x07 on is obviously invalid, so replace it with zeroes, and clamp the mapper number to 0-15.

Even if the NES 2.0 flag was set to 10, there are other quick rejection tests. If PC10 and VS are set at the same time, that's invalid. If there's anything in the last two bytes (0x0E or 0x0F), you can reject all header bytes from 0x07 on as well.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 6:10 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6509
Location: Seattle
zeroone wrote:
Byte 7 is still required to do the NES 2.0 check; so, it's not a flawless strategy
Kevtris specifically chose the signature he did for NES2.0 because it doesn't collide with any known dirty headers.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 7:00 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
Dwedit wrote:
Here we have 'd' (0x64) as header byte 0x07. This would add 0x60 to the mapper number, and put the "NES 2.0" flag at 01, which is invalid. (only 10 and 00 are valid)
The header from byte 0x07 on is obviously invalid, so replace it with zeroes, and clamp the mapper number to 0-15.

Even if the NES 2.0 flag was set to 10, there are other quick rejection tests. If PC10 and VS are set at the same time, that's invalid. If there's anything in the last two bytes (0x0E or 0x0F), you can reject all header bytes from 0x07 on as well.


According to the wiki:

Code:
If equal to 2, flags 8-15 are in NES 2.0 format


It does not explicitly say that 0 indicates iNES; rather, it suggests that anything other than 2 is iNES. But, I can add a check for 2 or 0.

I also like the PC10-VS coincidence test.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 7:10 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6509
Location: Seattle
zeroone wrote:
It does not explicitly say that 0 indicates iNES; rather, it suggests that anything other than 2 is iNES. But, I can add a check for 2 or 0.
byte7&$C == 0 is not sufficient; I've certainly found other headers with bad contents in the 8th and later bytes.


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 7:28 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 750
Location: New York, NY
lidnariq wrote:
byte7&$C == 0 is not sufficient; I've certainly found other headers with bad contents in the 8th and later bytes.


I meant to do that test in addition to the others. Something like this:

Code:
    nes20Format = (header[7] & 0x0C) == 0x08 && (header[7] & 0x03) != 0x03;
   
    if (!nes20Format) {
      if ((header[7] & 0x0C) != 0x00 || (header[7] & 0x03) == 0x03) {
        header[7] = header[8] = header[9] = 0x00;
      } else {
        for(int i = 10; i < 16; i++) {
          if (header[i] != 0x00) {
            header[7] = header[8] = header[9] = 0x00;
            break;
          }
        }
      }
    }


Top
 Profile  
 
PostPosted: Sun Feb 12, 2017 8:18 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1393
zeroone wrote:
According to the wiki:

Code:
If equal to 2, flags 8-15 are in NES 2.0 format


It does not explicitly say that 0 indicates iNES; rather, it suggests that anything other than 2 is iNES. But, I can add a check for 2 or 0.

I seem to recall an older document stating that 00 meant "iNES", 10 meant "NES 2.0", 01 meant "DiskDude! corrupted header" (and apparently also "demiforce"), and 11 meant "reserved for future expansion" - it's possible that was lost during the transition to the wiki, or maybe it was just a discussion on IRC from over 10 years ago.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group