now if the name of installed channels is not in the database.txt, we try to fine it from inside the channel itself.

first try the 00000000.app with the system language, then with english.
if there is still no name for the title, look in banner.bin

also made a kick-ass clone of the wii settings screen to adjust the normal wii settings.  it is after all the channels.
This commit is contained in:
giantpune 2009-07-30 02:54:08 +00:00
parent 1b9a56b877
commit c9b7cf70b4
17 changed files with 860 additions and 328 deletions

View File

@ -20,6 +20,7 @@ SOURCES := source source/libwiigui source/images source/fonts source/sounds \
source/libwbfs source/unzip source/language source/mload source/patches \
source/usbloader source/xml source/network source/settings source/prompts \
source/ramdisc source/wad source/banner source/cheats source/homebrewboot
DATA := data
INCLUDES := source
#---------------------------------------------------------------------------------
@ -150,6 +151,13 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang)
@echo $(notdir $<)
$(bin2o)
%.certs.o : %.certs
@echo $(notdir $<)
$(bin2o)
%.dat.o : %.dat
@echo $(notdir $<)
$(bin2o)
export PATH := $(PROJECTDIR)/gettext-bin:$(PATH)

BIN
data/certs.dat Normal file

Binary file not shown.

BIN
data/haxx.certs Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<pd><ViewState><e p="gui\source\mload" x="false"></e><e p="gui\source\settings" x="false"></e><e p="gui\source\images" x="false"></e><e p="gui\source\prompts" x="false"></e><e p="gui\source\banner" x="false"></e><e p="gui\source\cheats" x="true"></e><e p="gui\source\network" x="false"></e><e p="gui\source\unzip" x="false"></e><e p="gui\source\usbloader" x="false"></e><e p="gui\source\xml" x="false"></e><e p="gui\source\fonts" x="false"></e><e p="gui\source\ramdisc" x="false"></e><e p="gui\source\sounds" x="false"></e><e p="gui\source\wad" x="false"></e><e p="gui" x="true"></e><e p="gui\source\homebrewboot" x="false"></e><e p="gui\source\language" x="true"></e><e p="gui\source" x="true"></e><e p="gui\source\libwbfs" x="false"></e><e p="gui\source\libwiigui" x="false"></e><e p="gui\source\patches" x="false"></e></ViewState></pd>
<pd><ViewState><e p="gui\source\mload" x="false"></e><e p="gui\source\settings" x="false"></e><e p="gui\source\images" x="false"></e><e p="gui\source\prompts" x="true"></e><e p="gui\source\banner" x="false"></e><e p="gui\source\cheats" x="true"></e><e p="gui\source\network" x="false"></e><e p="gui\source\unzip" x="false"></e><e p="gui\source\usbloader" x="false"></e><e p="gui\source\xml" x="false"></e><e p="gui\source\fonts" x="false"></e><e p="gui\source\ramdisc" x="false"></e><e p="gui\source\sounds" x="false"></e><e p="gui\source\wad" x="true"></e><e p="gui" x="true"></e><e p="gui\source\homebrewboot" x="false"></e><e p="gui\source\language" x="true"></e><e p="gui\source" x="true"></e><e p="gui\source\libwbfs" x="false"></e><e p="gui\source\libwiigui" x="false"></e><e p="gui\source\patches" x="false"></e></ViewState></pd>

View File

