mirror of
https://github.com/modmii/YAWM-ModMii-Edition.git
synced 2024-11-21 23:59:18 +01:00
(Hopefully) fix unsuspecting crashes when retaining Priiloader (#7)
* "memalign is busted apparently" * accidentally used ES_GetTMDView * "static u32 cid" - hero of time
This commit is contained in:
parent
b520bc7f88
commit
8c0269a8bc
@ -1,9 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fileops.h"
|
||||
|
||||
#include "malloc.h"
|
||||
|
||||
bool FSOPFileExists(const char* file)
|
||||
{
|
||||
@ -85,7 +84,7 @@ s32 FSOPReadOpenFile(FILE* fp, void* buffer, u32 offset, u32 length)
|
||||
|
||||
s32 FSOPReadOpenFileA(FILE* fp, void** buffer, u32 offset, u32 length)
|
||||
{
|
||||
*buffer = memalign(32, length);
|
||||
*buffer = memalign32(length);
|
||||
if (!*buffer)
|
||||
return -1;
|
||||
|
||||
|
11
source/malloc.h
Normal file
11
source/malloc.h
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void *memalign32(size_t size)
|
||||
{
|
||||
return aligned_alloc(0x20, (size + 0x1F) & ~0x1F);
|
||||
}
|
||||
|
||||
static inline void *memalign64(size_t size)
|
||||
{
|
||||
return aligned_alloc(0x40, (size + 0x3F) & ~0x3F);
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <ogcsys.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nand.h"
|
||||
#include "malloc.h"
|
||||
#include "fileops.h"
|
||||
|
||||
/* Buffer */
|
||||
@ -118,7 +118,7 @@ u8* NANDReadFromFile(const char* path, u32 offset, u32 length, u32* size)
|
||||
if (!length)
|
||||
length = IOS_Seek(fd, 0, SEEK_END);
|
||||
|
||||
u8* data = (u8*)memalign(0x40, length);
|
||||
u8* data = memalign64(length);
|
||||
if (!data)
|
||||
{
|
||||
*size = 0;
|
||||
@ -155,9 +155,10 @@ u8* NANDLoadFile(const char* path, u32* size)
|
||||
|
||||
s32 NANDWriteFileSafe(const char* path, u8* data, u32 size)
|
||||
{
|
||||
char tmpPath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(64);
|
||||
|
||||
NANDInitialize();
|
||||
|
||||
char* tmpPath = (char*)memalign(0x40, ISFS_MAXPATH);
|
||||
u32 i;
|
||||
|
||||
for (i = strlen(path); i > 0; --i)
|
||||
@ -175,43 +176,29 @@ s32 NANDWriteFileSafe(const char* path, u8* data, u32 size)
|
||||
ret = ISFS_CreateFile(tmpPath, 0, 3, 3, 3);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
free(tmpPath);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (ret < 0)
|
||||
{
|
||||
if (ret < 0)
|
||||
{
|
||||
free(tmpPath);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
s32 fd = IOS_Open(tmpPath, 2);
|
||||
if (fd < 0)
|
||||
{
|
||||
free(tmpPath);
|
||||
return fd;
|
||||
}
|
||||
|
||||
ret = IOS_Write(fd, data, size);
|
||||
|
||||
|
||||
IOS_Close(fd);
|
||||
if (ret != size)
|
||||
{
|
||||
free(tmpPath);
|
||||
return ret - 3;
|
||||
}
|
||||
|
||||
if (strcmp(tmpPath, path))
|
||||
ret = ISFS_Rename(tmpPath, path);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
free(tmpPath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
33
source/sys.c
33
source/sys.c
@ -1,9 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "sys.h"
|
||||
#include "malloc.h"
|
||||
#include "mload.h"
|
||||
#include "ehcmodule_elf.h"
|
||||
|
||||
@ -31,11 +31,11 @@ void __Sys_PowerCallback(void)
|
||||
|
||||
bool isIOSstub(u8 ios_number)
|
||||
{
|
||||
u32 tmd_size;
|
||||
u32 tmd_size = 0;
|
||||
tmd_view *ios_tmd;
|
||||
|
||||
|
||||
if((boot2version >= 5) && ( ios_number == 202 || ios_number == 222 || ios_number == 223 || ios_number == 224)) return true;
|
||||
if ((boot2version >= 5) && (ios_number == 202 || ios_number == 222 || ios_number == 223 || ios_number == 224))
|
||||
return true;
|
||||
|
||||
ES_GetTMDViewSize(0x0000000100000000ULL | ios_number, &tmd_size);
|
||||
if (!tmd_size)
|
||||
@ -44,7 +44,7 @@ bool isIOSstub(u8 ios_number)
|
||||
// gprintf("failed to get tmd for ios %d\n",ios_number);
|
||||
return true;
|
||||
}
|
||||
ios_tmd = (tmd_view *)memalign( 32, (tmd_size+31)&(~31) );
|
||||
ios_tmd = memalign32(tmd_size);
|
||||
if (!ios_tmd)
|
||||
{
|
||||
// gprintf("failed to mem align the TMD struct!\n");
|
||||
@ -62,8 +62,10 @@ bool isIOSstub(u8 ios_number)
|
||||
people/applications install an ios with a stub rev >_> ...*/
|
||||
u8 Version = ios_tmd->title_version;
|
||||
|
||||
if((boot2version >= 5) && (ios_number == 249 || ios_number == 250) && (Version < 18)) return true;
|
||||
if(( ios_number == 202 || ios_number == 222 || ios_number == 223 || ios_number == 224) && (Version < 4)) return true;
|
||||
if ((boot2version >= 5) && (ios_number == 249 || ios_number == 250) && (Version < 18))
|
||||
return true;
|
||||
if ((ios_number == 202 || ios_number == 222 || ios_number == 223 || ios_number == 224) && (Version < 4))
|
||||
return true;
|
||||
// version now contains the last 2 bytes. as said above, if this is 00, its a stub
|
||||
if (Version == 0)
|
||||
{
|
||||
@ -85,10 +87,10 @@ bool isIOSstub(u8 ios_number)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool loadIOS(int ios)
|
||||
{
|
||||
if(isIOSstub(ios)) return false;
|
||||
if (isIOSstub(ios))
|
||||
return false;
|
||||
mload_close();
|
||||
if (IOS_ReloadIOS(ios) >= 0)
|
||||
{
|
||||
@ -125,7 +127,8 @@ void Sys_Reboot(void)
|
||||
void Sys_Shutdown(void)
|
||||
{
|
||||
/* Poweroff console */
|
||||
if(CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE) {
|
||||
if (CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
/* Set LED mode */
|
||||
@ -135,7 +138,9 @@ void Sys_Shutdown(void)
|
||||
|
||||
/* Shutdown to idle */
|
||||
STM_ShutdownToIdle();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shutdown to standby */
|
||||
STM_ShutdownToStandby();
|
||||
}
|
||||
@ -158,7 +163,8 @@ void Sys_LoadMenu(void)
|
||||
}
|
||||
|
||||
/* Homebrew Channel stub */
|
||||
if (HBC == 1) {
|
||||
if (HBC == 1)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
/* Return to the Wii system menu */
|
||||
@ -183,7 +189,8 @@ s32 Sys_GetCerts(signed_blob **certs, u32 *len)
|
||||
IOS_Close(fd);
|
||||
|
||||
/* Set values */
|
||||
if (ret > 0) {
|
||||
if (ret > 0)
|
||||
{
|
||||
*certs = certificates;
|
||||
*len = sizeof(certificates);
|
||||
}
|
||||
|
@ -2,12 +2,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
|
||||
#include "sha1.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "malloc.h"
|
||||
|
||||
s32 Title_ZeroSignature(signed_blob *p_sig)
|
||||
{
|
||||
@ -79,7 +78,7 @@ s32 Title_GetList(u64 **outbuf, u32 *outlen)
|
||||
{
|
||||
u64 *titles = NULL;
|
||||
|
||||
u32 len, nb_titles;
|
||||
u32 nb_titles;
|
||||
s32 ret;
|
||||
|
||||
/* Get number of titles */
|
||||
@ -87,11 +86,9 @@ s32 Title_GetList(u64 **outbuf, u32 *outlen)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Calculate buffer lenght */
|
||||
len = round_up(sizeof(u64) * nb_titles, 32);
|
||||
|
||||
/* Allocate memory */
|
||||
titles = memalign(32, len);
|
||||
titles = memalign32(nb_titles * sizeof(u64));
|
||||
if (!titles)
|
||||
return -1;
|
||||
|
||||
@ -126,7 +123,7 @@ s32 Title_GetTicketViews(u64 tid, tikview **outbuf, u32 *outlen)
|
||||
return ret;
|
||||
|
||||
/* Allocate memory */
|
||||
views = (tikview *)memalign(32, sizeof(tikview) * nb_views);
|
||||
views = memalign32(sizeof(tikview) * nb_views);
|
||||
if (!views)
|
||||
return -1;
|
||||
|
||||
@ -161,7 +158,7 @@ s32 Title_GetTMD(u64 tid, signed_blob **outbuf, u32 *outlen)
|
||||
return ret;
|
||||
|
||||
/* Allocate memory */
|
||||
p_tmd = memalign(32, round_up(len, 32));
|
||||
p_tmd = memalign32(len);
|
||||
if (!p_tmd)
|
||||
return -1;
|
||||
|
||||
@ -290,7 +287,7 @@ s32 Title_GetIOSVersions(u8 **outbuf, u32 *outlen)
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
buffer = (u8 *)memalign(32, cnt);
|
||||
buffer = memalign32(cnt);
|
||||
if (!buffer) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
|
162
source/wad.c
162
source/wad.c
@ -1,6 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/pad.h>
|
||||
#include <unistd.h>
|
||||
@ -16,6 +15,7 @@
|
||||
#include "sha1.h"
|
||||
#include "menu.h"
|
||||
#include "iospatch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
// Turn upper and lower into a full title ID
|
||||
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
|
||||
@ -97,7 +97,7 @@ u64 get_title_ios(u64 title) {
|
||||
|
||||
// Check to see if title exists
|
||||
if (ES_GetDataDir(title, filepath) >= 0 ) {
|
||||
u32 tmd_size;
|
||||
u32 tmd_size = 0;
|
||||
static u8 tmd_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
ret = ES_GetStoredTMDSize(title, &tmd_size);
|
||||
@ -265,62 +265,86 @@ const char* GetSysMenuVersionString(u16 version)
|
||||
return VersionLookupTable[version % 32][version / 32];
|
||||
};
|
||||
|
||||
static char* GetTitleExec(u64 tId, bool tweaked)
|
||||
static u32 GetSysMenuBootContent(void)
|
||||
{
|
||||
u32 size;
|
||||
const u8 buffer[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
s32 ret;
|
||||
u32 cid = 0;
|
||||
u32 size = 0;
|
||||
signed_blob *s_tmd = NULL;
|
||||
|
||||
s32 ret = ES_GetStoredTMDSize(0x100000002LL, &size);
|
||||
signed_blob* tmdRaw = (signed_blob*)buffer;
|
||||
|
||||
ret = ES_GetStoredTMD(0x100000002LL, tmdRaw, size);
|
||||
if (ret < 0)
|
||||
ret = ES_GetStoredTMDSize(0x100000002LL, &size);
|
||||
if (!size)
|
||||
{
|
||||
printf("Error! ES_GetStoredTMDSize: Failed! (Error: %d)\n", ret);
|
||||
return NULL;
|
||||
printf("Error! ES_GetStoredTMDSize failed (ret=%i)\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmd* smTMD = SIGNATURE_PAYLOAD(tmdRaw);
|
||||
s_tmd = memalign32(size);
|
||||
if (!s_tmd)
|
||||
{
|
||||
printf("Error! Memory allocation failed!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* path = (char*)memalign(0x40, ISFS_MAXPATH);
|
||||
if (!path)
|
||||
return NULL;
|
||||
ret = ES_GetStoredTMD(0x100000002LL, (u8*)s_tmd, size);
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Error! ES_GetStoredTMD failed (ret=%i)\n", ret);
|
||||
free(s_tmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tweaked)
|
||||
sprintf(path, "/title/%08x/%08x/content/1%.7x.app", TITLE_UPPER(tId), TITLE_LOWER(tId), smTMD->contents[smTMD->boot_index].cid);
|
||||
else
|
||||
sprintf(path, "/title/%08x/%08x/content/%.8x.app", TITLE_UPPER(tId), TITLE_LOWER(tId), smTMD->contents[smTMD->boot_index].cid);
|
||||
tmd *p_tmd = SIGNATURE_PAYLOAD(s_tmd);
|
||||
|
||||
return path;
|
||||
for (int i = 0; i < p_tmd->num_contents; i++)
|
||||
{
|
||||
tmd_content* content = &p_tmd->contents[i];
|
||||
if (content->index == p_tmd->boot_index)
|
||||
{
|
||||
cid = content->cid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(s_tmd);
|
||||
if (!cid) printf("Error! Cannot find system menu boot content!\n");
|
||||
|
||||
return cid;
|
||||
}
|
||||
|
||||
bool GetSysMenuExecPath(char path[ISFS_MAXPATH], bool mainDOL)
|
||||
{
|
||||
u32 cid = GetSysMenuBootContent();
|
||||
if (!cid) return false;
|
||||
|
||||
if (mainDOL) cid |= 0x10000000;
|
||||
sprintf(path, "/title/00000001/00000002/content/%08x.app", cid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsPriiloaderInstalled()
|
||||
{
|
||||
char* path = GetTitleExec(0x100000002LL, true);
|
||||
if (!path)
|
||||
return false;
|
||||
char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20);
|
||||
|
||||
if (!GetSysMenuExecPath(path, true))
|
||||
return false;
|
||||
|
||||
u32 size = 0;
|
||||
NANDGetFileSize(path, &size);
|
||||
free(path);
|
||||
|
||||
if (size > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return (size > 0);
|
||||
}
|
||||
|
||||
static bool BackUpPriiloader()
|
||||
{
|
||||
char* path = GetTitleExec(0x100000002LL, false);
|
||||
if (!path)
|
||||
char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20);
|
||||
|
||||
if (!GetSysMenuExecPath(path, false))
|
||||
return false;
|
||||
|
||||
u32 size = 0;
|
||||
s32 ret = NANDBackUpFile(path, "/tmp/priiload.app", &size);
|
||||
free(path);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
printf("Error! NANDBackUpFile: Failed! (Error: %d)\n", ret);
|
||||
@ -334,23 +358,19 @@ static bool BackUpPriiloader()
|
||||
|
||||
static bool MoveMenu(bool restore)
|
||||
{
|
||||
char* srcPath = GetTitleExec(0x100000002LL, restore);
|
||||
if (!srcPath)
|
||||
ATTRIBUTE_ALIGN(0x20)
|
||||
char srcPath[ISFS_MAXPATH], dstPath[ISFS_MAXPATH];
|
||||
|
||||
if (!GetSysMenuBootContent())
|
||||
return false;
|
||||
|
||||
char* dstPath = GetTitleExec(0x100000002LL, !restore);
|
||||
if (!dstPath)
|
||||
{
|
||||
free(srcPath);
|
||||
return false;
|
||||
}
|
||||
GetSysMenuExecPath(srcPath, restore);
|
||||
GetSysMenuExecPath(dstPath, !restore);
|
||||
|
||||
u32 size = 0;
|
||||
s32 ret = NANDBackUpFile(srcPath, dstPath, &size);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
printf("Error! NANDBackUpFile: Failed! (Error: %d)\n", ret);
|
||||
return false;
|
||||
}
|
||||
@ -358,23 +378,19 @@ static bool MoveMenu(bool restore)
|
||||
u32 checkSize = 0;
|
||||
ret = NANDGetFileSize(dstPath, &checkSize);
|
||||
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
|
||||
return (checkSize == size);
|
||||
}
|
||||
|
||||
static bool RestorePriiloader()
|
||||
{
|
||||
char* dstPath = GetTitleExec(0x100000002LL, false);
|
||||
if (!dstPath)
|
||||
return false;
|
||||
char dstPath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20);
|
||||
|
||||
if (!GetSysMenuExecPath(dstPath, false));
|
||||
|
||||
u32 size = 0;
|
||||
s32 ret = NANDBackUpFile("/tmp/priiload.app", dstPath, &size);
|
||||
if (ret < 0)
|
||||
{
|
||||
free(dstPath);
|
||||
printf("Error! NANDBackUpFile: Failed! (Error: %d)\n", ret);
|
||||
return false;
|
||||
}
|
||||
@ -382,8 +398,6 @@ static bool RestorePriiloader()
|
||||
u32 checkSize = 0;
|
||||
ret = NANDGetFileSize(dstPath, &checkSize);
|
||||
|
||||
free(dstPath);
|
||||
|
||||
return (checkSize == size && checkSize == gPriiloaderSize);
|
||||
}
|
||||
|
||||
@ -453,56 +467,30 @@ static void CleanupPriiloaderLeftOvers(bool retain)
|
||||
|
||||
static bool CompareHashes(bool priiloader)
|
||||
{
|
||||
char* dstPath = NULL;
|
||||
char* srcPath = GetTitleExec(0x100000002LL, false);
|
||||
ATTRIBUTE_ALIGN(0x20)
|
||||
char srcPath[ISFS_MAXPATH], dstPath[ISFS_MAXPATH] = "/tmp/priiload.app";
|
||||
|
||||
if (!srcPath)
|
||||
if (!GetSysMenuExecPath(srcPath, false))
|
||||
return false;
|
||||
|
||||
if (priiloader)
|
||||
{
|
||||
dstPath = (char*)memalign(0x40, ISFS_MAXPATH);
|
||||
if (!dstPath)
|
||||
{
|
||||
free(srcPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
strcpy(dstPath, "/tmp/priiload.app");
|
||||
}
|
||||
else
|
||||
{
|
||||
dstPath = GetTitleExec(0x100000002LL, true);
|
||||
if (!dstPath)
|
||||
{
|
||||
free(srcPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!priiloader)
|
||||
GetSysMenuExecPath(dstPath, true);
|
||||
|
||||
u32 sizeA = 0;
|
||||
u32 sizeB = 0;
|
||||
u8* dataA = NANDLoadFile(srcPath, &sizeA);
|
||||
if (!dataA)
|
||||
{
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
u8* dataB = NANDLoadFile(dstPath, &sizeB);
|
||||
if (!dataA)
|
||||
if (!dataB)
|
||||
{
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
free(dataA);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = !CompareHash(dataA, sizeA, dataB, sizeB);
|
||||
bool ret = (sizeA == sizeB) && !CompareHash(dataA, sizeA, dataB, sizeB);
|
||||
|
||||
free(srcPath);
|
||||
free(dstPath);
|
||||
free(dataA);
|
||||
free(dataB);
|
||||
|
||||
@ -971,9 +959,9 @@ skipChecks:
|
||||
{
|
||||
if (restored)
|
||||
{
|
||||
char* path = GetTitleExec(0x100000002LL, true);
|
||||
char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20);
|
||||
GetSysMenuExecPath(path, true);
|
||||
NANDDeleteFile(path);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user