-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)
This commit is contained in:
fix94.1 2012-05-16 19:29:53 +00:00
parent 8ca6d767bc
commit 7714c6e6d8
8 changed files with 177 additions and 133 deletions

View File

@ -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};

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -4,15 +4,8 @@
#include <stdlib.h>
#include <stdio.h>
#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;

View File

@ -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
}

View File

@ -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();
}