@ -44,6 +44,7 @@
#include "fatmounter.h"
#include "buffer.h"
#include "xml/xml.h"
#include "wad/title.h"
#include "usbloader/wdvd.h"
@ -706,7 +707,7 @@ int MenuDiscList()
if (Settings.godmode == 1)
w.Append(&homebrewBtn);
if((Settings.hddinfo == hr12)||(Settings.hddinfo == hr24))
if((Settings.hddinfo == hr12)||(Settings.hddinfo == hr24))
{
w.Append(&clockTimeBack);
w.Append(&clockTime);

View File

@ -2,7 +2,7 @@
* TitleBrowser
* USB Loader GX 2009
*
* TitleBrowser.cpp
* TitleBrowser.cpp *giantpune*
***************************************************************************/
#include "language/gettext.h"
#include "libwiigui/gui.h"
@ -45,6 +45,8 @@ int TitleBrowser(u32 type)
FILE *f;
char path[100];
ISFS_Initialize();
sprintf(path,"%s/config/database.txt",bootDevice);
f = fopen(path, "r");
@ -55,12 +57,6 @@ int TitleBrowser(u32 type)
//exit(1);
}
// Die if we can't handle this many
if (num_titles > 100){
//printf("\tError! Too many titles! (%u)\n", num_titles);
//exit(1);
}
// Get titles of our requested type
ret = getTitles_Type(type, titles, num_titles);
if (ret < 0){
@ -83,9 +79,10 @@ int TitleBrowser(u32 type)
}
//this array will hold all the names for the titles so we only have to get them one time
char name[num_titles+num_sys_titles][50];
customOptionList options3(num_titles+num_sys_titles);
customOptionList options3(num_titles+num_sys_titles+1);
//write the titles on the option browser
u32 i = 0;
@ -95,45 +92,54 @@ int TitleBrowser(u32 type)
while (i < num_titles){
//start from the beginning of the file each loop
if (f)rewind(f);
char name[50];
//char name[50];
char text[15];
strcpy(name,"");//make sure name is empty
strcpy(name[i],"");//make sure name is empty
u8 found=0;
//set the title's name, number, ID to text
sprintf(text, "%s", titleText(type, titles[i]));
//getTitle_Name(name, TITLE_ID(type, titles[i]), text);
//get name from database cause i dont like the ADT function
char line[200];
char tmp[50];
snprintf(tmp,50,tmp," ");
snprintf(name,sizeof(name),"Unknown Title");
//snprintf(name[i],sizeof(name[i]),"Unknown Title");
if (!f) {
sprintf(name,"Unknown--<No DB>");
}
else
if(f)
{
while (fgets(line, sizeof(line), f)) {
if (line[0]== text[0]&&
line[1]== text[1]&&
line[2]== text[2])
{ int j=0;
found=1;
for(j=0;(line[j+4]!='\0' || j<51);j++)
tmp[j]=line[j+4];
snprintf(name,sizeof(name),"%s",tmp);
break;
snprintf(name[i],sizeof(name[i]),"%s",tmp);
//break;
}
}
}
if(!found)
{
if (getName00(name[i], TITLE_ID(type, titles[i]),CONF_GetLanguage()*2)>=0)
found=2;
if(!found)
{
if (getNameBN(name[i], TITLE_ID(type, titles[i]))>=0)
found=3;
if(!found)
snprintf(name[i],sizeof(name[i]),"Unknown Title (%08x)",titles[i]);
}
}
}
//set the text to the option browser
options3.SetName(i, "%s",text);
options3.SetValue(i, "%s",name);
//options3.SetValue(i, " (%08x)",titles[i]);//use this line to show the number to call to launch the channel
options3.SetValue(i, "%s",name[i]);
//options3.SetValue(i, " (%08x) %s",titles[i],name[i]);//use this line to show the number to call to launch the channel
//move on to the next title
i++;
}
@ -142,49 +148,66 @@ int TitleBrowser(u32 type)
while (i < num_titles+num_sys_titles){
//start from the beginning of the file each loop
if (f)rewind(f);
char name[50];
//char name[50];
char text[15];
strcpy(name,"");//make sure name is empty
strcpy(name[i],"");//make sure name is empty
u8 found=0;
//set the title's name, number, ID to text
sprintf(text, "%s", titleText(0x00010002, sys_titles[i-num_titles]));
//getTitle_Name(name, TITLE_ID(0x00010002, sys_titles[i-num_titles]), text);
//get name from database cause i dont like the ADT function
char line[200];
char tmp[50];
snprintf(tmp,50,tmp," ");
snprintf(name,sizeof(name),"Unknown Title");
if (!f) {
sprintf(name,"Unknown--<No DB>");
}
else
//snprintf(name[i],sizeof(name[i]),"Unknown Title");
if(f)
{
while (fgets(line, sizeof(line), f)) {
if (line[0]== text[0]&&
line[1]== text[1]&&
line[2]== text[2])
{ int j=0;
found=1;
for(j=0;(line[j+4]!='\0' || j<51);j++)
tmp[j]=line[j+4];
snprintf(name,sizeof(name),"%s",tmp);
snprintf(name[i],sizeof(name[i]),"%s",tmp);
break;
}
}
}
if(!found)
{
if (getName00(name[i], TITLE_ID(0x00010002, sys_titles[i-num_titles]))>=0)
found=2;
if(!found)
{
if (getNameBN(name[i], TITLE_ID(0x00010002, sys_titles[i-num_titles]))>=0)
found=3;
if(!found)
snprintf(name[i],sizeof(name[i]),"Unknown Title (%08x)",sys_titles[i-num_titles]);
}
}
}
//set the text to the option browser
options3.SetName(i, "%s",text);
options3.SetValue(i, "%s",name);
//options3.SetValue(i, " (%08x)",titles[i]);
options3.SetValue(i, "%s",name[i]);
//options3.SetValue(i, " (%08x) %s",titles[i],name[i]);//use this line to show the number to call to launch the channel
//move on to the next title
i++;
}
if(i == num_titles+num_sys_titles)
{ options3.SetName(i, " ");
options3.SetValue(i, "%s",tr("Wii Settings"));
}
//we have all the titles we need so close the database and stop poking around in the wii
fclose(f);
//get rid of our footprints in there
Uninstall_FromTitle(TITLE_ID(1, 0));
ISFS_Deinitialize();
bool exit = false;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
@ -231,7 +254,7 @@ int TitleBrowser(u32 type)
if(num_titles > 9)
scrollbaron = 1;
GuiCustomOptionBrowser optionBrowser3(396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, num_titles>9?1:0, 200);
GuiCustomOptionBrowser optionBrowser3(396, 280, &options3, CFG.theme_path, "bg_options_gamesettings.png", bg_options_settings_png, num_titles+num_sys_titles>9?1:0, 200);
optionBrowser3.SetPosition(0, 90);
optionBrowser3.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
@ -244,6 +267,8 @@ int TitleBrowser(u32 type)
mainWindow->Append(&w);
int tmp=num_titles+num_sys_titles;
ResumeGui();
numtitle=num_titles;
while(!exit)
@ -259,50 +284,25 @@ int TitleBrowser(u32 type)
if(ret > -1) {//if a click happened
char name[50];
//char name[50];
char text[15];
if (f)rewind(f);
strcpy(name,"");//make sure name is empty
//strcpy(name,"");//make sure name is empty
if (ret<numtitle)
{
//set the title's name, number, ID to text
sprintf(text, "%s", titleText(type, titles[ret]));
getTitle_Name(name, TITLE_ID(type, titles[ret]), text);
//get name from database cause i dont like the ADT function
char line[200];
char tmp[50];
snprintf(tmp,50,tmp," ");
snprintf(name,sizeof(name),"Unknown Title");
if (!f) {
sprintf(name,"Unknown--<No DB>");
}
else
{
while (fgets(line, sizeof(line), f)) {
if (line[0]== text[0]&&
line[1]== text[1]&&
line[2]== text[2])
{ int j=0;
for(j=0;(line[j+4]!='\0' || j<51);j++)
tmp[j]=line[j+4];
snprintf(name,sizeof(name),"%s",tmp);
break;
}
}
}
char temp[100];
//prompt to boot selected title
snprintf(temp, sizeof(temp), "%s : %s",text,name);
snprintf(temp, sizeof(temp), "%s : %s",text,name[ret]);
int choice = WindowPrompt(tr("Boot?"), temp, tr("OK"), tr("Cancel"));
if(choice) {//if they say yes
//stop all this stuff before starting the channel
fclose(f);
CloseXMLDatabase();
ExitGUIThreads();
ShutdownAudio();
@ -322,59 +322,46 @@ int TitleBrowser(u32 type)
}
else//if they clicked a system title
{
//set the title's name, number, ID to text
sprintf(text, "%s", titleText(0x00010002, sys_titles[ret-num_titles]));
getTitle_Name(name, TITLE_ID(0x00010002, sys_titles[ret-num_titles]), text);
//get name from database cause i dont like the ADT function
char line[200];
char tmp[50];
snprintf(tmp,50,tmp," ");
snprintf(name,sizeof(name),"Unknown Title");
if (!f) {
sprintf(name,"Unknown--<No DB>");
}
else
{
while (fgets(line, sizeof(line), f)) {
if (line[0]== text[0]&&
line[1]== text[1]&&
line[2]== text[2])
{ int j=0;
for(j=0;(line[j+4]!='\0' || j<51);j++)
tmp[j]=line[j+4];
snprintf(name,sizeof(name),"%s",tmp);
break;
}
}
}
char temp[100];
//prompt to boot selected title
snprintf(temp, sizeof(temp), "%s : %s May not boot correctly if your System Menu is not up to date.",text,name);
int choice = WindowPrompt(tr("Boot?"), temp, tr("OK"), tr("Cancel"));
if(choice) {//if they say yes
//stop all this stuff before starting the channel
fclose(f);
CloseXMLDatabase();
ExitGUIThreads();
ShutdownAudio();
StopGX();
if(ret == tmp)
{
CloseXMLDatabase();
ExitGUIThreads();
ShutdownAudio();
StopGX();
WII_Initialize();
WII_LaunchTitle(TITLE_ID(0x00010002,sys_titles[ret-num_titles]));
//this really shouldn't be needed because the title will be booted
exit = true;
break;
}
else{
//if they said no to booting the title
ret = -1;
optionBrowser3.ResetState();
}
WII_ReturnToSettings();
}
else
{
//set the title's name, number, ID to text
sprintf(text, "%s", titleText(0x00010002, sys_titles[ret-num_titles]));
char temp[100];
//prompt to boot selected title
snprintf(temp, sizeof(temp), "%s : %s May not boot correctly if your System Menu is not up to date.",text,name[ret]);
int choice = WindowPrompt(tr("Boot?"), temp, tr("OK"), tr("Cancel"));
if(choice) {//if they say yes
//stop all this stuff before starting the channel
CloseXMLDatabase();
ExitGUIThreads();
ShutdownAudio();
StopGX();
WII_Initialize();
WII_LaunchTitle(TITLE_ID(0x00010002,sys_titles[ret-num_titles]));
//this really shouldn't be needed because the title will be booted
exit = true;
break;
}
else{
//if they said no to booting the title
ret = -1;
optionBrowser3.ResetState();
}
}
}
}

View File

@ -1,4 +1,4 @@
#define SVN_REV "669M"
#define SVN_REV "672M"
const char *GetRev()
{

210
source/wad/id.c Normal file
View File

@ -0,0 +1,210 @@
/*-------------------------------------------------------------
id.c -- ES Identification code
Copyright (C) 2008 tona
Unless other credit specified
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1.The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2.Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3.This notice may not be removed or altered from any source
distribution.
-------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <gccore.h>
#include "id.h"
#include "patchmii_core.h"
#include "certs_dat.h"
// Turn upper and lower into a full title ID
#define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
// Get upper or lower half of a title ID
#define TITLE_UPPER(x) ((u32)((x) >> 32))
// Turn upper and lower into a full title ID
#define TITLE_LOWER(x) ((u32)(x))
/* Debug functions adapted from libogc's es.c */
//#define DEBUG_ES
//#define DEBUG_IDENT
#define ISALIGNED(x) ((((u32)x)&0x1F)==0)
static u8 su_tmd[0x208] ATTRIBUTE_ALIGN(32);
static u8 su_tik[STD_SIGNED_TIK_SIZE] ATTRIBUTE_ALIGN(32);
int su_id_filled = 0;
/* Reads a file from ISFS to an array in memory */
s32 ISFS_ReadFileToArray (const char *filepath, u8 *filearray, u32 max_size, u32 *file_size) {
s32 ret, fd;
static fstats filestats ATTRIBUTE_ALIGN(32);
*file_size = 0;
ret = ISFS_Open(filepath, ISFS_OPEN_READ);
if (ret <= 0)
{
//printf("Error! ISFS_Open (ret = %d)\n", ret);
return -1;
}
fd = ret;
ret = ISFS_GetFileStats(fd, &filestats);
if (ret < 0)
{
//printf("Error! ISFS_GetFileStats (ret = %d)\n", ret);
return -1;
}
*file_size = filestats.file_length;
if (*file_size > max_size)
{
//printf("File is too large! Size: %u Max: %u", *file_size, max_size);
return -1;
}
ret = ISFS_Read(fd, filearray, *file_size);
*file_size = ret;
if (ret < 0)
{
//printf("Error! ISFS_Read (ret = %d)\n", ret);
return -1;
}
else if (ret != filestats.file_length)
{
//printf("Error! ISFS_Read Only read: %d\n", ret);
return -1;
}
ret = ISFS_Close(fd);
if (ret < 0)
{
//printf("Error! ISFS_Close (ret = %d)\n", ret);
return -1;
}
return 0;
}
void Make_SUID(void){
signed_blob *s_tmd, *s_tik;
tmd *p_tmd;
tik *p_tik;
memset(su_tmd, 0, sizeof su_tmd);
memset(su_tik, 0, sizeof su_tik);
s_tmd = (signed_blob*)&su_tmd[0];
s_tik = (signed_blob*)&su_tik[0];
*s_tmd = *s_tik = 0x10001;
p_tmd = (tmd*)SIGNATURE_PAYLOAD(s_tmd);
p_tik = (tik*)SIGNATURE_PAYLOAD(s_tik);
strcpy(p_tmd->issuer, "Root-CA00000001-CP00000004");
p_tmd->title_id = TITLE_ID(1,2);
p_tmd->num_contents = 1;
forge_tmd(s_tmd);
strcpy(p_tik->issuer, "Root-CA00000001-XS00000003");
p_tik->ticketid = 0x000038A45236EE5FLL;
p_tik->titleid = TITLE_ID(1,2);
memset(p_tik->cidx_mask, 0xFF, 0x20);
forge_tik(s_tik);
su_id_filled = 1;
}
s32 Identify(const u8 *certs, u32 certs_size, const u8 *idtmd, u32 idtmd_size, const u8 *idticket, u32 idticket_size) {
s32 ret;
u32 keyid = 0;
ret = ES_Identify((signed_blob*)certs, certs_size, (signed_blob*)idtmd, idtmd_size, (signed_blob*)idticket, idticket_size, &keyid);
/*if (ret < 0){
switch(ret){
case ES_EINVAL:
printf("Error! ES_Identify (ret = %d;) Data invalid!\n", ret);
break;
case ES_EALIGN:
printf("Error! ES_Identify (ret = %d;) Data not aligned!\n", ret);
break;
case ES_ENOTINIT:
printf("Error! ES_Identify (ret = %d;) ES not initialized!\n", ret);
break;
case ES_ENOMEM:
printf("Error! ES_Identify (ret = %d;) No memory!\n", ret);
break;
default:
printf("Error! ES_Identify (ret = %d)\n", ret);
break;
}
}
else
printf("OK!\n");*/
return ret;
}
s32 Identify_SU(void) {
if (!su_id_filled)
Make_SUID();
//printf("\nIdentifying as SU...");
//fflush(stdout);
return Identify(certs_dat, certs_dat_size, su_tmd, sizeof su_tmd, su_tik, sizeof su_tik);
}
s32 Identify_SysMenu(void) {
s32 ret;
u32 sysmenu_tmd_size, sysmenu_ticket_size;
//static u8 certs[0xA00] ATTRIBUTE_ALIGN(32);
static u8 sysmenu_tmd[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
static u8 sysmenu_ticket[STD_SIGNED_TIK_SIZE] ATTRIBUTE_ALIGN(32);
/*printf("\nPulling Certs...");
ret = ISFS_ReadFileToArray ("/sys/certs.sys", certs, 0xA00, &certs_size);
if (ret < 0) {
printf("\tReading Certs failed!\n");
return -1;
}*/
//printf("\nPulling Sysmenu TMD...");
ret = ISFS_ReadFileToArray ("/title/00000001/00000002/content/title.tmd", sysmenu_tmd, MAX_SIGNED_TMD_SIZE, &sysmenu_tmd_size);
if (ret < 0) {
//printf("\tReading TMD failed!\n");
return -1;
}
//printf("\nPulling Sysmenu Ticket...");
ret = ISFS_ReadFileToArray ("/ticket/00000001/00000002.tik", sysmenu_ticket, STD_SIGNED_TIK_SIZE, &sysmenu_ticket_size);
if (ret < 0) {
//printf("\tReading TMD failed!\n");
return -1;
}
//printf("\nIdentifying as SysMenu...");
//fflush(stdout);
return Identify(certs_dat, certs_dat_size, sysmenu_tmd, sysmenu_tmd_size, sysmenu_ticket, sysmenu_ticket_size);
}

38
source/wad/id.h Normal file
View File

@ -0,0 +1,38 @@
/*-------------------------------------------------------------
id.h -- ES Identification code
Copyright (C) 2008 tona
Unless other credit specified
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1.The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2.Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3.This notice may not be removed or altered from any source
distribution.
-------------------------------------------------------------*/
#ifndef _ID_H_
#define _ID_H_
// Identify as the "super user"
s32 Identify_SU(void);
// Identify as the system menu
s32 Identify_SysMenu(void);
#endif

View File

@ -0,0 +1,94 @@
/* patchmii_core -- low-level functions to handle the downloading, patching
and installation of updates on the Wii
Copyright (C) 2008 bushing / hackmii.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ogcsys.h>
#include <gccore.h>
#include <stdarg.h>
#include <ctype.h>
#include <unistd.h>
#include <network.h>
#include <sys/errno.h>
#include "patchmii_core.h"
#include "sha1.h"
#define ALIGN(a,b) ((((a)+(b)-1)/(b))*(b))
int http_status = 0;
int tmd_dirty = 0, tik_dirty = 0, temp_ios_slot = 0;
// yeah, yeah, I know.
signed_blob *s_tmd = NULL, *s_tik = NULL, *s_certs = NULL;
static u8 tmdbuf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(0x20);
static u8 tikbuf[STD_SIGNED_TIK_SIZE] ATTRIBUTE_ALIGN(0x20);
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));
}

View File

@ -0,0 +1,63 @@
#ifndef _PATCHMII_CORE_
#define _PATCHMII_CORE_
//Patchmii functions
void patchmii_network_init(void);
// Call with version = 0 to get the latest version
// Set "patch" if you want to try to patch title contents
s32 patchmii_install(u32 in_title_h, u32 in_title_l, u32 in_version, u32 out_title_h, u32 out_title_l, u32 out_version, bool patch);
s32 install_temporary_ios(u32 base_ios, u32 base_ver);
s32 load_temporary_ios(void);
s32 cleanup_temporary_ios(void);
//Tools
void forge_tmd(signed_blob *s_tmd);
void forge_tik(signed_blob *s_tik);
void spinner(void);
#define TEMP_IOS
// Basic I/O.
static inline u32 read32(u32 addr)
{
u32 x;
asm volatile("lwz %0,0(%1) ; sync" : "=r"(x) : "b"(0xc0000000 | addr));
return x;
}
static inline void write32(u32 addr, u32 x)
{
asm("stw %0,0(%1) ; eieio" : : "r"(x), "b"(0xc0000000 | addr));
}
// USB Gecko.
void usb_flush(int chn);
int usb_sendbuffer(int chn,const void *buffer,int size);
// Version string.
extern const char version[];
// Debug: blink the tray led.
static inline void blink(void)
{
write32(0x0d8000c0, read32(0x0d8000c0) ^ 0x20);
}
void debug_printf(const char *fmt, ...);
void hexdump(FILE *fp, void *d, int len);
void aes_set_key(u8 *key);
void aes_decrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len);
void aes_encrypt(u8 *iv, u8 *inbuf, u8 *outbuf, unsigned long long len);
#define TRACE(x) debug_printf("%s / %d: %d\n", __FUNCTION__, __LINE__, (x))
#define ISFS_ACCESS_READ 1
#define ISFS_ACCESS_WRITE 2
#endif

172
source/wad/sha1.c Normal file
View File

@ -0,0 +1,172 @@
/*
SHA-1 in C
By Steve Reid <steve@edmweb.com>
100% Public Domain
Test Vectors (from FIPS PUB 180-1)
"abc"
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
A million repetitions of "a"
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd if true. */
#define SHA1HANDSOFF
#include <stdio.h>
#include <string.h>
#include "sha1.h"
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#ifdef LITTLE_ENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
#define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
{
unsigned long a, b, c, d, e;
typedef union {
unsigned char c[64];
unsigned long l[16];
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
static unsigned char workspace[64];
block = (CHAR64LONG16*)workspace;
memcpy(block, buffer, 64);
#else
block = (CHAR64LONG16*)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void SHA1Init(SHA1_CTX* context)
{
/* SHA1 initialization constants */
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
{
unsigned int i, j;
j = (context->count[0] >> 3) & 63;
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
context->count[1] += (len >> 29);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64-j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
{
unsigned long i, j;
unsigned char finalcount[8];
for (i = 0; i < 8; i++) {
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
}
SHA1Update(context, (unsigned char *)"\200", 1);
while ((context->count[0] & 504) != 448) {
SHA1Update(context, (unsigned char *)"\0", 1);
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
for (i = 0; i < 20; i++) {
digest[i] = (unsigned char)
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
}
/* Wipe variables */
i = j = 0;
memset(context->buffer, 0, 64);
memset(context->state, 0, 20);
memset(context->count, 0, 8);
memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
SHA1Transform(context->state, context->buffer);
#endif
}
void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf) {
SHA1_CTX ctx;
SHA1Init(&ctx);
SHA1Update(&ctx, ptr, size);
SHA1Final(outbuf, &ctx);
}

12
source/wad/sha1.h Normal file
View File

@ -0,0 +1,12 @@
typedef struct {
unsigned long state[5];
unsigned long count[2];
unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(unsigned long state[5], unsigned char buffer[64]);
void SHA1Init(SHA1_CTX* context);
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len);
void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf);

View File

@ -8,6 +8,7 @@
#include "utils.h"
#include "../settings/cfg.h"
#include "fatmounter.h"
#include "id.h"
#define MAX_TITLES 256
@ -260,6 +261,113 @@ out:
return ret;
}
s32 Uninstall_RemoveTicket(u64 tid)
{
static tikview viewdata[0x10] ATTRIBUTE_ALIGN(32);
u32 cnt, views;
s32 ret;
/* Get number of ticket views */
ret = ES_GetNumTicketViews(tid, &views);
if (ret < 0) {
return ret;
}
if (!views) {
//printf(" No tickets found!\n");
return 1;
} else if (views > 16) {
//printf(" Too many ticket views! (views = %d)\n", views);
return -1;
}
/* Get ticket views */
ret = ES_GetTicketViews(tid, viewdata, views);
if (ret < 0) {
//printf(" \n\tError! ES_GetTicketViews (ret = %d)\n", ret);
return ret;
}
/* Remove tickets */
for (cnt = 0; cnt < views; cnt++) {
ret = ES_DeleteTicket(&viewdata[cnt]);
if (ret < 0) {
//printf(" Error! (view = %d, ret = %d)\n", cnt, ret);
return ret;
}
}
//printf(" OK!\n");
return ret;
}
s32 Uninstall_DeleteTitle(u32 title_u, u32 title_l)
{
s32 ret;
char filepath[256];
sprintf(filepath, "/title/%08x/%08x", title_u, title_l);
/* Remove title */
ret = ISFS_Delete(filepath);
return ret;
}
s32 Uninstall_DeleteTicket(u32 title_u, u32 title_l)
{
s32 ret;
char filepath[256];
sprintf(filepath, "/ticket/%08x/%08x.tik", title_u, title_l);
/* Delete ticket */
ret = ISFS_Delete(filepath);
return ret;
}
//carefull when using this function
//it will force remove stuff even if something fails
s32 Uninstall_FromTitle(const u64 tid)
{
s32 contents_ret, tik_ret, title_ret, ret;
u32 id = tid & 0xFFFFFFFF, kind = tid >> 32;
contents_ret = tik_ret = title_ret = ret = 0;
if (kind == 1)
{
// Delete title and ticket at FS level.
tik_ret = Uninstall_DeleteTicket(kind, id);
title_ret = Uninstall_DeleteTitle(kind, id);
contents_ret = title_ret;
}
else
{
// Remove title (contents and ticket)
tik_ret = Uninstall_RemoveTicket(tid);
contents_ret = ES_DeleteTitleContent(tid);
title_ret = ES_DeleteTitle(tid);
// Attempt forced uninstall if something fails
if (tik_ret < 0 || contents_ret < 0 || title_ret < 0){
tik_ret = Uninstall_DeleteTicket(kind, id);
title_ret = Uninstall_DeleteTitle(kind, id);
contents_ret = title_ret;
}
}
if (tik_ret < 0 && contents_ret < 0 && title_ret < 0)
ret = -1;
else if (tik_ret < 0 || contents_ret < 0 || title_ret < 0)
ret = 1;
else
ret = 0;
return ret;
}
/*-------------------------------------------------------------
taken from anytitledeleter
@ -268,104 +376,6 @@ out:
Copyright (C) 2009 MrClick
-------------------------------------------------------------*/
// Max number of entries in the database
#define MAX_DB 1024
// Max name length
#define MAX_LINE 80
// Contains all title ids (e.g.: "HAC")
static char **__db_i;
// Contains all title names (e.g.: "Mii Channel")
static char **__db;
// Contains the number of entries in the database
static u32 __db_cnt = 0;
s32 loadDatabase(){
FILE *fdb;
char dbfile[100];
snprintf(dbfile,sizeof(dbfile),"SD:/database.txt");
// Init SD card access, open database file and check if it worked
//fatInitDefault();
SDCard_Init();
fdb = fopen(dbfile, "r");
if (fdb == NULL)
return -1;
// Allocate memory for the database
__db_i = calloc(MAX_DB, sizeof(char*));
__db = calloc(MAX_DB, sizeof(char*));
// Define the line buffer. Each line in the db file will be stored here first
char line[MAX_LINE];
line[sizeof(line)] = 0;
// Generic char buffer and counter variable
char byte;
u32 i = 0;
// Read each character from the file
do {
byte = fgetc(fdb);
// In case a line was longer than MAX_LINE
if (i == -1){
// Read bytes till a new line is hit
if (byte == 0x0A)
i = 0;
// In case were still good with the line length
} else {
// Add the new byte to the line buffer
line[i] = byte;
i++;
// When a new line is hit or MAX_LINE is reached
if (byte == 0x0A || i == sizeof(line) - 1) {
// Terminate finished line to create a string
line[i] = 0;
// When the line is not a comment or not to short
if (line[0] != '#' && i > 5){
// Allocate and copy title id to database
__db_i[__db_cnt] = calloc(4, sizeof(char*));
memcpy(__db_i[__db_cnt], line, 3);
__db_i[__db_cnt][3] = 0;
// Allocate and copy title name to database
__db[__db_cnt] = calloc(i - 4, sizeof(char*));
memcpy(__db[__db_cnt], line + 4, i - 4);
__db[__db_cnt][i - 5] = 0;
// Check that the next line does not overflow the database
__db_cnt++;
if (__db_cnt == MAX_DB)
break;
}
// Set routine to ignore all bytes in the line when MAX_LINE is reached
if (byte == 0x0A) i = 0; else i = -1;
}
}
} while (!feof(fdb));
// Close database file; we are done with it
fclose(fdb);
return 0;
}
void freeDatabase(){
u32 i = 0;
for(; i < __db_cnt; i++){
free(__db_i[i]);
free(__db[i]);
}
free(__db_i);
free(__db);
}
s32 getDatabaseCount(){
return __db_cnt;
}
s32 __convertWiiString(char *str, u8 *data, u32 cnt){
u32 i = 0;
@ -385,47 +395,6 @@ s32 __convertWiiString(char *str, u8 *data, u32 cnt){
return 0;
}
s32 getNameDB(char* name, char* id){
// Return fixed values for special entries
if (strncmp(id, "IOS", 3) == 0){
sprintf(name, "Operating System %s", id);
return 0;
}
if (strncmp(id, "MIOS", 3) == 0){
sprintf(name, "Gamecube Compatibility Layer");
return 0;
}
if (strncmp(id, "SYSMENU", 3) == 0){
sprintf(name, "System Menu");
return 0;
}
if (strncmp(id, "BC", 2) == 0){
sprintf(name, "BC");
return 0;
}
// Create an ? just in case the function aborts prematurely
sprintf(name, "?");
u32 i;
u8 db_found = 0;
// Compare each id in the database to the title id
for (i = 0; i < __db_cnt; i++)
if (strncmp(id, __db_i[i], 3) == 0){
db_found = 1;
break;
}
if (db_found == 0)
// Return -1 if no mathcing entry was found
return -1;
else {
// Get name from database once a matching id was found
sprintf(name, __db[i]);
return 0;
}
}
s32 getNameBN(char* name, u64 id){
// Terminate the name string just in case the function exits prematurely
@ -438,9 +407,9 @@ s32 getNameBN(char* name, u64 id){
// Bring the Wii into the title's userspace
if (ES_SetUID(id) < 0){
// Should that fail repeat after setting permissions to system menu mode
// Identify_SysMenu();
// if (ES_SetUID(id) < 0)
// return -1;
Identify_SysMenu();
if (ES_SetUID(id) < 0)
return -1;
}
// Try to open file
@ -452,8 +421,8 @@ s32 getNameBN(char* name, u64 id){
// If it fails try to open again after identifying as SU
if (fh == -102){
// Identify_SU();
// fh = ISFS_Open(file, ISFS_OPEN_READ);
Identify_SU();
fh = ISFS_Open(file, ISFS_OPEN_READ);
}
// If the file won't open
else if (fh < 0)
@ -494,11 +463,21 @@ s32 getNameBN(char* name, u64 id){
}
s32 getName00(char* name, u64 id){
s32 getName00(char* name, u64 id, int lang){
/*
languages
0jap
2eng
4german
6french
8spanish
10italian
12dutch
*/
// Create a string containing the absolute filename
char file[256] __attribute__ ((aligned (32)));
sprintf(file, "/title/%08x/%08x/content/00000000.app", (u32)(id >> 32), (u32)id);
Identify_SU();
s32 fh = ISFS_Open(file, ISFS_OPEN_READ);
@ -510,8 +489,8 @@ s32 getName00(char* name, u64 id){
// In case there is some problem with the permission
if (fh == -102){
// Identify as super user
// Identify_SU();
// fh = ISFS_Open(file, ISFS_OPEN_READ);
Identify_SU();
fh = ISFS_Open(file, ISFS_OPEN_READ);
}
else if (fh < 0)
return fh;
@ -541,12 +520,16 @@ s32 getName00(char* name, u64 id){
free(data);
// Assemble name
// Only the English name is returned
// There are 6 other language names in the str array
sprintf(name, "%s", str[2]);
if (strlen(str[3]) > 1)
sprintf(name, "%s (%s)", name, str[3]);
if(strlen(str[lang]) > 1){
sprintf(name, "%s", str[lang]);
if (strlen(str[lang+1]) > 1)
sprintf(name, "%s (%s)", name, str[lang+1]);
}
else{
sprintf(name, "%s", str[2]);
if (strlen(str[3]) > 1)
sprintf(name, "%s (%s)", name, str[3]);
}
// Job well done
return 2;
}
@ -575,35 +558,6 @@ s32 printContent(u64 tid){
}
s32 getTitle_Name(char* name, u64 id, char *tid){
char buf[256] __attribute__ ((aligned (32)));
s32 r = -1;
// Determine the title's name database/banner/00000000.app
r = getNameDB(buf, tid);
if (r < 0)
r = getNameBN(buf, id);
if (r < 0)
r = getName00(buf, id);
switch (r){
// In case a name was found in the database
case 0: sprintf(name, "%s", buf);
break;
// In case a name was found in the banner.bin
case 1: sprintf(name, "*%s*", buf);
break;
// In case a name was found in the 00000000.app
case 2: sprintf(name, "+%s+", buf);
break;
// In case no proper name was found return a ?
default: sprintf(name, "Unknown Title");
break;
}
return 0;
}
char *titleText(u32 kind, u32 title){
static char text[10];
@ -684,7 +638,7 @@ s32 getTitles_TypeCount(u32 type, u32 *count) {
upper = __title_list[i] >> 32;
lower = __title_list[i] & 0xFFFFFFFF;
if((upper == type)&&
((lower !=0x48414741)&&//this filters out haga,haaa, hafa. dupe foctory channels that don't load
((lower !=0x48414741)&&//this filters out haga,haaa, hafa. dupe factory channels that don't load
(lower !=0x48414141)&&//since we dont care about apps that dont load for what we are doing
(lower !=0x48414641)))
type_count++;
@ -721,3 +675,6 @@ s32 getTitles_Type(u32 type, u32 *titles, u32 count) {
}

View File

@ -39,26 +39,11 @@ s32 Title_GetSysVersion(u64, u64 *);
s32 Title_GetSize(u64, u32 *);
s32 Title_GetIOSVersions(u8 **, u32 *);
// Load the database from SD card
s32 loadDatabase();
// Free the database on exit
void freeDatabase();
// Get the number of entries in the database
s32 getDatabaseCount();
// Get the name of a title
s32 getTitle_Name(char *name, u64 id, char *tid);
// Get the name of a title from the database located on the SD card
s32 getNameDB(char *name, char* id);
// Get the name of a title from its banner.bin in NAND
s32 getNameBN(char *name, u64 id);
// Get the name of a title from its 00000000.app in NAND
s32 getName00(char *name, u64 id);
s32 getName00(char *name, u64 id, int lang = 2);
// Get string representation of lower title id
char *titleText(u32 kind, u32 title);
@ -72,6 +57,11 @@ s32 getTitles_TypeCount(u32 type, u32 *count);
// Get the list of titles of this type
s32 getTitles_Type(u32 type, u32 *titles, u32 count);
//returns a name for a title
char *__getTitleName(u64 titleid, int language);
s32 Uninstall_FromTitle(const u64 tid);
#ifdef __cplusplus
}
#endif

View File

@ -331,7 +331,7 @@ void LoadTitlesFromXML(char *langtxt, bool forcejptoen)
strcpy(title_text,title_text_EN);
}
snprintf(id_text, 5, "%s",id_text);
snprintf(id_text, 7, "%s",id_text);
title_set(id_text, title_text);
}
}