Esempio n. 1
0
int elf_ProcessHeader(elf_context *elf)
{
	const elf_hdr *hdr = (const elf_hdr*)elf->file;

	/* Check conditions for valid CTR ELF */
	if (u8_to_u32(hdr->magic, BE) != ELF_MAGIC)
		return NOT_ELF_FILE;
	if (hdr->bitFormat != elf_32_bit)
		return NOT_CTR_ARM_ELF;
	if (hdr->endianness != elf_little_endian)
		return NOT_CTR_ARM_ELF;
	if (u8_to_u16(hdr->targetArchitecture, LE) != elf_arm)
		return NOT_CTR_ARM_ELF;
	if (u8_to_u16(hdr->type, LE) != elf_executeable)
		return NON_EXECUTABLE_ELF;

	elf->phdrOffset = u8_to_u32(hdr->programHeaderTableOffset, LE);
	elf->segmentNum = u8_to_u16(hdr->programHeaderEntryCount, LE);
	elf->segments = calloc(elf->segmentNum, sizeof(elf_segment));
	if (!elf->segments) {
		fprintf(stderr, "[ELF ERROR] Not enough memory\n");
		return MEM_ERROR;
	}

	elf->shdrOffset = u8_to_u32(hdr->sectionHeaderTableOffset, LE);
	elf->shdrNameIndex = u8_to_u16(hdr->sectionHeaderNameEntryIndex, LE);
	elf->sectionNum = u8_to_u16(hdr->sectionHeaderEntryCount, LE);
	elf->sections = calloc(elf->sectionNum, sizeof(elf_section));
	if (!elf->sections) {
		fprintf(stderr, "[ELF ERROR] Not enough memory\n");
		return MEM_ERROR;
	}

	return 0;
}
static int
check (const uint8_t *input, size_t input_length,
       const uint16_t *expected, size_t expected_length)
{
  size_t length;
  uint16_t *result;

  /* Test return conventions with resultbuf == NULL.  */
  result = u8_to_u16 (input, input_length, NULL, &length);
  if (!(result != NULL))
    return 1;
  if (!(length == expected_length))
    return 2;
  if (!(u16_cmp (result, expected, expected_length) == 0))
    return 3;
  free (result);

  /* Test return conventions with resultbuf too small.  */
  if (expected_length > 0)
    {
      uint16_t *preallocated;

      length = expected_length - 1;
      preallocated = (uint16_t *) malloc (length * sizeof (uint16_t));
      result = u8_to_u16 (input, input_length, preallocated, &length);
      if (!(result != NULL))
        return 4;
      if (!(result != preallocated))
        return 5;
      if (!(length == expected_length))
        return 6;
      if (!(u16_cmp (result, expected, expected_length) == 0))
        return 7;
      free (result);
      free (preallocated);
    }

  /* Test return conventions with resultbuf large enough.  */
  {
    uint16_t *preallocated;

    length = expected_length;
    preallocated = (uint16_t *) malloc (length * sizeof (uint16_t));
    result = u8_to_u16 (input, input_length, preallocated, &length);
    if (!(result != NULL))
      return 8;
    if (!(preallocated == NULL || result == preallocated))
      return 9;
    if (!(length == expected_length))
      return 10;
    if (!(u16_cmp (result, expected, expected_length) == 0))
      return 11;
    free (preallocated);
  }

  return 0;
}
Esempio n. 3
0
void GetCUPVersion(/*char *FW_STRING, */CARD_INFO_HEADER *card_info)
{
	u8 MAJOR = 0;
	u8 MINOR = 0;
	u8 BUILD = 0;
	char REGION_CHAR = ' ';

	u16 CVer_ver = u8_to_u16(card_info->cver_title_version,LE);
	u32 CVer_UID = u8_to_u32(card_info->cver_title_id,LE);
		
	switch(CVer_UID){
		case EUR_UPDATE : REGION_CHAR = 'E'; break;
		case JPN_UPDATE : REGION_CHAR = 'J'; break;
		case USA_UPDATE : REGION_CHAR = 'U'; break;
		case CHN_UPDATE : REGION_CHAR = 'C'; break;
		case KOR_UPDATE : REGION_CHAR = 'K'; break;
		case TWN_UPDATE : REGION_CHAR = 'T'; break;
	}
	
	
	switch(CVer_ver){
		case 3088 : MAJOR = 3; MINOR = 0; BUILD = 0; break;
		default ://This tends to work most of the time, use above for manual overrides
			MAJOR = (CVer_ver & 0x7f00) >> 10;
			MINOR = (CVer_ver & 0x3f0) >> 4;
			//BUILD = CVer_ver & 0xf; 
			break;	
	}
	printf(" CUP Version:           %d.%d.%d%c\n",MAJOR,MINOR,BUILD,REGION_CHAR);
}
Esempio n. 4
0
void GetMin3DSFW(char *FW_STRING, CARD_INFO_HEADER *card_info)
{
	u8 MAJOR = 0;
	u8 MINOR = 0;
	u8 BUILD = 0;
	char REGION_CHAR = 'X';

	u16 CVer_ver = u8_to_u16(card_info->cver_title_version,LE);
	u32 CVer_UID = u8_to_u32(card_info->cver_title_id,LE);
		
	switch(CVer_UID){
		case EUR_ROM : REGION_CHAR = 'E'; break;
		case JPN_ROM : REGION_CHAR = 'J'; break;
		case USA_ROM : REGION_CHAR = 'U'; break;
		case CHN_ROM : REGION_CHAR = 'C'; break;
		case KOR_ROM : REGION_CHAR = 'K'; break;
		case TWN_ROM : REGION_CHAR = 'T'; break;
	}
	
	
	switch(CVer_ver){
		case 3088 : MAJOR = 3; MINOR = 0; BUILD = 0; break;
		default : MAJOR = CVer_ver/1024; MINOR = (CVer_ver - 1024*(CVer_ver/1024))/0x10; break;//This tends to work 98% of the time, use above for manual overides
	}
	sprintf(FW_STRING,"%d.%d.%d-X%c",MAJOR,MINOR,BUILD,REGION_CHAR);
}
Esempio n. 5
0
void PrintNCSDHeaderData(NCSD_STRUCT *ctx, NCSD_HEADER *header, CARD_INFO_HEADER *card_info, DEV_CARD_INFO_HEADER *dev_card_info)
{
	printf("[+] CCI Image Details\n");
	u8 CardDevice = header->partition_flags[MEDIA_CARD_DEVICE_OLD] + header->partition_flags[MEDIA_CARD_DEVICE];
	switch (header->partition_flags[MEDIA_TYPE_INDEX]){
		case INNER_DEVICE: printf(" Media Type:            INTERNAL_DEVICE\n"); break;
		case CARD1: printf(" Media Type:            CARD1\n"); break;
		case CARD2: printf(" Media Type:            CARD2\n  > Writable Region:\n   - Offset:            0x%llx\n   - Size:              0x%llx (%lld MB)\n",ctx->WRITABLE_ADDRESS,ctx->CARD2_MAX_SAVEDATA_SIZE,(ctx->CARD2_MAX_SAVEDATA_SIZE/MB)); break;
		case EXTENDED_DEVICE: printf(" Media Type:            EXTENDED_DEVICE\n"); break;
	}
	GetCHIPFullSize(ctx->MEDIA_SIZE,ctx->type);
	GetCCIDataSize(ctx->CCI_IMAGE_SIZE,ctx->type);
	GetCCIFileStatus(ctx->CCI_FILE_SIZE,ctx->CCI_FILE_STATUS,ctx->type);
	switch (CardDevice){
		case CARD_DEVICE_NOR_FLASH: printf(" Additional Device:     EEPROM\n"); break;
		case CARD_DEVICE_NONE: printf(" Additional Device:     None\n"); break;
		case CARD_DEVICE_BT: printf(" Additional Device:     BT\n"); break;
	}
	printf(" Partition Count:       %d\n",ctx->partition_count);
	if(u8_to_u64(card_info->cver_title_id,LE) && u8_to_u16(card_info->cver_title_version,LE)){
		//printf("CVer Title ID:          %016llx\n",u8_to_u64(card_info->cver_title_id,LE));
		//printf("CVer Title Ver:         v%d\n",u8_to_u16(card_info->cver_title_version,LE));
		GetCUPVersion(card_info);
	}
	if(!header->partition_flags[MEDIA_6X_SAVE_CRYPTO] && !header->partition_flags[MEDIA_CARD_DEVICE] && !header->partition_flags[MEDIA_CARD_DEVICE_OLD]){
		printf(" Save Crypto:           Repeating CTR Fail\n");
	}
	else if(!header->partition_flags[MEDIA_6X_SAVE_CRYPTO] && (header->partition_flags[MEDIA_CARD_DEVICE] || header->partition_flags[MEDIA_CARD_DEVICE_OLD])){
		printf(" Save Crypto:           2.2.0 KeyY Method\n");
	}
	else if(header->partition_flags[MEDIA_6X_SAVE_CRYPTO] == 1 && !header->partition_flags[MEDIA_CARD_DEVICE_OLD]){
		if(!header->partition_flags[MEDIA_CARD_DEVICE]){
			printf(" Save Crypto:           2.2.0 KeyY Method\n");
		}
		else if(header->partition_flags[MEDIA_CARD_DEVICE]){
			printf(" Save Crypto:           6.0.0 KeyY Method\n");
		}
	}
	
	printf("[+] CXI Partition\n");
	printf(" Product Code:          %.16s\n",card_info->partition_0_header.product_code);
	printf(" Company Code:          %.2s\n",card_info->partition_0_header.maker_code);
	u32 UniqueID = u8_to_u32(&card_info->partition_0_header.program_id[1],LE)&0xffffff;
	printf(" Unique ID:             %05x\n",UniqueID);
	printf(" Build Type:            %s\n",ctx->BUILD_TYPE? "Debug or Development" : "Release");
	printf(" SDK Version:           %d.%d.%d %s\n",ctx->SDK_VER[0],ctx->SDK_VER[1],ctx->SDK_VER[2],ctx->SDK_PATCH);
	if(ctx->FW_VER[0] || ctx->FW_VER[1]) printf(" Req. Kernel Version:   %d.%d-%d\n",ctx->FW_VER[0],ctx->FW_VER[1],ctx->FW_VER[2]);
	printf("[+] CFA Partitions\n");
	for(int i = 1; i < 8; i++){
		if(i == 1) printf(" E-Manual:              %s\n",ctx->partition_data[i].active? "Yes" : "No"); 
		else if(i == 2) printf(" DLP Child:             %s\n",ctx->partition_data[i].active? "Yes" : "No"); 
		else if(i == 7) printf(" Update Data:           %s\n",ctx->partition_data[i].active? "Yes" : "No"); 
		else{
			if(ctx->partition_data[i].active) printf(" CFA %d:                %s\n",i,ctx->partition_data[i].active? "Yes" : "No"); 
		}
	}
	
	
	
}
Esempio n. 6
0
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);

	u32 block_size = GetNcchBlockSize(hdr);
	
	info->formatVersion = u8_to_u16(hdr->formatVersion,LE);
	if(!IsCfa(hdr)){
		info->exhdrOffset = sizeof(ncch_hdr);
		info->exhdrSize = u8_to_u32(hdr->exhdrSize,LE);
		info->acexOffset = (info->exhdrOffset + info->exhdrSize);
		info->acexSize = sizeof(access_descriptor);
		info->plainRegionOffset = (u64)(u8_to_u32(hdr->plainRegionOffset,LE)*block_size);
		info->plainRegionSize = (u64)(u8_to_u32(hdr->plainRegionSize,LE)*block_size);
	}

	info->logoOffset = (u64)(u8_to_u32(hdr->logoOffset,LE)*block_size);
	info->logoSize = (u64)(u8_to_u32(hdr->logoSize,LE)*block_size);
	info->exefsOffset = (u64)(u8_to_u32(hdr->exefsOffset,LE)*block_size);
	info->exefsSize = (u64)(u8_to_u32(hdr->exefsSize,LE)*block_size);
	info->exefsHashDataSize = (u64)(u8_to_u32(hdr->exefsHashSize,LE)*block_size);
	info->romfsOffset = (u64) (u8_to_u32(hdr->romfsOffset,LE)*block_size);
	info->romfsSize = (u64) (u8_to_u32(hdr->romfsSize,LE)*block_size);
	info->romfsHashDataSize = (u64)(u8_to_u32(hdr->romfsHashSize,LE)*block_size);
	return 0;
}
int
main ()
{
  /* Empty string.  */
  ASSERT (check (NULL, 0, NULL, 0) == 0);

  /* Simple string.  */
  { /* "Grüß Gott. Здравствуйте! x=(-b±sqrt(b²-4ac))/(2a)  日本語,中文,한글" */
    static const uint8_t input[] =
      { 'G', 'r', 0xC3, 0xBC, 0xC3, 0x9F, ' ', 'G', 'o', 't', 't', '.', ' ',
        0xD0, 0x97, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, 0xB2, 0xD1, 0x81,
        0xD1, 0x82, 0xD0, 0xB2, 0xD1, 0x83, 0xD0, 0xB9, 0xD1, 0x82, 0xD0, 0xB5,
        '!', ' ', 'x', '=', '(', '-', 'b', 0xC2, 0xB1, 's', 'q', 'r', 't', '(',
        'b', 0xC2, 0xB2, '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')',
        ' ', ' ', 0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E, ',',
        0xE4, 0xB8, 0xAD, 0xE6, 0x96, 0x87, ',',
        0xED, 0x95, 0x9C, 0xEA, 0xB8, 0x80, '\n'
      };
    static const uint16_t expected[] =
      { 'G', 'r', 0x00FC, 0x00DF, ' ', 'G', 'o', 't', 't', '.', ' ',
        0x0417, 0x0434, 0x0440, 0x0430, 0x0432, 0x0441, 0x0442, 0x0432, 0x0443,
        0x0439, 0x0442, 0x0435, '!', ' ',
        'x', '=', '(', '-', 'b', 0x00B1, 's', 'q', 'r', 't', '(', 'b', 0x00B2,
        '-', '4', 'a', 'c', ')', ')', '/', '(', '2', 'a', ')', ' ', ' ',
        0x65E5, 0x672C, 0x8A9E, ',', 0x4E2D, 0x6587, ',', 0xD55C, 0xAE00, '\n'
      };
    ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
  }

  /* String with characters outside the BMP.  */
  {
    static const uint8_t input[] =
      { '-', '(', 0xF0, 0x9D, 0x94, 0x9E, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9F,
        ')', '=', 0xF0, 0x9D, 0x94, 0x9F, 0xC3, 0x97, 0xF0, 0x9D, 0x94, 0x9E
      };
    static const uint16_t expected[] =
      { '-', '(', 0xD835, 0xDD1E, 0x00D7, 0xD835, 0xDD1F, ')', '=',
        0xD835, 0xDD1F, 0x00D7, 0xD835, 0xDD1E
      };
    ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
  }

  /* Invalid input.  */
  {
    static const uint8_t input[] = { 'x', 0xC2, 0xC3, 'y' };
#if 0 /* Currently invalid input is rejected, not accommodated.  */
    static const uint16_t expected[] = { 'x', 0xFFFD, 0xFFFD, 'y' };
    ASSERT (check (input, SIZEOF (input), expected, SIZEOF (expected)) == 0);
#else
    size_t length;
    uint16_t *result;
    uint16_t preallocated[10];

    /* Test return conventions with resultbuf == NULL.  */
    result = u8_to_u16 (input, SIZEOF (input), NULL, &length);
    ASSERT (result == NULL);
    ASSERT (errno == EILSEQ);

    /* Test return conventions with resultbuf too small.  */
    length = 1;
    result = u8_to_u16 (input, SIZEOF (input), preallocated, &length);
    ASSERT (result == NULL);
    ASSERT (errno == EILSEQ);

    /* Test return conventions with resultbuf large enough.  */
    length = SIZEOF (preallocated);
    result = u8_to_u16 (input, SIZEOF (input), preallocated, &length);
    ASSERT (result == NULL);
    ASSERT (errno == EILSEQ);
#endif
  }

  return 0;
}
Esempio n. 8
0
static inline u16 dispatch_t204(t204 a205, u8 a206)
{
    return u8_to_u16(a206);
}
Esempio n. 9
0
void PrintNCSDData(NCSD_STRUCT *ctx, NCSD_HEADER *header, CARD_INFO_HEADER *card_info, DEV_CARD_INFO_HEADER *dev_card_info)
{
	if(ctx->valid != True){
		printf("[!] NCSD Corrupt\n");
		return;
	}
	printf("[+] NCSD\n");
	switch(ctx->sig_valid){
		case Good : memdump(stdout,"Signature(Good):        ",ctx->signature,0x100); break;
		case Fail : memdump(stdout,"Signature(Fail):        ",ctx->signature,0x100); break;
		case NotChecked: memdump(stdout,"Signature:              ",ctx->signature,0x100); break;
	}
	switch(ctx->type){
		case retail : 
			printf("Target:                 Retail/Production\n"); 
			printf("CVer Title ID:          %016llx\n",u8_to_u64(card_info->cver_title_id,LE));
			printf("CVer Title Ver:         v%d\n",u8_to_u16(card_info->cver_title_version,LE));
			char *FW_STRING = malloc(10);
			memset(FW_STRING,0,10);
			GetMin3DSFW(FW_STRING,card_info);
			printf("Min 3DS Firm:           %s\n",FW_STRING);
			_free(FW_STRING);
			break;
		case dev_internal_SDK :
			printf("Target:                 Debug/Development\n");
			printf("SDK Type:               Nintendo Internal SDK\n");
			memdump(stdout,"Title Key:              ",dev_card_info->TitleKey,0x10);
			break;
		case dev_external_SDK :
			printf("Target:                 Debug/Development\n");
			printf("SDK Type:               Nintendo 3RD Party SDK\n");
			memdump(stdout,"Title Key:              ",dev_card_info->TitleKey,0x10);
			break;
	}
	if(ctx->rom_size >= GB){
		printf("ROM Cart Size:          %lld GB",ctx->rom_size/GB); printf(" (%lld Gbit)\n",(ctx->rom_size/GB)*8);
	}
	else{
		printf("ROM Cart Size:          %lld MB",ctx->rom_size/MB); 
		u32 tmp = (ctx->rom_size/MB)*8;
		if(tmp >= 1024)
			printf(" (%d Gbit)\n",tmp/1024);
		else
			printf(" (%d Mbit)\n",tmp);
	}
	if(ctx->used_rom_size >= MB){
		printf("ROM Used Size:          %lld MB",ctx->used_rom_size/MB); printf(" (0x%llx bytes)\n",ctx->used_rom_size);
	}
	else if(ctx->used_rom_size >= KB){
		printf("ROM Used Size:          %lld KB",ctx->used_rom_size/KB); printf(" (0x%llx bytes)\n",ctx->used_rom_size);
	}
	printf("NCSD Title ID:          %016llx\n",u8_to_u64(header->title_id,LE));
	memdump(stdout,"ExHeader Hash:          ",header->exheader_hash,0x20);
	printf("AddHeader Size:         0x%x\n",u8_to_u32(header->additional_header_size,LE));
	printf("Sector 0 Offset:        0x%x\n",u8_to_u32(header->sector_zero_offset,LE));
	memdump(stdout,"Flags:                  ",header->partition_flags,8);
	printf("\n");
	for(int i = 0; i < 8; i++){
		if(ctx->partition_data[i].active == True){
			printf("Partition %d\n",i);
			printf(" Title ID:              %016llx\n",ctx->partition_data[i].title_id);
			printf(" Content Type:          ");
			switch(ctx->partition_data[i].content_type){
				case _unknown : printf("Unknown\n"); break;
				case CXI : printf("Application\n"); break;
				case CFA_Manual : printf("Electronic Manual\n"); break;
				case CFA_DLPChild : printf("Download Play Child\n"); break;
				case CFA_Update : printf("Software Update Partition\n"); break;
			}
			
			printf(" FS Type:               %x\n",ctx->partition_data[i].fs_type);
			printf(" Crypto Type:           %x\n",ctx->partition_data[i].crypto_type);
			printf(" Offset:                0x%x\n",ctx->partition_data[i].offset);
			printf(" Size:                  0x%x\n",ctx->partition_data[i].size);
			printf("\n");
		}
	}
}