mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
52 lines
1.7 KiB
C
52 lines
1.7 KiB
C
|
#include "gba.h"
|
||
|
#include "sha.h"
|
||
|
#include "sdmmc.h"
|
||
|
|
||
|
#define AGBLOGO_SHA256 \
|
||
|
0x08, 0xA0, 0x15, 0x3C, 0xFD, 0x6B, 0x0E, 0xA5, 0x4B, 0x93, 0x8F, 0x7D, 0x20, 0x99, 0x33, 0xFA, \
|
||
|
0x84, 0x9D, 0xA0, 0xD5, 0x6F, 0x5A, 0x34, 0xC4, 0x81, 0x06, 0x0C, 0x9F, 0xF2, 0xFA, 0xD8, 0x18
|
||
|
|
||
|
u32 ValidateAgbSaveHeader(AgbSaveHeader* header) {
|
||
|
u8 magic[] = { AGBSAVE_MAGIC };
|
||
|
|
||
|
// basic checks
|
||
|
if ((memcmp(header->magic, magic, sizeof(magic)) != 0) ||
|
||
|
(header->unknown0 != 1) || (header->save_start != 0x200) ||
|
||
|
(header->save_size > AGBSAVE_MAX_SSIZE) || !(GBASAVE_VALID(header->save_size)))
|
||
|
return 1;
|
||
|
|
||
|
// reserved area checks
|
||
|
for (u32 i = 0; i < sizeof(header->reserved0); i++) if (header->reserved0[i] != 0xFF) return 1;
|
||
|
for (u32 i = 0; i < sizeof(header->reserved1); i++) if (header->reserved1[i] != 0xFF) return 1;
|
||
|
for (u32 i = 0; i < sizeof(header->reserved2); i++) if (header->reserved2[i] != 0xFF) return 1;
|
||
|
for (u32 i = 0; i < sizeof(header->reserved3); i++) if (header->reserved3[i] != 0xFF) return 1;
|
||
|
|
||
|
// all fine if arriving here
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// http://problemkaputt.de/gbatek.htm#gbacartridgeheader
|
||
|
u32 ValidateAgbHeader(AgbHeader* agb) {
|
||
|
const u8 logo_sha[0x20] = { AGBLOGO_SHA256 };
|
||
|
u8 logo[0x9C];
|
||
|
|
||
|
// check fixed value
|
||
|
if (agb->fixed != 0x96) return 1;
|
||
|
|
||
|
// header checksum
|
||
|
u8* hdr = (u8*) agb;
|
||
|
u8 checksum = 0x00 - 0x19;
|
||
|
for (u32 i = 0xA0; i < 0xBD; i++)
|
||
|
checksum -= hdr[i];
|
||
|
if (agb->checksum != checksum) return 1;
|
||
|
|
||
|
// logo SHA check
|
||
|
memcpy(logo, agb->logo, 0x9C);
|
||
|
logo[0x98] &= ~0x84;
|
||
|
logo[0x9A] &= ~0x03;
|
||
|
if (sha_cmp(logo_sha, logo, 0x9C, SHA256_MODE) != 0)
|
||
|
return 1;
|
||
|
|
||
|
return 0;
|
||
|
}
|