From 40d4d80c255c9043e4692d05542ddaa8182de90b Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 18 Mar 2016 00:36:55 +0000 Subject: [PATCH] (winport) fix: #1543 fex identifying ROMs as compressed archives, causing crash (added a method to attempt to ID any kind of NDS rom before even passing it to FEX) --- desmume/src/utils/decrypt/header.cpp | 45 ++++++++++++++++++++++++---- desmume/src/utils/decrypt/header.h | 3 ++ desmume/src/windows/OpenArchive.cpp | 10 +++++++ 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/desmume/src/utils/decrypt/header.cpp b/desmume/src/utils/decrypt/header.cpp index 5fb07011f..2d890c29d 100644 --- a/desmume/src/utils/decrypt/header.cpp +++ b/desmume/src/utils/decrypt/header.cpp @@ -26,7 +26,7 @@ //#include "ndstool.h" //#include "banner.h" //#include "sha1.h" -//#include "crc.h" +#include "crc.h" //#include "bigint.h" //#include "arm7_sha1_homebrew.h" //#include "arm7_sha1_nintendo.h" @@ -58,10 +58,22 @@ ///* // * CalcLogoCRC // */ -//unsigned short CalcLogoCRC(Header &header) -//{ -// return CalcCrc16((unsigned char *)&header + 0xC0, 156); -//} + +extern unsigned short crc16tab[]; +static short MyCalcCrc(unsigned char *data, unsigned int length) +{ + short crc = (short)~0; + for (unsigned int i=0; i> 8) ^ crc16tab[(crc ^ data[i]) & 0xFF]; + } + return crc; +} + +unsigned short CalcLogoCRC(Header &header) +{ + return MyCalcCrc((unsigned char *)&header + 0xC0, 156); +} // /* * DetectRomType @@ -656,3 +668,26 @@ int DetectRomType(const Header &header, char *secure) // // fclose(fNDS); //} + + +bool CheckLogoCRC(void* bytes512) +{ + Header* header = (Header*)bytes512; + unsigned short crc = CalcLogoCRC(*header); //this isn't working, don't know why + return header->logo_crc == crc; +} + +bool DetectAnyRom(void* bytes512) +{ + //if(CheckLogoCRC(bytes512)) return true; //this isn't working + + //use other heuristics + Header* header = (Header*)bytes512; + //at least we have 5 bytes to ID here, not bad + if(header->rom_header_size != 0x4000) return false; + if(header->logo[0] != 0x24) return false; + if(header->logo_crc != 0xCF56) return false; + //if(header->zero[0] != 0) return false; //not sure if some weird demos will be packing data in here + + return true; +} \ No newline at end of file diff --git a/desmume/src/utils/decrypt/header.h b/desmume/src/utils/decrypt/header.h index 5009673c9..89b93899a 100644 --- a/desmume/src/utils/decrypt/header.h +++ b/desmume/src/utils/decrypt/header.h @@ -124,6 +124,9 @@ int HashAndCompareWithList(char *filename, unsigned char sha1[]); int DetectRomType(const Header& header, char* secure); unsigned short CalcSecureAreaCRC(bool encrypt); +bool CheckLogoCRC(void* bytes512); +bool DetectAnyRom(void* bytes512); + #define ROMTYPE_HOMEBREW 0 #define ROMTYPE_MULTIBOOT 1 #define ROMTYPE_NDSDUMPED 2 // decrypted secure area diff --git a/desmume/src/windows/OpenArchive.cpp b/desmume/src/windows/OpenArchive.cpp index b81865f02..8cf939175 100644 --- a/desmume/src/windows/OpenArchive.cpp +++ b/desmume/src/windows/OpenArchive.cpp @@ -30,6 +30,7 @@ #include "resource.h" #include "main.h" +#include "utils/decrypt/header.h" static char Str_Tmp[1024]; @@ -414,6 +415,15 @@ bool ObtainFile(const char* Name, char *const & LogicalName, char *const & Physi while(true) { + //before sending to FEX, see if we're known to be an NDS file + //(this will stop games beginning with the name ZOO from being mis-recognized as a zoo file) + FILE* inf = fopen(PhysicalName,"rb"); + u8 bytes512[512]; + bool got512 = fread(bytes512,1,512,inf)==512; + fclose(inf); + if(got512 && DetectAnyRom(bytes512)) + return true; + ArchiveFile archive (PhysicalName); if(!archive.IsCompressed()) {