diff --git a/README.md b/README.md
index 227f320..8b6c48b 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ These short instructions apply to all users who have [boot9strap](https://github
You may now run GodMode9 via holding the X Button (or any other button you chose) at startup. See below for a list of stuff you can do with it.
-## Buttons in GodMode9 usage
+## Buttons in GodMode9
GodMode9 is designed to be intuitive, buttons leading to the results you'd expect. However, some stuff may not be obvious at first glance. So, here's a quick, incomplete rundown of what each button / button combo does.
* __ button__: The button is the 'confirm' / 'choose' button. It confirms prompts and selects entries in menus. In the main file view, it pulls up a submenu for files and opens directories (use on directories for a submenu, also including the invaluable title search). In the hexviewer, switches into edit mode.
* __ button__: The button is the 'cancel' / 'return' button. Use it to leave menus without action, hold it on file operations to cancel said file operations.
diff --git a/arm9/source/game/firm.c b/arm9/source/game/firm.c
index 663b9ed..7dd8b51 100644
--- a/arm9/source/game/firm.c
+++ b/arm9/source/game/firm.c
@@ -38,7 +38,7 @@ u32 GetFirmSize(FirmHeader* header) {
FirmSectionHeader* section = header->sections + i;
if (!section->size) continue;
if (section->offset < firm_size) return 0;
- if ((section->offset % 512) || (section->address % 16) || (section->size % 512)) return 0;
+ if ((section->offset % 512) || (section->size % 512)) return 0;
if ((header->entry_arm11 >= section->address) &&
(header->entry_arm11 < section->address + section->size))
section_arm11 = i;
@@ -79,8 +79,10 @@ u32 ValidateFirm(void* firm, u32 firm_size, bool installable) {
if ((firm_size < sizeof(FirmHeader)) || (ValidateFirmHeader(header, firm_size) != 0))
return 1;
- // check for boot9strap magic
+ // overrides for b9s / superhax fb3ds firms
bool b9s_fix = installable && (memcmp(&(header->reserved0[0x2D]), "B9S", 3) == 0);
+ bool fb3ds_fix = installable && (header->sections[1].size == 0x200) &&
+ (header->sections[1].address == 0x07FFFE8C);
// hash verify all available sections and check load address
for (u32 i = 0; i < 4; i++) {
@@ -92,7 +94,7 @@ u32 ValidateFirm(void* firm, u32 firm_size, bool installable) {
if (!section->size) continue;
if (sha_cmp(section->hash, ((u8*) firm) + section->offset, section->size, SHA256_MODE) != 0)
return 1;
- bool is_whitelisted = (b9s_fix && (i == 3)); // don't check last section in b9s
+ bool is_whitelisted = (b9s_fix && (i == 3)) || (fb3ds_fix && (i == 1)); // b9s / fb3ds overrides
for (u32 a = 0; (a < whitelist_size) && !is_whitelisted; a++) {
if ((section->address >= whitelist[2*a]) && (section->address + section->size <= whitelist[(2*a)+1]))
is_whitelisted = true;
diff --git a/arm9/source/virtual/vgame.c b/arm9/source/virtual/vgame.c
index af823fa..20c2348 100644
--- a/arm9/source/virtual/vgame.c
+++ b/arm9/source/virtual/vgame.c
@@ -614,7 +614,7 @@ bool BuildVGameFirmDir(void) {
u8* buffer = (u8*) malloc(section->size);
if (buffer) {
if (ReadGameImageBytes(buffer, section->offset, section->size) != 0) break;
- for (u32 s = 0; (s < section->size - 0x400) && (!offset_p9); s += 0x10) {
+ for (u32 s = 0; (s + 0x400 < section->size) && (!offset_p9); s += 0x10) {
if ((ValidateNcchHeader((NcchHeader*) (void*) (buffer + s)) == 0) &&
(ReadGameImageBytes((u8*) name, section->offset + s + 0x200, 8) == 0)) {
offset_p9 = section->offset + s;