From 7714c6e6d8156794bcd6d5183fe18b3659d1a9dd Mon Sep 17 00:00:00 2001 From: "fix94.1" Date: Wed, 16 May 2012 19:29:53 +0000 Subject: [PATCH] -changed quite alot of things in apploader (thanks to GX again, before the NSMBW and Prince of Persia patch did nothing at all) -fixed typo in wip debug print (before it didnt work at all so nobody noticed) --- source/loader/apploader.c | 231 +++++++++++++++++++++----------------- source/loader/apploader.h | 2 +- source/loader/disc.c | 10 +- source/loader/wdvd.c | 23 ++-- source/loader/wdvd.h | 2 +- source/loader/wip.c | 27 +++-- source/loader/wip.h | 12 +- source/menu/menu_game.cpp | 3 +- 8 files changed, 177 insertions(+), 133 deletions(-) diff --git a/source/loader/apploader.c b/source/loader/apploader.c index f8202c15..8df2a867 100644 --- a/source/loader/apploader.c +++ b/source/loader/apploader.c @@ -11,6 +11,7 @@ #include "wbfs.h" #include "sys.h" #include "gecko.h" +#include "fst.h" /* Apploader function pointers */ typedef int (*app_main)(void **dst, int *size, int *offset); @@ -26,16 +27,19 @@ static u8 *appldr = (u8 *) 0x81200000; /* Variables */ static u32 buffer[0x20] ATTRIBUTE_ALIGN(32); - -static bool maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio); -static bool Remove_001_Protection(void *Address, int Size); -static bool PrinceOfPersiaPatch(); + +void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio); +void PatchCountryStrings(void *Address, int Size); +bool Remove_001_Protection(void *Address, int Size); +bool PrinceOfPersiaPatch(); +bool NewSuperMarioBrosPatch(); +bool hookpatched = false; s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio) -{ - void *dst = NULL; - int len = 0; - int offset = 0; +{ + void *dst = NULL; + int len = 0; + int offset = 0; u32 appldr_len; s32 ret; app_init appldr_init; @@ -63,24 +67,22 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc /* Initialize apploader */ appldr_init(gprintf); - - bool hookpatched = false; while (appldr_main(&dst, &len, &offset)) - { - /* Read data from DVD */ + { + /* Read data from DVD */ WDVD_Read(dst, len, (u64)(offset << 2)); - if(maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio)) - hookpatched = true; - } + maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio); + } - if (hooktype != 0 && !hookpatched) + free_wip(); + if (hooktype != 0) { - gprintf("Error: Could not patch the hook\n"); - gprintf("Ocarina and debugger won't work\n"); + if(hookpatched) + ocarina_do_code(); + else + gprintf("Error: Could not patch the hook, Ocarina and debugger won't work\n"); } - - PrinceOfPersiaPatch(); /* Set entry point from apploader */ *entry = appldr_final(); @@ -93,6 +95,32 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc return 0; } +void maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio) +{ + PrinceOfPersiaPatch(); + NewSuperMarioBrosPatch(); + + patchVideoModes(dst, len, vidMode, vmode, patchVidModes); + + if(hooktype != 0 && dogamehooks(dst, len, false)) + hookpatched = true; + if(vipatch) + vidolpatcher(dst, len); + if(configbytes[0] != 0xCD) + langpatcher(dst, len); + if(countryString) + PatchCountryStrings(dst, len); // Country Patch by WiiPower + if(aspectRatio != -1) + PatchAspectRatio(dst, len, aspectRatio); + + Remove_001_Protection(dst, len); + + do_wip_code((u8 *)dst, len); + + DCFlushRange(dst, len); + ICInvalidateRange(dst, len); +} + void PatchCountryStrings(void *Address, int Size) { u8 SearchPattern[4] = {0x00, 0x00, 0x00, 0x00}; @@ -168,98 +196,97 @@ void PatchCountryStrings(void *Address, int Size) } } -static bool PrinceOfPersiaPatch() +bool PrinceOfPersiaPatch() { - if (memcmp("SPX", (char *)0x80000000, 3) == 0 || memcmp("RPW", (char *)0x80000000, 3) == 0) + if (memcmp("SPX", (char *) 0x80000000, 3) != 0 && memcmp("RPW", (char *) 0x80000000, 3) != 0) + return false; + + WIP_Code * CodeList = MEM2_alloc(5 * sizeof(WIP_Code)); + CodeList[0].offset = 0x007AAC6A; + CodeList[0].srcaddress = 0x7A6B6F6A; + CodeList[0].dstaddress = 0x6F6A7A6B; + CodeList[1].offset = 0x007AAC75; + CodeList[1].srcaddress = 0x7C7A6939; + CodeList[1].dstaddress = 0x69397C7A; + CodeList[2].offset = 0x007AAC82; + CodeList[2].srcaddress = 0x7376686B; + CodeList[2].dstaddress = 0x686B7376; + CodeList[3].offset = 0x007AAC92; + CodeList[3].srcaddress = 0x80717570; + CodeList[3].dstaddress = 0x75708071; + CodeList[4].offset = 0x007AAC9D; + CodeList[4].srcaddress = 0x82806F3F; + CodeList[4].dstaddress = 0x6F3F8280; + + if (set_wip_list(CodeList, 5) == false) { - u8 *p = (u8 *)0x807AEB6A; - *p++ = 0x6F; - *p++ = 0x6A; - *p++ = 0x7A; - *p++ = 0x6B; - p = (u8 *)0x807AEB75; - *p++ = 0x69; - *p++ = 0x39; - *p++ = 0x7C; - *p++ = 0x7A; - p = (u8 *)0x807AEB82; - *p++ = 0x68; - *p++ = 0x6B; - *p++ = 0x73; - *p++ = 0x76; - p = (u8 *)0x807AEB92; - *p++ = 0x75; - *p++ = 0x70; - *p++ = 0x80; - *p++ = 0x71; - p = (u8 *)0x807AEB9D; - *p++ = 0x6F; - *p++ = 0x3F; - *p++ = 0x82; - *p++ = 0x80; - return true; + MEM2_free(CodeList); + CodeList = NULL; + return false; } - return false; + + return true; } -bool NewSuperMarioBrosPatch(void *Address, int Size) +bool NewSuperMarioBrosPatch() { - if (memcmp("SMN", (char *)0x80000000, 3) == 0) + WIP_Code * CodeList = NULL; + + if (memcmp("SMNE01", (char *) 0x80000000, 6) == 0) { - u8 SearchPattern1[32] = {// PAL - 0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, - 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, - 0x48, 0x12, 0xD9, 0x39, 0x7C, 0x7B, 0x1B, 0x78, - 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78}; - u8 SearchPattern2[32] = {// NTSC - 0x94, 0x21, 0xFF, 0xD0, 0x7C, 0x08, 0x02, 0xA6, - 0x90, 0x01, 0x00, 0x34, 0x39, 0x61, 0x00, 0x30, - 0x48, 0x12, 0xD7, 0x89, 0x7C, 0x7B, 0x1B, 0x78, - 0x7C, 0x9C, 0x23, 0x78, 0x7C, 0xBD, 0x2B, 0x78}; - u8 PatchData[4] = {0x4E, 0x80, 0x00, 0x20}; - - void *Addr = Address; - void *Addr_end = Address+Size; - while (Addr <= Addr_end-sizeof(SearchPattern1)) - { - if ( memcmp(Addr, SearchPattern1, sizeof(SearchPattern1))==0 - || memcmp(Addr, SearchPattern2, sizeof(SearchPattern2))==0) - { - memcpy(Addr,PatchData,sizeof(PatchData)); - return true; - } - Addr += 4; - } + CodeList = MEM2_alloc(3 * sizeof(WIP_Code)); + if(!CodeList) + return false; + CodeList[0].offset = 0x001AB610; + CodeList[0].srcaddress = 0x9421FFD0; + CodeList[0].dstaddress = 0x4E800020; + CodeList[1].offset = 0x001CED53; + CodeList[1].srcaddress = 0xDA000000; + CodeList[1].dstaddress = 0x71000000; + CodeList[2].offset = 0x001CED6B; + CodeList[2].srcaddress = 0xDA000000; + CodeList[2].dstaddress = 0x71000000; } - return false; + else if (memcmp("SMNP01", (char *) 0x80000000, 6) == 0) + { + CodeList = MEM2_alloc(3 * sizeof(WIP_Code)); + if(!CodeList) + return false; + CodeList[0].offset = 0x001AB750; + CodeList[0].srcaddress = 0x9421FFD0; + CodeList[0].dstaddress = 0x4E800020; + CodeList[1].offset = 0x001CEE90; + CodeList[1].srcaddress = 0x38A000DA; + CodeList[1].dstaddress = 0x38A00071; + CodeList[2].offset = 0x001CEEA8; + CodeList[2].srcaddress = 0x388000DA; + CodeList[2].dstaddress = 0x38800071; + } + else if (memcmp("SMNJ01", (char *) 0x80000000, 6) == 0) + { + CodeList = MEM2_alloc(3 * sizeof(WIP_Code)); + if(!CodeList) + return false; + CodeList[0].offset = 0x001AB420; + CodeList[0].srcaddress = 0x9421FFD0; + CodeList[0].dstaddress = 0x4E800020; + CodeList[1].offset = 0x001CEB63; + CodeList[1].srcaddress = 0xDA000000; + CodeList[1].dstaddress = 0x71000000; + CodeList[2].offset = 0x001CEB7B; + CodeList[2].srcaddress = 0xDA000000; + CodeList[2].dstaddress = 0x71000000; + } + if (CodeList && set_wip_list(CodeList, 3) == false) + { + MEM2_free(CodeList); + CodeList = NULL; + return false; + } + return CodeList != NULL; } -static bool maindolpatches(void *dst, int len, u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio) -{ - bool ret = false; - - DCFlushRange(dst, len); - - patchVideoModes(dst, len, vidMode, vmode, patchVidModes); - - if (hooktype != 0) ret = dogamehooks(dst, len, false); - if (vipatch) vidolpatcher(dst, len); - if (configbytes[0] != 0xCD) langpatcher(dst, len); - if (countryString) PatchCountryStrings(dst, len); // Country Patch by WiiPower - if (aspectRatio != -1) PatchAspectRatio(dst, len, aspectRatio); - Remove_001_Protection(dst, len); - - // NSMB Patch by WiiPower - NewSuperMarioBrosPatch(dst,len); - - do_wip_code((u8 *) dst, len); - - DCFlushRange(dst, len); - - return ret; -} - -static bool Remove_001_Protection(void *Address, int Size) +bool Remove_001_Protection(void *Address, int Size) { static const u8 SearchPattern[] = {0x40, 0x82, 0x00, 0x0C, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18}; static const u8 PatchData[] = {0x40, 0x82, 0x00, 0x04, 0x38, 0x60, 0x00, 0x01, 0x48, 0x00, 0x02, 0x44, 0x38, 0x61, 0x00, 0x18}; diff --git a/source/loader/apploader.h b/source/loader/apploader.h index 1151ecf9..0f5ed02f 100644 --- a/source/loader/apploader.h +++ b/source/loader/apploader.h @@ -5,6 +5,6 @@ typedef void (*entry_point)(void); /* Prototypes */ -s32 Apploader_Run(entry_point *, u8, GXRModeObj *vmode, bool, bool, u8, int); +s32 Apploader_Run(entry_point *entry,u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio); #endif diff --git a/source/loader/disc.c b/source/loader/disc.c index c62c3cd7..472754cd 100644 --- a/source/loader/disc.c +++ b/source/loader/disc.c @@ -40,8 +40,8 @@ static u8 *diskid = (u8 *)0x80000000; GXRModeObj *disc_vmode = NULL; GXRModeObj *vmode = NULL; u32 vmode_reg = 0; +u8 vidmode_selected = 0; -static u8 Tmd_Buffer[0x49e4] ALIGNED(32); extern void __exception_closeall(); entry_point p_entry; @@ -63,9 +63,6 @@ void __Disc_SetLowMem() /* Copy disc ID */ memcpy((void *) Online_Check, (void *) Disc_ID, 4); - - /* Flush cache */ - DCFlushRange((void *)0x80000000, 0x3F00); } GXRModeObj * __Disc_SelectVMode(u8 videoselected, u64 chantitle) @@ -360,9 +357,6 @@ s32 Disc_IsGC(void) s32 Disc_BootPartition() { - if (hooktype != 0) - ocarina_do_code(); - /* Set time */ __Disc_SetTime(); @@ -410,7 +404,7 @@ s32 Disc_BootPartition() void RunApploader(u64 offset, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio) { - WDVD_OpenPartition(offset, 0, 0, 0, Tmd_Buffer); + WDVD_OpenPartition(offset); /* Setup low memory */; __Disc_SetLowMem(); diff --git a/source/loader/wdvd.c b/source/loader/wdvd.c index e4f5f799..faec4eb4 100644 --- a/source/loader/wdvd.c +++ b/source/loader/wdvd.c @@ -169,9 +169,14 @@ s32 WDVD_Eject(void) return (ret == 1) ? 0 : -ret; } -s32 WDVD_OpenPartition(u64 offset, void* Ticket, void* Certificate, unsigned int Cert_Len, void* Out) +s32 WDVD_OpenPartition(u64 offset) { + if (di_fd < 0) + return di_fd; + + static u8 Tmd_Buffer[0x4A00] ATTRIBUTE_ALIGN(32); static ioctlv Vectors[5] ATTRIBUTE_ALIGN(32); + s32 ret; memset(inbuf, 0, sizeof inbuf); memset(outbuf, 0, sizeof outbuf); @@ -181,17 +186,19 @@ s32 WDVD_OpenPartition(u64 offset, void* Ticket, void* Certificate, unsigned int Vectors[0].data = inbuf; Vectors[0].len = 0x20; - Vectors[1].data = (Ticket == NULL) ? 0 : Ticket; - Vectors[1].len = (Ticket == NULL) ? 0 : 0x2a4; - Vectors[2].data = (Certificate == NULL) ? 0 : Certificate; - Vectors[2].len = (Certificate == NULL) ? 0 : Cert_Len; - Vectors[3].data = Out; + Vectors[1].data = 0; + Vectors[1].len = 0; + Vectors[2].data = 0; + Vectors[2].len = 0; + Vectors[3].data = Tmd_Buffer; Vectors[3].len = 0x49e4; Vectors[4].data = outbuf; Vectors[4].len = 0x20; - s32 ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, Vectors); - if (ret < 0) return ret; + ret = IOS_Ioctlv(di_fd, IOCTL_DI_OPENPART, 3, 2, (ioctlv *)Vectors); + + if (ret < 0) + return ret; return (ret == 1) ? 0 : -ret; } diff --git a/source/loader/wdvd.h b/source/loader/wdvd.h index 0e5d2961..bcf8c3fd 100644 --- a/source/loader/wdvd.h +++ b/source/loader/wdvd.h @@ -15,7 +15,7 @@ s32 WDVD_Seek(u64); s32 WDVD_Offset(u64); s32 WDVD_StopLaser(void); s32 WDVD_StopMotor(void); -s32 WDVD_OpenPartition(u64 offset, void* Ticket, void* Certificate, unsigned int Cert_Len, void* Out); +s32 WDVD_OpenPartition(u64 offset); s32 WDVD_ClosePartition(void); s32 WDVD_UnencryptedRead(void *, u32, u64); s32 WDVD_Read(void *, u32, u64); diff --git a/source/loader/wip.c b/source/loader/wip.c index 621b2861..b08f08ec 100644 --- a/source/loader/wip.c +++ b/source/loader/wip.c @@ -4,15 +4,8 @@ #include #include #include "mem2.hpp" -#include "utils.h" //SAFE_CLOSE #include "gecko.h" - -typedef struct -{ - u32 offset; - u32 srcaddress; - u32 dstaddress; -} WIP_Code; +#include "wip.h" static WIP_Code * CodeList = NULL; static u32 CodesCount = 0; @@ -50,7 +43,7 @@ void do_wip_code(u8 * dst, u32 len) } else { - gprintf("WIP: %08X Address does not match with WIP entrie.\n", CodeList[i].offset+n); + gprintf("WIP: %08X Address does not match with WIP entry.\n", CodeList[i].offset+n); gprintf("Destination: %02X | Should be: %02X.\n", dst[offset], ((u8 *)&CodeList[i].srcaddress)[n]); } } @@ -59,6 +52,22 @@ void do_wip_code(u8 * dst, u32 len) Counter++; } +//! for internal patches only +//! .wip files override internal patches +//! the codelist has to be freed if the set fails +//! if set was successful the codelist will be freed when it's done +bool set_wip_list(WIP_Code * list, int size) +{ + if (!CodeList && size > 0) + { + CodeList = list; + CodesCount = size; + return true; + } + + return false; +} + void wip_reset_counter() { ProcessedLength = 0; diff --git a/source/loader/wip.h b/source/loader/wip.h index b49ac3fa..bdb6343f 100644 --- a/source/loader/wip.h +++ b/source/loader/wip.h @@ -5,10 +5,18 @@ extern "C" { #endif /* __cplusplus */ +typedef struct +{ + u32 offset; + u32 srcaddress; + u32 dstaddress; +} WIP_Code; + +bool set_wip_list(WIP_Code *list, int size); void wip_reset_counter(); void free_wip(); -void do_wip_code(u8 * dst, u32 len); -void load_wip_patches(u8 *wippath, u8 *discid); +void do_wip_code(u8 *dst, u32 len); +int load_wip_patches(u8 *dir, u8 *gameid); #ifdef __cplusplus } diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index b6079688..c1c9e9b5 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -1293,7 +1293,6 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd) if(currentPartition == 0) SDHC_Init(); - gprintf("Booting game\n"); usleep(100 * 1000); /* Find game partition offset */ @@ -1305,7 +1304,7 @@ void CMenu::_launchGame(dir_discHdr *hdr, bool dvd) RunApploader(offset, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio); DeviceHandler::DestroyInstance(); USBStorage_Deinit(); - free_wip(); + gprintf("Booting game\n"); Disc_BootPartition(); }