mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
ctrtool: Updated exheader validation and ncch spec/flag recognition
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
@@ -18,13 +18,13 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
|
||||
+114
-97
@@ -126,6 +126,58 @@ int exheader_programid_valid(exheader_context* ctx)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void exheader_deserialise_arm11localcaps_permissions(exheader_arm11systemlocalcaps_deserialised *caps, const exheader_arm11systemlocalcaps *arm11)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(caps, 0, sizeof(exheader_arm11systemlocalcaps_deserialised));
|
||||
|
||||
memcpy(caps->program_id, arm11->programid, 8);
|
||||
caps->core_version = getle32(arm11->coreversion);
|
||||
|
||||
caps->enable_l2_cache = (arm11->flag[0] >> 0) & 1;
|
||||
caps->use_additional_cores = (arm11->flag[0] >> 1) & 1;
|
||||
caps->new3ds_systemmode = (arm11->flag[1] >> 0) & 15;
|
||||
|
||||
caps->ideal_processor = (arm11->flag[2] >> 0) & 3;
|
||||
caps->affinity_mask = (arm11->flag[2] >> 2) & 3;
|
||||
caps->old3ds_systemmode = (arm11->flag[2] >> 4) & 15;
|
||||
|
||||
caps->priority = (s8)arm11->flag[3];
|
||||
|
||||
// storage info
|
||||
if (arm11->storageinfo.otherattributes & 2) {
|
||||
caps->extdata_id = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
caps->other_user_saveid[i] = 0;
|
||||
caps->use_other_variation_savedata = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
caps->accessible_saveid[i] = 0xfffff & (getle64(arm11->storageinfo.accessibleuniqueids) >> 20 * (2 - i));
|
||||
for (i = 0; i < 3; i++)
|
||||
caps->accessible_saveid[i+3] = 0xfffff & (getle64(arm11->storageinfo.extsavedataid) >> 20 * (2 - i));
|
||||
}
|
||||
else {
|
||||
caps->extdata_id = getle64(arm11->storageinfo.extsavedataid);
|
||||
for (i = 0; i < 3; i++)
|
||||
caps->other_user_saveid[i] = 0xfffff & (getle64(arm11->storageinfo.accessibleuniqueids) >> 20 * (2 - i));
|
||||
caps->use_other_variation_savedata = (getle64(arm11->storageinfo.accessibleuniqueids) >> 60) & 1;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
caps->accessible_saveid[i] = 0;
|
||||
}
|
||||
|
||||
caps->system_saveid[0] = getle32(arm11->storageinfo.systemsavedataid);
|
||||
caps->system_saveid[1] = getle32(arm11->storageinfo.systemsavedataid + 4);
|
||||
caps->accessinfo = getle64(arm11->storageinfo.accessinfo) & ~((u64)0xff00000000000000);
|
||||
|
||||
// Service Access Control
|
||||
for (i = 0; i < 34; i++)
|
||||
strncpy(caps->service_access_control[i], (char*)arm11->serviceaccesscontrol[i], 8);
|
||||
|
||||
caps->resource_limit_category = arm11->resourcelimitcategory;
|
||||
}
|
||||
|
||||
int exheader_process(exheader_context* ctx, u32 actions)
|
||||
{
|
||||
exheader_determine_key(ctx, actions);
|
||||
@@ -135,13 +187,13 @@ int exheader_process(exheader_context* ctx, u32 actions)
|
||||
if (ctx->header.codesetinfo.flags.flag & 1)
|
||||
ctx->compressedflag = 1;
|
||||
|
||||
exheader_deserialise_arm11localcaps_permissions(&ctx->system_local_caps, &ctx->header.arm11systemlocalcaps);
|
||||
|
||||
if (actions & VerifyFlag)
|
||||
exheader_verify(ctx);
|
||||
|
||||
if (actions & InfoFlag)
|
||||
{
|
||||
exheader_print(ctx);
|
||||
}
|
||||
exheader_print(ctx);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -397,11 +449,10 @@ void exheader_print_arm11accessinfo(exheader_context* ctx)
|
||||
{
|
||||
char str[100];
|
||||
u64 i, bit;
|
||||
u64 accessinfo = 0xffffffffffffff & getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessinfo);
|
||||
for(i = 0; i < 56; i++)
|
||||
{
|
||||
bit = ((u64)1 << i);
|
||||
if((accessinfo & bit) == bit)
|
||||
if((ctx->system_local_caps.accessinfo & bit) == bit)
|
||||
fprintf(stdout, " > %s\n",exheader_print_accessinfobit((u32)i,str));
|
||||
}
|
||||
}
|
||||
@@ -410,72 +461,21 @@ void exheader_print_arm11storageinfo(exheader_context* ctx)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
// Storage Info
|
||||
u32 systemsaveID[2];
|
||||
u64 extdataID;
|
||||
u32 otherusersaveID[3];
|
||||
u32 accessiblesaveID[6];
|
||||
|
||||
u8 otherattibutes = ctx->header.arm11systemlocalcaps.storageinfo.otherattributes;
|
||||
u8 accessOtherVariationSavedata = (getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessibleuniqueids) & 0x1000000000000000) == 0x1000000000000000;
|
||||
|
||||
systemsaveID[0] = getle32(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid);
|
||||
systemsaveID[1] = getle32(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid+4);
|
||||
|
||||
extdataID = getle64(ctx->header.arm11systemlocalcaps.storageinfo.extsavedataid);
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
accessiblesaveID[i] = 0xfffff & (getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessibleuniqueids) >> 20*(2-i));
|
||||
otherusersaveID[i] = 0xfffff & (getle64(ctx->header.arm11systemlocalcaps.storageinfo.accessibleuniqueids) >> 20*(2-i));
|
||||
}
|
||||
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
accessiblesaveID[i+3] = 0xfffff & (getle64(ctx->header.arm11systemlocalcaps.storageinfo.extsavedataid) >> 20*(2-i));
|
||||
}
|
||||
|
||||
if(otherattibutes & 2)
|
||||
{
|
||||
extdataID = 0;
|
||||
for(i = 0; i < 3; i++)
|
||||
otherusersaveID[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < 6; i++)
|
||||
accessiblesaveID[i] = 0;
|
||||
}
|
||||
|
||||
fprintf(stdout, "Ext savedata id: 0x%08"PRIx64"\n",extdataID);
|
||||
fprintf(stdout, "Ext savedata id: 0x%"PRIx64"\n",ctx->system_local_caps.extdata_id);
|
||||
for(i = 0; i < 2; i++)
|
||||
fprintf(stdout, "System savedata id %d: 0x%08x %s\n",i+1,systemsaveID[i],exheader_getvalidstring(ctx->validsystemsaveID[i]));
|
||||
fprintf(stdout, "System savedata id %d: 0x%x %s\n",i+1, ctx->system_local_caps.system_saveid[i],exheader_getvalidstring(ctx->validsystemsaveID[i]));
|
||||
for(i = 0; i < 3; i++)
|
||||
fprintf(stdout, "OtherUserSaveDataId%d: 0x%05x\n",i+1,otherusersaveID[i]);
|
||||
fprintf(stdout, "OtherUserSaveDataId%d: 0x%x\n",i+1, ctx->system_local_caps.other_user_saveid[i]);
|
||||
fprintf(stdout, "Accessible Savedata Ids:\n");
|
||||
for(i = 0; i < 6; i++)
|
||||
{
|
||||
if(accessiblesaveID[i] != 0x00000)
|
||||
fprintf(stdout, " > 0x%05x\n",accessiblesaveID[i]);
|
||||
if(ctx->system_local_caps.accessible_saveid[i] != 0x00000)
|
||||
fprintf(stdout, " > 0x%05x\n", ctx->system_local_caps.accessible_saveid[i]);
|
||||
}
|
||||
|
||||
fprintf(stdout, "Other Variation Saves: %s\n", accessOtherVariationSavedata ? "Accessible" : "Inaccessible");
|
||||
if(ctx->validaccessinfo == Unchecked)
|
||||
memdump(stdout, "Access info: ", ctx->header.arm11systemlocalcaps.storageinfo.accessinfo, 7);
|
||||
else if(ctx->validaccessinfo == Good)
|
||||
memdump(stdout, "Access info (GOOD): ", ctx->header.arm11systemlocalcaps.storageinfo.accessinfo, 7);
|
||||
else
|
||||
memdump(stdout, "Access info (FAIL): ", ctx->header.arm11systemlocalcaps.storageinfo.accessinfo, 7);
|
||||
exheader_print_arm11accessinfo(ctx);
|
||||
|
||||
fprintf(stdout, "Other attributes: %02X", ctx->header.arm11systemlocalcaps.storageinfo.otherattributes);
|
||||
/*
|
||||
if(otherattibutes & 1)
|
||||
fprintf(stdout," [no use romfs]");
|
||||
if(otherattibutes & 2)
|
||||
fprintf(stdout," [use extended savedata access control]");
|
||||
*/
|
||||
printf("\n");
|
||||
fprintf(stdout, "Other Variation Saves: %s\n", ctx->system_local_caps.use_other_variation_savedata ? "Accessible" : "Inaccessible");
|
||||
fprintf(stdout, "Access info: 0x%"PRIx64" %s\n", ctx->system_local_caps.accessinfo,exheader_getvalidstring(ctx->validaccessinfo));
|
||||
exheader_print_arm11accessinfo(ctx);
|
||||
}
|
||||
|
||||
int exheader_signature_verify(exheader_context* ctx, rsakey2048* key)
|
||||
@@ -486,61 +486,78 @@ int exheader_signature_verify(exheader_context* ctx, rsakey2048* key)
|
||||
return ctr_rsa_verify_hash(ctx->header.accessdesc.signature, hash, key);
|
||||
}
|
||||
|
||||
|
||||
void exheader_verify(exheader_context* ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
u8 exheaderflag6[3];
|
||||
u8 descflag6[3];
|
||||
unsigned int i, j;
|
||||
exheader_arm11systemlocalcaps_deserialised accessdesc;
|
||||
|
||||
exheader_deserialise_arm11localcaps_permissions(&accessdesc, &ctx->header.accessdesc.arm11systemlocalcaps);
|
||||
|
||||
ctx->validsystemsaveID[0] = Good;
|
||||
ctx->validsystemsaveID[1] = Good;
|
||||
ctx->validaccessinfo = Good;
|
||||
ctx->validcoreversion = Good;
|
||||
ctx->validprogramid = Good;
|
||||
ctx->validpriority = Good;
|
||||
ctx->validaffinitymask = Good;
|
||||
ctx->valididealprocessor = Good;
|
||||
ctx->validold3dssystemmode = Good;
|
||||
ctx->validnew3dssystemmode = Good;
|
||||
ctx->validenablel2cache = Good;
|
||||
ctx->validuseadditionalcores = Good;
|
||||
ctx->validservicecontrol = Good;
|
||||
|
||||
for(i=0; i<8; i++)
|
||||
{
|
||||
if (0 == (ctx->header.arm11systemlocalcaps.programid[i] & ~ctx->header.accessdesc.arm11systemlocalcaps.programid[i]))
|
||||
if (ctx->system_local_caps.program_id[i] == accessdesc.program_id[i] || accessdesc.program_id[i] == 0xFF)
|
||||
continue;
|
||||
ctx->validprogramid = Fail;
|
||||
break;
|
||||
}
|
||||
|
||||
// Ideal Proccessor
|
||||
exheaderflag6[0] = (ctx->header.arm11systemlocalcaps.flag>>0)&0x3;
|
||||
descflag6[0] = (ctx->header.accessdesc.arm11systemlocalcaps.flag>>0)&0x3;
|
||||
// Affinity Mask
|
||||
exheaderflag6[1] = (ctx->header.arm11systemlocalcaps.flag>>2)&0x3;
|
||||
descflag6[1] = (ctx->header.accessdesc.arm11systemlocalcaps.flag>>2)&0x3;
|
||||
// System Mode
|
||||
//exheaderflag6[2] = (ctx->header.arm11systemlocalcaps.flag>>4)&0xf;
|
||||
//descflag6[2] = (ctx->header.accessdesc.arm11systemlocalcaps.flag>>4)&0xf;
|
||||
if (ctx->system_local_caps.core_version != accessdesc.core_version)
|
||||
ctx->validcoreversion = Fail;
|
||||
|
||||
if (ctx->header.accessdesc.arm11systemlocalcaps.priority > ctx->header.arm11systemlocalcaps.priority || ctx->header.arm11systemlocalcaps.priority > 127)
|
||||
if (ctx->system_local_caps.priority < accessdesc.priority)
|
||||
ctx->validpriority = Fail;
|
||||
|
||||
if((1<<exheaderflag6[0] & descflag6[0]) == 0)
|
||||
if((1<<ctx->system_local_caps.ideal_processor & accessdesc.ideal_processor) == 0)
|
||||
ctx->valididealprocessor = Fail;
|
||||
|
||||
if (exheaderflag6[1] & ~descflag6[1])
|
||||
if (ctx->system_local_caps.affinity_mask & ~accessdesc.affinity_mask)
|
||||
ctx->validaffinitymask = Fail;
|
||||
|
||||
if (ctx->system_local_caps.old3ds_systemmode > accessdesc.old3ds_systemmode)
|
||||
ctx->validold3dssystemmode = Fail;
|
||||
|
||||
if (ctx->system_local_caps.new3ds_systemmode > accessdesc.new3ds_systemmode)
|
||||
ctx->validnew3dssystemmode = Fail;
|
||||
|
||||
|
||||
// Storage Info Verify
|
||||
if(0 != (getle32(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid) & ~getle32(ctx->header.accessdesc.arm11systemlocalcaps.storageinfo.systemsavedataid)))
|
||||
if(ctx->system_local_caps.system_saveid[0] & ~accessdesc.system_saveid[0])
|
||||
ctx->validsystemsaveID[0] = Fail;
|
||||
if(0 != (getle32(ctx->header.arm11systemlocalcaps.storageinfo.systemsavedataid+4) & ~getle32(ctx->header.accessdesc.arm11systemlocalcaps.storageinfo.systemsavedataid+4)))
|
||||
if(ctx->system_local_caps.system_saveid[1] & ~accessdesc.system_saveid[1])
|
||||
ctx->validsystemsaveID[1] = Fail;
|
||||
|
||||
for(i=0; i<7; i++)
|
||||
{
|
||||
if(0 == (ctx->header.arm11systemlocalcaps.storageinfo.accessinfo[i] & ~ctx->header.accessdesc.arm11systemlocalcaps.storageinfo.accessinfo[i]))
|
||||
continue;
|
||||
|
||||
if (ctx->system_local_caps.accessinfo & ~accessdesc.accessinfo)
|
||||
ctx->validaccessinfo = Fail;
|
||||
break;
|
||||
|
||||
// Service Access Control
|
||||
for (i = 0; i < 34; i++) {
|
||||
if (strlen(ctx->system_local_caps.service_access_control[i]) == 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < 34; j++) {
|
||||
if (strcmp(ctx->system_local_caps.service_access_control[i], accessdesc.service_access_control[j]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp(ctx->system_local_caps.service_access_control[i], accessdesc.service_access_control[j]) == 0)
|
||||
continue;
|
||||
|
||||
ctx->validservicecontrol = Fail;
|
||||
}
|
||||
|
||||
if (ctx->usersettings)
|
||||
@@ -609,21 +626,21 @@ void exheader_print(exheader_context* ctx)
|
||||
|
||||
fprintf(stdout, "Program id: %016"PRIx64" %s\n", getle64(ctx->header.arm11systemlocalcaps.programid), exheader_getvalidstring(ctx->validprogramid));
|
||||
fprintf(stdout, "Core version: 0x%X\n", getle32(ctx->header.arm11systemlocalcaps.coreversion));
|
||||
fprintf(stdout, "System mode: 0x%X\n", (ctx->header.arm11systemlocalcaps.flag>>4)&0xF);
|
||||
fprintf(stdout, "Ideal processor: %d %s\n", (ctx->header.arm11systemlocalcaps.flag>>0)&0x3, exheader_getvalidstring(ctx->valididealprocessor));
|
||||
fprintf(stdout, "Affinity mask: %d %s\n", (ctx->header.arm11systemlocalcaps.flag>>2)&0x3, exheader_getvalidstring(ctx->validaffinitymask));
|
||||
fprintf(stdout, "Main thread priority: %d %s\n", ctx->header.arm11systemlocalcaps.priority, exheader_getvalidstring(ctx->validpriority));
|
||||
fprintf(stdout, "System mode: %d %s\n", ctx->system_local_caps.old3ds_systemmode, exheader_getvalidstring(ctx->validold3dssystemmode));
|
||||
fprintf(stdout, "System mode (New3DS): %d %s\n", ctx->system_local_caps.new3ds_systemmode, exheader_getvalidstring(ctx->validnew3dssystemmode));
|
||||
fprintf(stdout, "Ideal processor: %d %s\n", ctx->system_local_caps.ideal_processor, exheader_getvalidstring(ctx->valididealprocessor));
|
||||
fprintf(stdout, "Affinity mask: %d %s\n", ctx->system_local_caps.affinity_mask, exheader_getvalidstring(ctx->validaffinitymask));
|
||||
fprintf(stdout, "Main thread priority: %d %s\n", ctx->system_local_caps.priority, exheader_getvalidstring(ctx->validpriority));
|
||||
// print resource limit descriptor too? currently mostly zeroes...
|
||||
exheader_print_arm11storageinfo(ctx);
|
||||
exheader_print_arm11kernelcapabilities(ctx);
|
||||
exheader_print_arm9accesscontrol(ctx);
|
||||
|
||||
|
||||
|
||||
for(i=0; i<0x20; i++)
|
||||
fprintf(stdout, "Service access: %s\n", exheader_getvalidstring(ctx->validservicecontrol));
|
||||
for(i=0; i<34; i++)
|
||||
{
|
||||
if (getle64(ctx->header.arm11systemlocalcaps.serviceaccesscontrol[i]) != 0x0000000000000000UL)
|
||||
fprintf(stdout, "Service access: %.8s\n", ctx->header.arm11systemlocalcaps.serviceaccesscontrol[i]);
|
||||
if (strlen(ctx->system_local_caps.service_access_control[i]) > 0)
|
||||
fprintf(stdout, " > %s\n", ctx->system_local_caps.service_access_control[i]);
|
||||
}
|
||||
fprintf(stdout, "Reslimit category: %02X\n", ctx->header.arm11systemlocalcaps.resourcelimitcategory);
|
||||
}
|
||||
|
||||
+39
-5
@@ -57,16 +57,41 @@ typedef struct
|
||||
{
|
||||
u8 programid[8];
|
||||
u8 coreversion[4];
|
||||
u8 reserved0[2];
|
||||
u8 flag;
|
||||
u8 priority;
|
||||
u8 flag[4];
|
||||
u8 resourcelimitdescriptor[0x10][2];
|
||||
exheader_storageinfo storageinfo;
|
||||
u8 serviceaccesscontrol[0x20][8];
|
||||
u8 reserved[0x1f];
|
||||
u8 serviceaccesscontrol[34][8];
|
||||
u8 reserved[0xf];
|
||||
u8 resourcelimitcategory;
|
||||
} exheader_arm11systemlocalcaps;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 program_id[8];
|
||||
u32 core_version;
|
||||
|
||||
// flag
|
||||
u8 enable_l2_cache;
|
||||
u8 use_additional_cores;
|
||||
u8 new3ds_systemmode;
|
||||
u8 ideal_processor;
|
||||
u8 affinity_mask;
|
||||
u8 old3ds_systemmode;
|
||||
s8 priority;
|
||||
|
||||
// storageinfo
|
||||
u64 extdata_id;
|
||||
u32 other_user_saveid[3];
|
||||
u8 use_other_variation_savedata;
|
||||
u32 accessible_saveid[3];
|
||||
u32 system_saveid[2];
|
||||
u64 accessinfo;
|
||||
|
||||
|
||||
char service_access_control[34][10];
|
||||
u8 resource_limit_category;
|
||||
} exheader_arm11systemlocalcaps_deserialised;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 descriptors[28][4];
|
||||
@@ -115,6 +140,9 @@ typedef struct
|
||||
u32 offset;
|
||||
u32 size;
|
||||
exheader_header header;
|
||||
|
||||
exheader_arm11systemlocalcaps_deserialised system_local_caps;
|
||||
|
||||
ctr_aes_context aes;
|
||||
ctr_rsa_context rsa;
|
||||
int compressedflag;
|
||||
@@ -123,8 +151,14 @@ typedef struct
|
||||
int validpriority;
|
||||
int validaffinitymask;
|
||||
int valididealprocessor;
|
||||
int validold3dssystemmode;
|
||||
int validnew3dssystemmode;
|
||||
int validenablel2cache;
|
||||
int validuseadditionalcores;
|
||||
int validcoreversion;
|
||||
int validsystemsaveID[2];
|
||||
int validaccessinfo;
|
||||
int validservicecontrol;
|
||||
int validsignature;
|
||||
} exheader_context;
|
||||
|
||||
|
||||
+14
-7
@@ -540,6 +540,17 @@ static const char* contenttypetostring(unsigned char flags)
|
||||
case 2: return "Manual";
|
||||
case 3: return "Child";
|
||||
case 4: return "Trial";
|
||||
case 5: return "Extended System Update";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* contentplatformtostring(unsigned char platform)
|
||||
{
|
||||
switch (platform)
|
||||
{
|
||||
case 1: return "CTR";
|
||||
case 2: return "SNAKE";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
@@ -566,6 +577,7 @@ void ncch_print(ncch_context* ctx)
|
||||
fprintf(stdout, "Partition id: %016"PRIx64"\n", getle64(header->partitionid));
|
||||
fprintf(stdout, "Maker code: %04x\n", getle16(header->makercode));
|
||||
fprintf(stdout, "Version: %04x\n", getle16(header->version));
|
||||
fprintf(stdout, "Title seed check: %08x\n", getle32(header->seedcheck));
|
||||
fprintf(stdout, "Program id: %016"PRIx64"\n", getle64(header->programid));
|
||||
if(ctx->logohashcheck == Unchecked)
|
||||
memdump(stdout, "Logo hash: ", header->logohash, 0x20);
|
||||
@@ -587,16 +599,11 @@ void ncch_print(ncch_context* ctx)
|
||||
fprintf(stdout, " > Crypto key: None\n");
|
||||
else if (header->flags[7] & 1)
|
||||
fprintf(stdout, " > Crypto key: %s\n", programid_is_system(header->programid)? "Fixed":"Zeros");
|
||||
else if (header->flags[3] & 1)
|
||||
fprintf(stdout, " > Crypto key: Secure2\n");
|
||||
else if (header->flags[3] & 10)
|
||||
fprintf(stdout, " > Crypto key: secure3 (New 3DS)\n");
|
||||
else
|
||||
fprintf(stdout, " > Crypto key: Secure\n");
|
||||
fprintf(stdout, " > Crypto key: Secure (%d)%s\n", header->flags[3], header->flags[7] & 32? " (KeyY seeded)" : "");
|
||||
fprintf(stdout, " > Form type: %s\n", formtypetostring(header->flags[5]));
|
||||
fprintf(stdout, " > Content type: %s\n", contenttypetostring(header->flags[5]));
|
||||
if (header->flags[4] & 1)
|
||||
fprintf(stdout, " > Content platform: CTR\n");
|
||||
fprintf(stdout, " > Content platform: %s\n", contentplatformtostring(header->flags[4]));
|
||||
if (header->flags[7] & 2)
|
||||
fprintf(stdout, " > No RomFS mount\n");
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ typedef struct
|
||||
u8 partitionid[8];
|
||||
u8 makercode[2];
|
||||
u8 version[2];
|
||||
u8 reserved0[4];
|
||||
u8 seedcheck[4];
|
||||
u8 programid[8];
|
||||
u8 reserved1[0x10];
|
||||
u8 logohash[0x20];
|
||||
|
||||
Reference in New Issue
Block a user