makerom: misc and small changes

Altered behaviour to make CIA file generated to more closely match CIAs
made by Nintendo's private CIA generator. As seen in gamecard updates.
This commit is contained in:
applestash
2014-09-18 11:03:57 +10:00
parent 744abbe852
commit 274b523e9c
3 changed files with 71 additions and 43 deletions
+68 -42
View File
@@ -175,7 +175,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
}
// Ticket Data
ciaset->tik.ticketId = u64GetRand();
ciaset->tik.ticketId = u64GetRand() & 0x0004FFFFFFFFFFFF;
ciaset->tik.deviceId = usrset->cia.deviceId;
ciaset->tik.eshopAccId = usrset->cia.eshopAccId;
ciaset->tik.licenceType = lic_Permanent;
@@ -235,9 +235,9 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
GetNcchInfo(info,hdr);
/* Verify Ncch0 (Sig&Hash Checks) */
int result = VerifyNcch(ncch0,ciaset->keys,false,true);
int result = VerifyNcch(ncch0, ciaset->keys, false, ciaset->verbose == false);
if(result == UNABLE_TO_LOAD_NCCH_KEY){
ciaset->content.keyNotFound = true;
ciaset->content.keyFound = false;
if(!ciaset->content.IsCfa){
fprintf(stderr,"[CIA WARNING] CXI AES Key could not be loaded\n");
fprintf(stderr," Meta Region, SaveDataSize, Remaster Version cannot be obtained\n");
@@ -254,7 +254,7 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
/* Getting ncch key */
u8 *ncchkey = NULL;
if(!ciaset->content.keyNotFound && IsNcchEncrypted(hdr)){
if(ciaset->content.keyFound && IsNcchEncrypted(hdr)){
SetNcchKeys(ciaset->keys,hdr);
ncchkey = ciaset->keys->aes.ncchKey0;
if(ciaset->verbose){
@@ -278,90 +278,116 @@ finish:
int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key)
{
extended_hdr *exhdr = malloc(sizeof(extended_hdr));
memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr));
if(key != NULL)
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx->titleId,key,ncch_exhdr);
int result = 0;
extended_hdr *exhdr = NULL;
if(!ciaset->content.IsCfa && ciaset->content.keyFound){
exhdr = malloc(sizeof(extended_hdr));
memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr));
if(key != NULL)
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx->titleId,key,ncch_exhdr);
}
if(IsPatch(GetTidCategory(ciaset->common.titleId))||ciaset->content.IsCfa)
// If this title is a Patch or a CFA SaveData size cannot be set in TMD
if( IsPatch(GetTidCategory(ciaset->common.titleId)) || ciaset->content.IsCfa )
ciaset->tmd.savedataSize = 0;
else if(!ciaset->content.keyNotFound)
// Otherwise read Savedata size from exheader, but only first word of savesize is read
else if(ciaset->content.keyFound)
ciaset->tmd.savedataSize = (u32)(GetSaveDataSize_frm_exhdr(exhdr) & MAX_U32);
else if(ciaset->rsf->SystemControlInfo.SaveDataSize){ // if it's a title which can have save data, but save data size could not be read from exhdr
// if it's a title which can have save data, but save data size could not be read from exhdr
else if(ciaset->rsf->SystemControlInfo.SaveDataSize){
u64 size = 0;
GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA");
ciaset->tmd.savedataSize = (u32)(size & MAX_U32);
}
// the user has neglected to provide any means of determining the savedata size
else
ciaset->tmd.savedataSize = 0;
if(ciaset->content.IsCfa||ciaset->content.keyNotFound){
// Process title version
// If this is a CFA, the -major must be set, since CFAs don't have an exheader
if(ciaset->content.IsCfa){
if(ciaset->common.titleVersion[VER_MAJOR] == MAX_U16){ // '-major' wasn't set
if(ciaset->content.IsCfa){ // Is a CFA and can be decrypted
fprintf(stderr,"[CIA ERROR] Invalid major version. Use \"-major\" option.\n");
return CIA_BAD_VERSION;
}
else // CXI which cannot be decrypted
ciaset->common.titleVersion[VER_MAJOR] = 0;
fprintf(stderr,"[CIA ERROR] Invalid major version. Use \"-major\" option.\n");
result = CIA_BAD_VERSION;
goto cleanup;
}
}
else{ // Is a CXI and can be decrypted
// Otherwise this is a CXI, if it can be decrypted, -major cannot be set and must be read from exheader
else if(ciaset->content.keyFound){
if(ciaset->common.titleVersion[VER_MAJOR] != MAX_U16){ // '-major' was set
fprintf(stderr,"[CIA ERROR] Option \"-major\" cannot be applied for cxi.\n");
return CIA_BAD_VERSION;
result = CIA_BAD_VERSION;
goto cleanup;
}
// Setting remaster ver
ciaset->common.titleVersion[VER_MAJOR] = GetRemasterVersion_frm_exhdr(exhdr);
}
// CXI which cannot be decrypted
else{
if(ciaset->common.titleVersion[VER_MAJOR] == MAX_U16) // '-major' wasn't set
ciaset->common.titleVersion[VER_MAJOR] = 0;
}
// Calculate u16 title version
ciaset->tmd.version = ciaset->tik.version = SetupVersion(ciaset->common.titleVersion[VER_MAJOR],ciaset->common.titleVersion[VER_MINOR],ciaset->common.titleVersion[VER_MICRO]);
cleanup:
free(exhdr);
return 0;
return result;
}
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_info *info, u8 *key)
{
if(ciaset->content.IsCfa || ciaset->content.keyNotFound)
extended_hdr *exhdr;
exefs_hdr *exefsHdr;
cia_metadata *hdr;
u32 icon_size, icon_offset;
// Do not proceed if this is a CFA or can't be decrypted
if(ciaset->content.IsCfa || !ciaset->content.keyFound)
return 0;
extended_hdr *exhdr = malloc(sizeof(extended_hdr));
// Obtain (&decrypt) exheader
exhdr = malloc(sizeof(extended_hdr));
memcpy(exhdr,ncch+info->exhdrOffset,sizeof(extended_hdr));
if(key != NULL)
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,info->titleId,key,ncch_exhdr);
exefs_hdr *exefsHdr = malloc(sizeof(exefs_hdr));
// Obtain (&decrypt) exefs header
exefsHdr = malloc(sizeof(exefs_hdr));
memcpy(exefsHdr,ncch+info->exefsOffset,sizeof(exefs_hdr));
if(key != NULL)
CryptNcchRegion((u8*)exefsHdr,sizeof(exefs_hdr),0,info->titleId,key,ncch_exefs);
u32 icon_size = 0;
u32 icon_offset = 0;
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
if(strncmp(exefsHdr->fileHdr[i].name,"icon",8) == 0){
icon_size = u8_to_u32(exefsHdr->fileHdr[i].size,LE);
icon_offset = u8_to_u32(exefsHdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr);
}
}
// Only continue if icon exists
if(!DoesExeFsSectionExist("icon",(u8*)exefsHdr))
goto cleanup;
icon_size = GetExeFsSectionSize("icon",(u8*)exefsHdr);
icon_offset = GetExeFsSectionOffset("icon",(u8*)exefsHdr);
// Allocating memory for Meta region
ciaset->ciaSections.meta.size = sizeof(cia_metadata) + icon_size;
ciaset->ciaSections.meta.buffer = malloc(ciaset->ciaSections.meta.size);
ciaset->ciaSections.meta.buffer = calloc(1,ciaset->ciaSections.meta.size);
if(!ciaset->ciaSections.meta.buffer){
fprintf(stderr,"[CIA ERROR] Not enough memory\n");
return MEM_ERROR;
}
cia_metadata *hdr = (cia_metadata*)ciaset->ciaSections.meta.buffer;
memset(hdr,0,sizeof(cia_metadata));
// Writing Dependency List & Core Version to Meta region
hdr = (cia_metadata*)ciaset->ciaSections.meta.buffer;
GetDependencyList_frm_exhdr(hdr->dependencyList,exhdr);
GetCoreVersion_frm_exhdr(hdr->coreVersion,exhdr);
if(icon_size > 0){
u8 *IconDestPos = (ciaset->ciaSections.meta.buffer + sizeof(cia_metadata));
memcpy(IconDestPos,ncch+info->exefsOffset+icon_offset,icon_size);
if(key != NULL)
CryptNcchRegion(IconDestPos,icon_size,icon_offset,info->titleId,key,ncch_exefs);
//memdump(stdout,"Icon: ",IconDestPos,0x10);
}
// Writing Icon data to Meta region
u8 *iconPos = (ciaset->ciaSections.meta.buffer + sizeof(cia_metadata));
memcpy(iconPos,ncch+info->exefsOffset+icon_offset,icon_size);
if(key != NULL)
CryptNcchRegion(iconPos,icon_size,icon_offset,info->titleId,key,ncch_exefs);
cleanup:
free(exefsHdr);
free(exhdr);
return 0;
+1 -1
View File
@@ -66,7 +66,7 @@ typedef struct
bool encryptCia;
bool includeUpdateNcch; // for cci -> cia conversions
bool keyNotFound;
bool keyFound;
FILE **filePtrs;
u64 fileSize[CIA_MAX_CONTENT];
+2
View File
@@ -1011,6 +1011,8 @@ bool SetNcchKeys(keys_struct *keys, ncch_hdr *hdr)
int GetNcchInfo(ncch_info *info, ncch_hdr *hdr)
{
clrmem(info, sizeof(ncch_info));
info->titleId = u8_to_u64(hdr->titleId,LE);
info->programId = u8_to_u64(hdr->programId,LE);