ES_Identify errors, ISFS errors, asm bootstub? February 11, 2009 09:37PM | Registered: 14 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; }