/*************************************************************************** * Copyright (C) 2011 * by Dimok * Modifications by xFede * Wiiflowized and heavily improved by Miigotu * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any * damages arising from the use of this software. * * Permission is granted to anyone to use this software for any * purpose, including commercial applications, and to alter it and * redistribute it freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you * must not claim that you wrote the original software. If you use * this software in a product, an acknowledgment in the product * documentation would be appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and * must not be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. ***************************************************************************/ #include <gctypes.h> #include <malloc.h> #include <cstdio> #include <cstring> #include "cios.hpp" #include "utils.h" #include "mem2.hpp" #include "fs.h" #define ARRAY_SIZE(a) (sizeof a / sizeof a[0]) static u32 allowedBases[] = { 37, 38, 53, 55, 56, 57, 58 }; static u32 boot2version = 0; bool cIOSInfo::neek2o(void) { if(!boot2version) ES_GetBoot2Version(&boot2version); return boot2version > 4 ? true : false; } /* Check if the cIOS is a D2X. */ bool cIOSInfo::D2X(u8 ios, u8 *base) { if(neek2o()) { *base = (u8)IOS_GetVersion(); return true; } iosinfo_t *info = GetInfo(ios); if(!info) return false; *base = (u8)info->baseios; MEM2_free(info); return true; } /* * Reads the ios info struct from the .app file. * @return pointer to iosinfo_t on success else NULL. The user is responsible for freeing the buffer. */ iosinfo_t *cIOSInfo::GetInfo(u8 ios) { u32 TMD_Length; if (ES_GetStoredTMDSize(TITLE_ID(1, ios), &TMD_Length) < 0) return NULL; signed_blob *TMD = (signed_blob*)MEM2_alloc(ALIGN32(TMD_Length)); if (TMD == NULL) return NULL; if (ES_GetStoredTMD(TITLE_ID(1, ios), TMD, TMD_Length) < 0) { MEM2_free(TMD); return NULL; } char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); sprintf(filepath, "/title/00000001/%08x/content/%08x.app", ios, *(u8 *)((u32)TMD+0x1E7)); MEM2_free(TMD); u32 size = 0; u8 *buffer = ISFS_GetFile((u8 *)filepath, &size, sizeof(iosinfo_t)); if(buffer == NULL || size == 0) return NULL; iosinfo_t *iosinfo = (iosinfo_t *)buffer; bool baseMatch = false; for(u8 i = 0; i < ARRAY_SIZE(allowedBases); i++) if(iosinfo->baseios == allowedBases[i]) { baseMatch = true; break; } if(iosinfo->magicword != 0x1ee7c105 /* Magic Word */ || iosinfo->magicversion != 1 /* Magic Version */ || iosinfo->version < 6 /* Version */ || !baseMatch /* Base */ || strncasecmp(iosinfo->name, "d2x", 3) != 0) /* Name */ { MEM2_free(buffer); return NULL; } return iosinfo; }