Merge pull request #21 from 3DSGuy/unstable

Merged unstable into master
This commit is contained in:
applestash
2014-09-18 09:10:03 +08:00
5 changed files with 87 additions and 61 deletions
+69 -42
View File
@@ -175,7 +175,7 @@ int GetSettingsFromUsrset(cia_settings *ciaset, user_settings *usrset)
} }
// Ticket Data // Ticket Data
ciaset->tik.ticketId = u64GetRand(); ciaset->tik.ticketId = u64GetRand() & 0x0004FFFFFFFFFFFF;
ciaset->tik.deviceId = usrset->cia.deviceId; ciaset->tik.deviceId = usrset->cia.deviceId;
ciaset->tik.eshopAccId = usrset->cia.eshopAccId; ciaset->tik.eshopAccId = usrset->cia.eshopAccId;
ciaset->tik.licenceType = lic_Permanent; ciaset->tik.licenceType = lic_Permanent;
@@ -235,9 +235,10 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
GetNcchInfo(info,hdr); GetNcchInfo(info,hdr);
/* Verify Ncch0 (Sig&Hash Checks) */ /* Verify Ncch0 (Sig&Hash Checks) */
int result = VerifyNcch(ncch0,ciaset->keys,false,true); ciaset->content.keyFound = true;
int result = VerifyNcch(ncch0, ciaset->keys, false, ciaset->verbose == false);
if(result == UNABLE_TO_LOAD_NCCH_KEY){ if(result == UNABLE_TO_LOAD_NCCH_KEY){
ciaset->content.keyNotFound = true; ciaset->content.keyFound = false;
if(!ciaset->content.IsCfa){ if(!ciaset->content.IsCfa){
fprintf(stderr,"[CIA WARNING] CXI AES Key could not be loaded\n"); fprintf(stderr,"[CIA WARNING] CXI AES Key could not be loaded\n");
fprintf(stderr," Meta Region, SaveDataSize, Remaster Version cannot be obtained\n"); fprintf(stderr," Meta Region, SaveDataSize, Remaster Version cannot be obtained\n");
@@ -254,7 +255,7 @@ int GetSettingsFromNcch0(cia_settings *ciaset, u32 ncch0_offset)
/* Getting ncch key */ /* Getting ncch key */
u8 *ncchkey = NULL; u8 *ncchkey = NULL;
if(!ciaset->content.keyNotFound && IsNcchEncrypted(hdr)){ if(ciaset->content.keyFound && IsNcchEncrypted(hdr)){
SetNcchKeys(ciaset->keys,hdr); SetNcchKeys(ciaset->keys,hdr);
ncchkey = ciaset->keys->aes.ncchKey0; ncchkey = ciaset->keys->aes.ncchKey0;
if(ciaset->verbose){ if(ciaset->verbose){
@@ -278,90 +279,116 @@ finish:
int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key) int GetTmdDataFromNcch(cia_settings *ciaset, u8 *ncch, ncch_info *ncch_ctx, u8 *key)
{ {
extended_hdr *exhdr = malloc(sizeof(extended_hdr)); int result = 0;
memcpy(exhdr,ncch+ncch_ctx->exhdrOffset,sizeof(extended_hdr)); extended_hdr *exhdr = NULL;
if(key != NULL)
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,ncch_ctx->titleId,key,ncch_exhdr); 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; 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); 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; u64 size = 0;
GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA"); GetSaveDataSizeFromString(&size,ciaset->rsf->SystemControlInfo.SaveDataSize,"CIA");
ciaset->tmd.savedataSize = (u32)(size & MAX_U32); ciaset->tmd.savedataSize = (u32)(size & MAX_U32);
} }
// the user has neglected to provide any means of determining the savedata size
else else
ciaset->tmd.savedataSize = 0; 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->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");
fprintf(stderr,"[CIA ERROR] Invalid major version. Use \"-major\" option.\n"); result = CIA_BAD_VERSION;
return CIA_BAD_VERSION; goto cleanup;
}
else // CXI which cannot be decrypted
ciaset->common.titleVersion[VER_MAJOR] = 0;
} }
} }
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 if(ciaset->common.titleVersion[VER_MAJOR] != MAX_U16){ // '-major' was set
fprintf(stderr,"[CIA ERROR] Option \"-major\" cannot be applied for cxi.\n"); 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 // Setting remaster ver
ciaset->common.titleVersion[VER_MAJOR] = GetRemasterVersion_frm_exhdr(exhdr); 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]); 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); free(exhdr);
return 0; return result;
} }
int GetMetaRegion(cia_settings *ciaset, u8 *ncch, ncch_info *info, u8 *key) 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; 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)); memcpy(exhdr,ncch+info->exhdrOffset,sizeof(extended_hdr));
if(key != NULL) if(key != NULL)
CryptNcchRegion((u8*)exhdr,sizeof(extended_hdr),0,info->titleId,key,ncch_exhdr); 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)); memcpy(exefsHdr,ncch+info->exefsOffset,sizeof(exefs_hdr));
if(key != NULL) if(key != NULL)
CryptNcchRegion((u8*)exefsHdr,sizeof(exefs_hdr),0,info->titleId,key,ncch_exefs); CryptNcchRegion((u8*)exefsHdr,sizeof(exefs_hdr),0,info->titleId,key,ncch_exefs);
u32 icon_size = 0; // Only continue if icon exists
u32 icon_offset = 0; if(!DoesExeFsSectionExist("icon",(u8*)exefsHdr))
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){ goto cleanup;
if(strncmp(exefsHdr->fileHdr[i].name,"icon",8) == 0){
icon_size = u8_to_u32(exefsHdr->fileHdr[i].size,LE); icon_size = GetExeFsSectionSize("icon",(u8*)exefsHdr);
icon_offset = u8_to_u32(exefsHdr->fileHdr[i].offset,LE) + sizeof(exefs_hdr); icon_offset = GetExeFsSectionOffset("icon",(u8*)exefsHdr);
}
}
// Allocating memory for Meta region
ciaset->ciaSections.meta.size = sizeof(cia_metadata) + icon_size; 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){ if(!ciaset->ciaSections.meta.buffer){
fprintf(stderr,"[CIA ERROR] Not enough memory\n"); fprintf(stderr,"[CIA ERROR] Not enough memory\n");
return MEM_ERROR; 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); GetDependencyList_frm_exhdr(hdr->dependencyList,exhdr);
GetCoreVersion_frm_exhdr(hdr->coreVersion,exhdr); GetCoreVersion_frm_exhdr(hdr->coreVersion,exhdr);
if(icon_size > 0){
u8 *IconDestPos = (ciaset->ciaSections.meta.buffer + sizeof(cia_metadata)); // Writing Icon data to Meta region
memcpy(IconDestPos,ncch+info->exefsOffset+icon_offset,icon_size); u8 *iconPos = (ciaset->ciaSections.meta.buffer + sizeof(cia_metadata));
if(key != NULL) memcpy(iconPos,ncch+info->exefsOffset+icon_offset,icon_size);
CryptNcchRegion(IconDestPos,icon_size,icon_offset,info->titleId,key,ncch_exefs); if(key != NULL)
//memdump(stdout,"Icon: ",IconDestPos,0x10); CryptNcchRegion(iconPos,icon_size,icon_offset,info->titleId,key,ncch_exefs);
}
cleanup:
free(exefsHdr); free(exefsHdr);
free(exhdr); free(exhdr);
return 0; return 0;
+1 -1
View File
@@ -66,7 +66,7 @@ typedef struct
bool encryptCia; bool encryptCia;
bool includeUpdateNcch; // for cci -> cia conversions bool includeUpdateNcch; // for cci -> cia conversions
bool keyNotFound; bool keyFound;
FILE **filePtrs; FILE **filePtrs;
u64 fileSize[CIA_MAX_CONTENT]; u64 fileSize[CIA_MAX_CONTENT];
+14 -17
View File
@@ -126,23 +126,20 @@ int get_ExHeaderSettingsFromNcchset(exheader_settings *exhdrset, ncch_settings *
exhdrset->exHdr = (extended_hdr*)ncchset->sections.exhdr.buffer; exhdrset->exHdr = (extended_hdr*)ncchset->sections.exhdr.buffer;
exhdrset->acexDesc = (access_descriptor*)ncchset->sections.acexDesc.buffer; exhdrset->acexDesc = (access_descriptor*)ncchset->sections.acexDesc.buffer;
/* Set Code Info if Code Section was built not imported */ /* BSS Size */
if(ncchset->options.IsBuildingCodeSection){ u32_to_u8(exhdrset->exHdr->codeSetInfo.bssSize,ncchset->codeDetails.bssSize,LE);
/* BSS Size */ /* Data */
u32_to_u8(exhdrset->exHdr->codeSetInfo.bssSize,ncchset->codeDetails.bssSize,LE); u32_to_u8(exhdrset->exHdr->codeSetInfo.data.address,ncchset->codeDetails.rwAddress,LE);
/* Data */ u32_to_u8(exhdrset->exHdr->codeSetInfo.data.codeSize,ncchset->codeDetails.rwSize,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.data.address,ncchset->codeDetails.rwAddress,LE); u32_to_u8(exhdrset->exHdr->codeSetInfo.data.numMaxPages,ncchset->codeDetails.rwMaxPages,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.data.codeSize,ncchset->codeDetails.rwSize,LE); /* RO */
u32_to_u8(exhdrset->exHdr->codeSetInfo.data.numMaxPages,ncchset->codeDetails.rwMaxPages,LE); u32_to_u8(exhdrset->exHdr->codeSetInfo.rodata.address,ncchset->codeDetails.roAddress,LE);
/* RO */ u32_to_u8(exhdrset->exHdr->codeSetInfo.rodata.codeSize,ncchset->codeDetails.roSize,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.rodata.address,ncchset->codeDetails.roAddress,LE); u32_to_u8(exhdrset->exHdr->codeSetInfo.rodata.numMaxPages,ncchset->codeDetails.roMaxPages,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.rodata.codeSize,ncchset->codeDetails.roSize,LE); /* Text */
u32_to_u8(exhdrset->exHdr->codeSetInfo.rodata.numMaxPages,ncchset->codeDetails.roMaxPages,LE); u32_to_u8(exhdrset->exHdr->codeSetInfo.text.address,ncchset->codeDetails.textAddress,LE);
/* Text */ u32_to_u8(exhdrset->exHdr->codeSetInfo.text.codeSize,ncchset->codeDetails.textSize,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.text.address,ncchset->codeDetails.textAddress,LE); u32_to_u8(exhdrset->exHdr->codeSetInfo.text.numMaxPages,ncchset->codeDetails.textMaxPages,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.text.codeSize,ncchset->codeDetails.textSize,LE);
u32_to_u8(exhdrset->exHdr->codeSetInfo.text.numMaxPages,ncchset->codeDetails.textMaxPages,LE);
}
/* Set Simple Flags */ /* Set Simple Flags */
if(ncchset->options.CompressCode) if(ncchset->options.CompressCode)
+2
View File
@@ -1011,6 +1011,8 @@ bool SetNcchKeys(keys_struct *keys, ncch_hdr *hdr)
int GetNcchInfo(ncch_info *info, 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->titleId = u8_to_u64(hdr->titleId,LE);
info->programId = u8_to_u64(hdr->programId,LE); info->programId = u8_to_u64(hdr->programId,LE);
+1 -1
View File
@@ -577,7 +577,7 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set)
} }
// Other Setting // Other Setting
else if(strcmp(argv[i],"-content") == 0){ else if(strcmp(argv[i],"-content") == 0 || strcmp(argv[i],"-i") == 0){
if(ParamNum != 1){ if(ParamNum != 1){
PrintArgReqParam(argv[i],1); PrintArgReqParam(argv[i],1);
return USR_ARG_REQ_PARAM; return USR_ARG_REQ_PARAM;