nesdev.com
http://forums.nesdev.com/

Signatures in iNES headers
http://forums.nesdev.com/viewtopic.php?f=3&t=15529
Page 1 of 1

Author:  zeroone [ Sun Feb 12, 2017 4:19 pm ]
Post subject:  Signatures in iNES headers

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?

Author:  Zepper [ Sun Feb 12, 2017 4:32 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  lidnariq [ Sun Feb 12, 2017 4:35 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  zeroone [ Sun Feb 12, 2017 4:42 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  Dwedit [ Sun Feb 12, 2017 5:58 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  lidnariq [ Sun Feb 12, 2017 6:10 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  zeroone [ Sun Feb 12, 2017 7:00 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  lidnariq [ Sun Feb 12, 2017 7:10 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Author:  zeroone [ Sun Feb 12, 2017 7:28 pm ]
Post subject:  Re: Signatures in iNES headers

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;
          }
        }
      }
    }

Author:  Quietust [ Sun Feb 12, 2017 8:18 pm ]
Post subject:  Re: Signatures in iNES headers

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.

Page 1 of 1 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/