|
ES_Identify errors, ISFS errors, asm bootstub? February 11, 2009 09:37PM | Registered: 17 years ago Posts: 188 |
...
#include "certs_bin.h"
#include "other_certs_bin.h"
#include "shop_certs_bin.h"//Extracted from a shop update partition wad.
#include "haxx_certs_bin.h"
#include "sysmenu_tik.h"
#include "su_tmd.h"
#include "su_tik.h"
static void *xfb = NULL;
static GXRModeObj *rmode = NULL;
u32 tempKeyID = 0;
char *Path = NULL;
tmd *TMD;
tik *ticket;
signed_blob *certs;
u8 *bootdol;
u32 tmd_size;
u32 bootdol_size;
u32 ticket_size;
u32 certs_size;
struct DOLHeader//This and BootDOL are from some loader, slightly modified.
//Don't remember the loader name though.
{
unsigned int text_file_positions[7];
unsigned int data_file_positions[11];
unsigned int text_addresses[7];
unsigned int data_addresses[11];
unsigned int text_sizes[7];
unsigned int data_sizes[11];
unsigned int bss_address;
unsigned int bss_size;
unsigned int entry_point;
unsigned char unused[0x1C];
};
bool BootDOL(unsigned char *data, u64 length);
u8 *ReadFile(char *path, u32 *filesize, bool source);
tmd *ReadTMD(u64 titleid, u32 *TMD_SIZE, bool source);
tik *ReadTIK(u64 titleid, u32 *TIK_SIZE, bool source);
signed_blob *ReadCERTS(u64 titleid, tmd *TMD, u32 *TMD_SIZE, u32 *CERTS_size, bool source);
u8 *ReadBootDol(u64 titleid, tmd *TMD, u32 *dol_size, bool source);
bool Boot(u64 titleid, bool source);
bool BootSD(u64 titleid);
bool BootNAND(u64 titleid);
bool SystemMenuAuth();//SystemMenuAuth and the sysmenu certs and ticket, are from SquidMan's WiiMU.
bool SUAuth();
bool BootDOL(unsigned char *data, u64 length)//This function needs replaced by an assembler bootstub,
//as this program freezes when attempting to boot. Anyone have such a bootstub?
//I'm not sure how to use GeckoOS's bootstub...
{
DOLHeader *header = (DOLHeader*)data;
void (*entry)();
//Load the .text section(Code)
for(int i=0; i<7; i++)
{
if(header->text_sizes==0)continue;
ICInvalidateRange((void*)header->text_addresses, header->text_sizes);
memmove((void*)header->text_addresses, data + header->text_file_positions, header->text_sizes);
}
//Load the .data section
for(int i=0; i<11; i++)
{
if(header->data_sizes==0)continue;
memmove((void*)header->data_addresses, data + header->data_file_positions, header->data_sizes);
DCFlushRangeNoSync((void*)header->data_addresses, header->data_sizes);
}
//Clear the .bss section
memset((void*)header->bss_address, 0, header->bss_size);
DCFlushRange((void*)header->bss_address, header->bss_size);
//Boot
__IOS_ShutdownSubsystems();
IRQ_Disable();
entry = (void(*)())header->entry_point;
entry();
return 0;
}
u8 *ReadFile(char *path, u32 *filesize, bool source)
{
FILE *fsd = NULL;
s32 fnand = 0;
s32 retval;
u8 *buffer = NULL;
fstats n_stats;
struct stat s_stats;
if(source)
{
retval = ISFS_Open(path, ISFS_OPEN_READ);
if(retval<0)
{
printf("Failed to open %s\nError: %d\n", path, retval);
return NULL;
}
fnand = retval;
retval = ISFS_GetStats(&n_stats);
if(retval<0)
{
printf("Failed to get the stats for %s\nError: %d\n", path, retval);
return NULL;
}
*filesize = n_stats.file_length;
}
if(!source)
{
fsd = fopen(path, "rb");
if(fsd==NULL)
{
printf("Failed to open %s\n", path);
return NULL;
}
stat(path, &s_stats);
*filesize = s_stats.st_size;
}
buffer = (u8*)memalign(32, *filesize);
if(buffer==NULL)
{
printf("Failed to allocate memory.\n");
return NULL;
}
if(source)
{
retval = ISFS_Read(fnand, buffer, *filesize);
if(retval<0)
{
printf("ISFS_Read failed: %d\n", retval);
free(buffer);
return NULL;
}
}
if(!source)fread(buffer, 1, *filesize, fsd);
if(source)
{
retval = ISFS_Close(fnand);
if(retval<0)
{
printf("Failed to close %s\nError: %d\n", path, retval);
free(buffer);
return NULL;
}
}
if(!source)
{
fclose(fsd);
}
return buffer;
}
tmd *ReadTMD(u64 titleid, u32 *TMD_SIZE, bool source)
{
tmd *read_tmd = NULL;
memset(Path, 0, 256);
if(!source)
sprintf(Path, "/wiipatcher_contents/%08x%08x/title.tmd", (u32)(titleid>>32), (u32)(titleid));
if(source)
sprintf(Path, "/title/%08x/%08x/content/title.tmd", (u32)(titleid>>32), (u32)(titleid));
read_tmd = (tmd*)(((int)(ReadFile(Path, TMD_SIZE, source))) + sizeof(sig_rsa2048));
return read_tmd;
}
tik *ReadTIK(u64 titleid, u32 *TIK_SIZE, bool source)
{
tik *TIK = NULL;
memset(Path, 0, 256);
if(!source)
sprintf(Path, "/wiipatcher_contents/%08x%08x/title.tik", (u32)(titleid>>32), (u32)(titleid));
if(source)
sprintf(Path, "/ticket/%08x/%08x.tik", (u32)(titleid>>32), (u32)(titleid));
TIK = (tik*)ReadFile(Path, TIK_SIZE, source);
return TIK;
}
signed_blob *ReadCERTS(u64 titleid, tmd *read_tmd, u32 *TMD_SIZE, u32 *CERTS_size, bool source)
{
tmd *_TMD = read_tmd;
bool bread_tmd = 0;
signed_blob *read_certs;
u32 *tmd_size;
if(TMD_SIZE)tmd_size = TMD_SIZE;
if(_TMD==NULL)
{
if(TMD_SIZE==NULL)
{
tmd_size = (u32*)malloc(sizeof(u32));
if(tmd_size==NULL)
{
printf("Failed to allocate memory.\n");
return NULL;
}
*tmd_size = 0;
}
_TMD = ReadTMD(titleid, tmd_size, source);
bread_tmd = 1;
if(_TMD==NULL)
{
printf("Failed to read tmd for certs.\n");
return NULL;
}
}
printf("ptr %p tmd_size %x cert offset %x\n", tmd_size, (int)*tmd_size, ((int)0x1E4 + (0x24 * _TMD->num_contents)));
read_certs = (signed_blob*)&(((u8*)TMD)[0x1E4 + (0x24 * _TMD->num_contents)]);
*CERTS_size = (u32)(((int)*tmd_size) - ((int)0x1E4 + (0x24 * _TMD->num_contents)));
if(read_tmd)
{
free(_TMD);
free(tmd_size);
}
return read_certs;
}
u8 *ReadBootDol(u64 titleid, tmd *TMD, u32 *dol_size, bool source)
{
tmd *_TMD = TMD;
bool read_tmd = 0;
u8 *bootdol;
tmd_content *boot_content;
u32 contentid;
memset(Path, 0, 256);
if(_TMD==NULL)
{
_TMD = ReadTMD(titleid, NULL, source);
read_tmd = 1;
if(_TMD==NULL)
{
printf("Failed to read tmd for certs.\n");
return NULL;
}
}
boot_content = (tmd_content*)&_TMD->contents[_TMD->boot_index];
contentid = boot_content->cid;
if(!source)
sprintf(Path, "/wiipatcher_contents/%08x%08x/%08x.app", (u32)(titleid>>32), (u32)(titleid), contentid);
if(source)
sprintf(Path, "/title/%08x/%08x/content/%08x.app", (u32)(titleid>>32), (u32)(titleid), contentid);
bootdol = ReadFile(Path, dol_size, source);
if(read_tmd)free(_TMD);
return bootdol;
}
bool Boot(u64 titleid, bool source)
{
int which = 0;
s32 retval = 0;
printf("Identify? Press A to not to identify as nothing, 1 for SU, 2 for SysMenu.\n");
while(1)
{
...
}
if(which==1)
{
if(!SUAuth())return 0;
}
if(which==2)
{
if(!SystemMenuAuth())return 0;
}
if(!fatInitDefault())//Called here, instead of main, because SD Card
//access fails when fatInitDefault was called before ES_Identify.
{
printf("Failed to initialize FAT. Do you have an SD Card inserted?\nPress A to exit.\n");
...
}
...
printf("Reading tmd...\n");
TMD = ReadTMD(titleid, &tmd_size, source);
printf("Reading ticket...\n");
ticket = ReadTIK(titleid, &ticket_size, source);
printf("Reading certs...\n");
printf("Use SU, SysMenu, or TMD certs?(NinCh TMD doesn't have certs)\n");
printf("Press A for TMD certs, 1 for SU, 2 for SysMenu, - for Shop, + for haxx.\n");
while(1)
{
...
}
if(which==0)certs = ReadCERTS(titleid, TMD, &tmd_size, &certs_size, source);
if(which==1)
{
certs = (signed_blob*)memalign(32, other_certs_bin_size);
memcpy(certs, other_certs_bin, other_certs_bin_size);
certs_size = other_certs_bin_size;
}
if(which==2)
{
certs = (signed_blob*)memalign(32, certs_bin_size);
memcpy(certs, certs_bin, certs_bin_size);
certs_size = certs_bin_size;
}
if(which==3)
{
certs = (signed_blob*)memalign(32, shop_certs_bin_size);
memcpy(certs, shop_certs_bin, shop_certs_bin_size);
certs_size = shop_certs_bin_size;
}
if(which==4)
{
certs = (signed_blob*)memalign(32, haxx_certs_bin_size);
memcpy(certs, haxx_certs_bin, haxx_certs_bin_size);
certs_size = haxx_certs_bin_size;
}
if(TMD==NULL)
{
printf("Failed to read tmd.\n");
return 0;
}
if(ticket==NULL)
{
printf("Failed to read ticket.\n");
return 0;
}
if(certs==NULL)
{
printf("Failed to read certs.\n");
return 0;
}
if(tmd_size==0)
{
printf("Read tmd filesize is invalid.(0)\n");
return 0;
}
if(ticket_size==0)
{
printf("Read ticket filesize is invalid.(0)\n");
return 0;
}
if(certs_size==0)
{
printf("Read certs size is invalid.(0)\n");
return 0;
}
printf("Identifying as %08x%08x...\n", (u32)(titleid>>32), (u32)(titleid));
retval = ES_Identify(certs, certs_size, (signed_blob*)TMD, tmd_size, (signed_blob*)ticket, ticket_size, &tempKeyID);//Fails with SU, SysMenu, Shop, and haxx certs: -4100.
if(retval<0)
{
printf("ES_Identify returned %d\n", retval);
...
return 0;
}
printf("Reading boot dol...\n");
bootdol = ReadBootDol(titleid, TMD, &bootdol_size, source);
if(bootdol==NULL)
{
printf("Failed to read boot dol.\n");
return 0;
}
printf("Done.\n");
printf("Press A to continue.\n");
while(1)
{
...
}
printf("Loading IOS%d...\n", (int)TMD->sys_version);
IOS_ReloadIOS((int)TMD->sys_version);
printf("Done.\n");
printf("Press A to continue.\n");
while(1)
{
...
}
printf("Booting...\n");
free(Path);
BootDOL(bootdol, bootdol_size);
return 1;
}
bool BootSD(u64 titleid)
{
return Boot(titleid, 0);
}
bool BootNAND(u64 titleid)
{
return Boot(titleid, 1);
}
bool SystemMenuAuth()
{
s32 retval;
u32 TMD_size ATTRIBUTE_ALIGN(32);
printf("Identifying as SysMenu...\n");
retval = ES_GetStoredTMDSize(0x0000000100000002LL, &TMD_size);
if(retval<0)
{
printf("ES_GetStoredTMDSize failed: %d\n", retval);
return 0;
}
signed_blob *TMD = (signed_blob *)memalign( 32, TMD_size );
memset(TMD, 0, TMD_size);
retval = ES_GetStoredTMD(0x0000000100000002LL, TMD, TMD_size);
if(retval<0)
{
printf("ES_GetStoredTMD failed: %d\n", retval);
return 0;
}
//printf("\nIdentifying as 00000001-00000002 (System Menu)!... \n");
retval = ES_Identify((signed_blob*)certs_bin, certs_bin_size, (signed_blob*)TMD, TMD_size, (signed_blob*)sysmenu_tik, sysmenu_tik_size, &tempKeyID);
if(retval<0)
{
printf("ES_Identify failed: %d\n", retval);
return 0;
}
//printf("SUCCESS!\n");
printf("SysMenu identification done.\n");
free(TMD);
return 1;
}
bool SUAuth()
{
s32 retval;
printf("Identifying as SU...\n");
retval = ES_Identify((signed_blob*)certs_bin, certs_bin_size, (signed_blob*)su_tmd, su_tmd_size, (signed_blob*)su_tik, su_tik_size, &tempKeyID);
if(retval<0)
{
printf("ES_Identify failed: %d\n", retval);
return 0;
}
printf("SU identification done.\n");
return 1;
}
//---------------------------------------------------------------------------------
int main( int argc, char **argv ){
//---------------------------------------------------------------------------------
int cur_pos = 0;
u64 titleid = 0x0001000148415445LL;
VIDEO_Init();
WPAD_Init();
rmode = VIDEO_GetPreferredMode(NULL);
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
Path = (char*)malloc(256);
if(Path==NULL)
{
printf("Failed to allocate memory.\n");
WPAD_ScanPads();
while(!(WPAD_ButtonsDown(0) & WPAD_BUTTON_A))
{
...
}
}
memset(Path, 0, 256);
printf("\x1b[2J");//Clear the screen and reset the cursor
printf("\x1b[2;2HWii Patcher - load and patch .dol binaries from Front SD or NAND, optionally write them back to NAND, and boot the binaries.\n\n");//NAND writing is not supported right now.
printf("Do you want to load/patch/run from Front SD, or NAND?\n");
while(1)
{
...
}
printf("\n\n");
if(cur_pos == 0)BootSD(titleid);
if(cur_pos == 1)BootNAND(titleid);
printf("Press A to exit.\n");
while(1)
{
...
}
return 0;
}