⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patchmii_core.c

📁 xyzzy is a program for the Nintendo Wii which will read a console s OTP key storage and dump out the
💻 C
📖 第 1 页 / 共 2 页
字号:
	u32 i;	u32 match_count = 0;	u8 old_table[] = {0x00,0x00,0x00,0x01,0xFF,0xFF,0xFC,0x07,0xB5,0xF0};	u8 new_table[] = {0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0xB5,0xF0};    for (i=0; i<size-sizeof old_table; i++) {    if (!memcmp(buf + i, old_table, sizeof old_table)) {//      debug_printf("Found IOS deletion check @ 0x%x, patching.\n", i);      memcpy(buf + i, new_table, sizeof new_table);      buf += sizeof new_table;      match_count++;      continue;    }  }  if (match_count > 1) {	printf("Match count for %s was %d, expected 1; failing.\n", __FUNCTION__, match_count);	exit(1);  }  return match_count;}/* This patch disables the MEM2 protection */int patch_mem2protect(u8 *buf, u32 size){	u32 i;	u32 match_count = 0;	u8 old_table[] = {0xB5,0x00,0x4B,0x09,0x22,0x01,0x80,0x1A,0x22,0xF0};	u8 new_table[] = {0xB5,0x00,0x4B,0x09,0x22,0x00,0x80,0x1A,0x22,0xF0};  	for (i=0; i<size-sizeof old_table; i++) {		if (!memcmp(buf + i, old_table, sizeof old_table)) {//			debug_printf("Found MEM2 protection enable @ 0x%x, patching.\n", i); 			memcpy(buf + i, new_table, sizeof new_table);			buf += sizeof new_table;			match_count++;			continue;		}	}	if (match_count > 2) {		debug_printf("Match count for %s was %d, expected 1 or 2; failing.\n", __FUNCTION__, match_count);		exit(1);  }  return match_count;}void print_tmd_summary(const tmd *p_tmd) {  const tmd_content *p_cr;  p_cr = TMD_CONTENTS(p_tmd);  u32 size=0;  u16 i=0;  for(i=0;i<p_tmd->num_contents;i++) {    size += p_cr[i].size;  }  debug_printf("Title ID: %016llx\n",p_tmd->title_id);  debug_printf("Number of parts: %d.  Total size: %uK\n", p_tmd->num_contents, (u32) (size / 1024));}void zero_sig(signed_blob *sig) {  u8 *sig_ptr = (u8 *)sig;  memset(sig_ptr + 4, 0, SIGNATURE_SIZE(sig)-4);}void brute_tmd(tmd *p_tmd) {  u16 fill;  for(fill=0; fill<65535; fill++) {    p_tmd->fill3=fill;    sha1 hash;    //    debug_printf("SHA1(%p, %x, %p)\n", p_tmd, TMD_SIZE(p_tmd), hash);    SHA1((u8 *)p_tmd, TMD_SIZE(p_tmd), hash);;      if (hash[0]==0) {      //      debug_printf("setting fill3 to %04hx\n", fill);      return;    }  }  printf("Unable to fix tmd :(\n");  exit(4);}void brute_tik(tik *p_tik) {  u16 fill;  for(fill=0; fill<65535; fill++) {    p_tik->padding=fill;    sha1 hash;    //    debug_printf("SHA1(%p, %x, %p)\n", p_tmd, TMD_SIZE(p_tmd), hash);    SHA1((u8 *)p_tik, sizeof(tik), hash);      if (hash[0]==0) return;  }  printf("Unable to fix tik :(\n");  exit(5);}    void forge_tmd(signed_blob *s_tmd) {//  debug_printf("forging tmd sig");  zero_sig(s_tmd);  brute_tmd(SIGNATURE_PAYLOAD(s_tmd));}void forge_tik(signed_blob *s_tik) {//  debug_printf("forging tik sig");  zero_sig(s_tik);  brute_tik(SIGNATURE_PAYLOAD(s_tik));}#define BLOCK 0x1000s32 install_ticket(const signed_blob *s_tik, const signed_blob *s_certs, u32 certs_len) {  u32 ret;progress(10);//  debug_printf("Installing ticket...\n");  ret = ES_AddTicket(s_tik,STD_SIGNED_TIK_SIZE,s_certs,certs_len, NULL, 0);  if (ret < 0) {      debug_printf("ES_AddTicket failed: %d\n",ret);      return ret;  }  return 0;}s32 install(const signed_blob *s_tmd, const signed_blob *s_certs, u32 certs_len) {  u32 ret, i;  tmd *p_tmd = SIGNATURE_PAYLOAD(s_tmd);//  debug_printf("Adding title...\n");  ret = ES_AddTitleStart(s_tmd, SIGNED_TMD_SIZE(s_tmd), s_certs, certs_len, NULL, 0);progress(40);  if(ret < 0) {    debug_printf("ES_AddTitleStart failed: %d\n",ret);    ES_AddTitleCancel();    return ret;  }  for(i=0; i<p_tmd->num_contents; i++) {//    debug_printf("Adding content ID %08x", i);    ret = install_nus_object((tmd *)SIGNATURE_PAYLOAD(s_tmd), i);    if (ret) return ret;  }  ret = ES_AddTitleFinish();  if(ret < 0) {    printf("ES_AddTitleFinish failed: %d\n",ret);    ES_AddTitleCancel();    return ret;  }//  printf("Installation complete!\n");  return 0;}void patchmii_network_init(void) {	int retval;//	printf("HackMii KeyRipper -- Initializing network."); fflush(stdout);	printf("xyzzy v1.1, powered by PatchMii\nSending things to Earth..."); fflush(stdout);  	while (1) {  		retval = net_init (); 		if (retval < 0) {			if (retval != -EAGAIN) {				debug_printf ("net_init failed: %d\nI need a network to download IOS, sorry :(\n)", retval);				exit(0);			}    	}		if (!retval) break;		usleep(100000);		printf("."); fflush(stdout);  	}  	printf("\n");}void patchmii_download(u32 titleid1, u32 titleid2) {  	u8 *temp_tmdbuf = NULL, *temp_tikbuf = NULL;  	u32 tmdsize;	u8 update_tmd;	int i, retval;	if (ISFS_Initialize() || create_temp_dir()) {		perror("Failed to create temp dir: ");		exit(1);	}//  	debug_printf("Downloading IOS%d metadata: ..", titleid2);//	debug_printf("Sending things to Earth...");  	retval = get_nus_object(titleid1, titleid2, "tmd.10", &temp_tmdbuf, &tmdsize);  	if (retval<0) {		debug_printf("get_nus_object(tmd) returned %d, tmdsize = %u\n", retval, tmdsize);		exit(1);	}	if (temp_tmdbuf == NULL) {		debug_printf("Failed to allocate temp buffer for encrypted content, size was %u\n", tmdsize);		exit(1);	}  	memcpy(tmdbuf, temp_tmdbuf, MIN(tmdsize, sizeof(tmdbuf)));	free(temp_tmdbuf);	s_tmd = (signed_blob *)tmdbuf;	if(!IS_VALID_SIGNATURE(s_tmd)) {    	debug_printf("Bad TMD signature!\n");		exit(1);  	}	u32 ticketsize;	retval = get_nus_object(titleid1, titleid2,						  "cetk", &temp_tikbuf, &ticketsize);							if (retval < 0) debug_printf("get_nus_object(cetk) returned %d, ticketsize = %u\n", retval, ticketsize);	memcpy(tikbuf, temp_tikbuf, MIN(ticketsize, sizeof(tikbuf)));  	s_tik = (signed_blob *)tikbuf;	if(!IS_VALID_SIGNATURE(s_tik)) {    	debug_printf("Bad tik signature!\n");		exit(1);  	}    	free(temp_tikbuf);	s_certs = (signed_blob *)haxx_certs;	if(!IS_VALID_SIGNATURE(s_certs)) {    	debug_printf("Bad cert signature!\n");		exit(1);  	}	u8 key[16];	get_title_key(s_tik, key);	aes_set_key(key);	const tmd *p_tmd;	tmd_content *p_cr;	p_tmd = (tmd*)SIGNATURE_PAYLOAD(s_tmd);	p_cr = TMD_CONTENTS(p_tmd);        //	print_tmd_summary(p_tmd);//	debug_printf("\b ..games..\b");  		static char cidstr[32];	for (i=0;i<p_tmd->num_contents;i++) {//	   debug_printf("Downloading part %d/%d (%lluK): ", i+1, //					p_tmd->num_contents, p_cr[i].size / 1024);	   sprintf(cidstr, "%08x", p_cr[i].cid);   	   u8 *content_buf, *decrypted_buf;	   u32 content_size;	   retval = get_nus_object(titleid1, titleid2, cidstr, &content_buf, &content_size);	   if (retval < 0) {			debug_printf("get_nus_object(%s) failed with error %d, content size = %u\n", 					cidstr, retval, content_size);			exit(1);		}		if (content_buf == NULL) {			debug_printf("error allocating content buffer, size was %u\n", content_size);			exit(1);		}		if (content_size % 16) {			debug_printf("ERROR: downloaded content[%hu] size %u is not a multiple of 16\n",					i, content_size);			free(content_buf);			exit(1);		}   		if (content_size < p_cr[i].size) {			debug_printf("ERROR: only downloaded %u / %llu bytes\n", content_size, p_cr[i].size);			free(content_buf);			exit(1);   		} 		decrypted_buf = malloc(content_size);		if (!decrypted_buf) {			debug_printf("ERROR: failed to allocate decrypted_buf (%u bytes)\n", content_size);			free(content_buf);			exit(1);		}		decrypt_buffer(i, content_buf, decrypted_buf, content_size);		sha1 hash;		SHA1(decrypted_buf, p_cr[i].size, hash);		if (!memcmp(p_cr[i].hash, hash, sizeof hash)) {//			debug_printf("\b\b hash OK. ");//			display_ios_tags(decrypted_buf, content_size);			update_tmd = 0;			if(patch_iosdelete(decrypted_buf, content_size)) update_tmd = 1;			if(patch_mem2protect(decrypted_buf, content_size)) update_tmd = 1;			if(update_tmd == 1)			{//				debug_printf("Updating TMD.\n");				SHA1(decrypted_buf, p_cr[i].size, hash);				memcpy(p_cr[i].hash, hash, sizeof hash);				tmd_dirty=1;			}			retval = (int) save_nus_object(p_cr[i].cid, decrypted_buf, content_size);			if (retval < 0) {				debug_printf("save_nus_object(%x) returned error %d\n", p_cr[i].cid, retval);				exit(1);			}		} else {			debug_printf("hash BAD\n");			exit(1);		}			free(decrypted_buf);	   	free(content_buf);	}//	debug_printf("\b ..keys..\b"); 	}s32 find_empty_IOS_slot(void) {	int i;	for (i=255; i>64; i--) {		if (get_title_version(1,i)==-106) break;	}	if (i>64) {//		debug_printf("Found empty IOS slot (IOS%d)\n", i);		temp_ios_slot = i;		return i;	}	debug_printf("Couldn't find empty IOS slot :(\n");	return -1;}s32 install_temporary_ios(u32 base_ios) {	if (find_empty_IOS_slot()==-1) return -1;	patchmii_download(1, base_ios);	change_ticket_title_id(s_tik, 1, temp_ios_slot);	change_tmd_title_id(s_tmd, 1, temp_ios_slot);	change_tmd_version(s_tmd, 31337);   	forge_tmd(s_tmd);   	forge_tik(s_tik);//  	debug_printf("Download complete. Installing:\n");  	int retval = install_ticket(s_tik, s_certs, haxx_certs_size);  	if (retval) {    	debug_printf("install_ticket returned %d\n", retval);		exit(1);  	}  	retval = install(s_tmd, s_certs, haxx_certs_size);//	debug_printf("\b..hacks..\b");	if (retval) printf("install returned %d\n", retval);	return retval;}s32 load_temporary_ios(void) {	return IOS_ReloadIOS(temp_ios_slot);}s32 cleanup_temporary_ios(void) {	debug_printf("Cleaning up temporary IOS version %d\n", temp_ios_slot);	if (temp_ios_slot < 64) { // this should never happen		printf("Not gonna do it, would't be prudent...\n");		while(1);	}	/*	This code should work, but ends up getting an error -1017...	s32 vers = get_title_version(1, temp_ios_slot);	debug_printf("Detected version %d of IOS%d\n", vers, temp_ios_slot);	if (vers != 31337) {		debug_printf("Error: we didn't make this version of IOS\n");		return -1;	} */	u64 title = (u64) 1 << 32 | (u64)temp_ios_slot;	int retval = ES_DeleteTitle(title);    if (retval < 0) debug_printf("ES_DeleteTitle(%016llx) returned %d\n", title, retval);	return retval;}#ifdef STANDALONEint main(int argc, char **argv) {	console_setup();	printf("PatchMii Core v" VERSION ", by bushing\n");// ******* WARNING *******// Obviously, if you're reading this, you're obviously capable of disabling the// following checks.  If you put any of the following titles into an unusuable state, // your Wii will fail to boot://// 1-1 (BOOT2), 1-2 (System Menu), 1-30 (IOS30, currently specified by 1-2's TMD)// Corrupting other titles (for example, BC or the banners of installed channels)// may also cause difficulty booting.  Please do not remove these safety checks// unless you have performed extensive testing and are willing to take on the risk// of bricking the systems of people to whom you give this code.  -bushing	if ((OUTPUT_TITLEID_H == 1) && (OUTPUT_TITLEID_L == 2)) {		printf("Sorry, I won't modify the system menu; too dangerous. :(\n");		while(1);  	}	if ((OUTPUT_TITLEID_H == 1) && (OUTPUT_TITLEID_L == 30)) {		printf("Sorry, I won't modify IOS30; too dangerous. :(\n");		while(1);  	}	printvers();	patchmii_network_init();//	patchmii_download(INPUT_TITLEID_H, INPUT_TITLEID_L);//	patchmii_install();	install_temporary_ios(11);	cleanup_temporary_ios();  	debug_printf("Done!\n");	exit(0);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -