Exemplo n.º 1
0
void exefs_print(exefs_context* ctx)
{
	u32 i;
	char sectname[9];
	u32 sectoffset;
	u32 sectsize;

	fprintf(stdout, "\nExeFS:\n");
	for(i=0; i<8; i++)
	{
		exefs_sectionheader* section = (exefs_sectionheader*)(ctx->header.section + i);


		memset(sectname, 0, sizeof(sectname));
		memcpy(sectname, section->name, 8);

		sectoffset = getle32(section->offset);
		sectsize = getle32(section->size);

		if (sectsize)
		{
			fprintf(stdout, "Section name:           %s\n", sectname);
			fprintf(stdout, "Section offset:         0x%08x\n", sectoffset + 0x200);
			fprintf(stdout, "Section size:           0x%08x\n", sectsize);
			if (ctx->hashcheck[i] == Good)
				memdump(stdout, "Section hash (GOOD):    ", ctx->header.hashes[7-i], 0x20);
			else if (ctx->hashcheck[i] == Fail)
				memdump(stdout, "Section hash (FAIL):    ", ctx->header.hashes[7-i], 0x20);
			else
				memdump(stdout, "Section hash:           ", ctx->header.hashes[7-i], 0x20);
		}
	}
}
Exemplo n.º 2
0
void ncch_get_counter(ctr_ncchheader header, unsigned char counter[16], unsigned char type)
{
	unsigned int version = getle16(header.version);
	unsigned int mediaunitsize = 0x200;
	unsigned char* partitionid = header.partitionid;
	unsigned int i;
	unsigned int x = 0;

	for(i = 0; i < 16; i++) counter[i] = 0x00;

	if (version == 2 || version == 0)
	{
		for(i=0; i<8; i++)
			counter[i] = partitionid[7-i];
		counter[8] = type;
	}
	else if (version == 1)
	{
		if (type == NCCHTYPE_EXHEADER)
			x = 0x200;
		else if (type == NCCHTYPE_EXEFS)
			x = getle32(header.exefsoffset) * mediaunitsize;
		else if (type == NCCHTYPE_ROMFS)
			x = getle32(header.romfsoffset) * mediaunitsize;

		for(i=0; i<8; i++)
			counter[i] = partitionid[i];
		for(i=0; i<4; i++)
			counter[12+i] = x>>((3-i)*8);
	}
}
Exemplo n.º 3
0
u32 IdentifyImage(const char* path) {
    u8 header[0x200];
    FIL file;
    if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
        return 0;
    f_lseek(&file, 0);
    f_sync(&file);
    UINT fsize = f_size(&file);
    UINT bytes_read;
    if ((f_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) {
        f_close(&file);
        return 0;
    }
    f_close(&file);
    if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
        (getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) {
        return IMG_NAND;
    } else if (getbe16(header + 0x1FE) == 0x55AA) { // migt be FAT or MBR
        if ((strncmp((char*) header + 0x36, "FAT12   ", 8) == 0) || (strncmp((char*) header + 0x36, "FAT16   ", 8) == 0) ||
            (strncmp((char*) header + 0x36, "FAT     ", 8) == 0) || (strncmp((char*) header + 0x52, "FAT32   ", 8) == 0)) {
            return IMG_FAT; // this is an actual FAT header
        } else if (((getle32(header + 0x1BE + 0x8) + getle32(header + 0x1BE + 0xC)) < (fsize / 0x200)) && // check file size
            (getle32(header + 0x1BE + 0x8) > 0) && (getle32(header + 0x1BE + 0xC) >= 0x800) && // check first partition sanity
            ((header[0x1BE + 0x4] == 0x1) || (header[0x1BE + 0x4] == 0x4) || (header[0x1BE + 0x4] == 0x6) || // filesystem type
             (header[0x1BE + 0x4] == 0xB) || (header[0x1BE + 0x4] == 0xC) || (header[0x1BE + 0x4] == 0xE))) {
            return IMG_FAT; // this might be an MBR -> give it the benefit of doubt
        }
    }
    return 0;
}
Exemplo n.º 4
0
Arquivo: firm.c Projeto: 3dshax/ctr
int firm_verify(firm_context* ctx, u32 flags)
{
	unsigned int i;
	u32 offset;
	u32 size;
	u8 buffer[16 * 1024];
	u8 hash[0x20];


	for(i=0; i<4; i++)
	{
		firm_sectionheader* section = (firm_sectionheader*)(ctx->header.section + i);
	

		offset = getle32(section->offset);
		size = getle32(section->size);

		if (size == 0)
			return 0;

		fseek(ctx->file, ctx->offset + offset, SEEK_SET);

		ctr_sha_256_init(&ctx->sha);

		while(size)
		{
			u32 max = sizeof(buffer);
			if (max > size)
				max = size;

			if (max != fread(buffer, 1, max, ctx->file))
			{
				fprintf(stdout, "Error reading input file\n");
				goto clean;
			}

			ctr_sha_256_update(&ctx->sha, buffer, max);

			size -= max;
		}	

		ctr_sha_256_finish(&ctx->sha, hash);


		if (memcmp(hash, section->hash, 0x20) == 0)
			ctx->hashcheck[i] = Good;
		else
			ctx->hashcheck[i] = Fail;
	}


clean:
	return 0;
}
Exemplo n.º 5
0
void romfs_print(romfs_context* ctx)
{
	u32 i;

	fprintf(stdout, "\nRomFS:\n");

	fprintf(stdout, "Header size:            0x%08X\n", getle32(ctx->infoheader.headersize));
	for(i=0; i<4; i++)
	{
		fprintf(stdout, "Section %d offset:       0x%08"PRIX64"\n", i, ctx->offset + 0x1000 + getle32(ctx->infoheader.section[i].offset));
		fprintf(stdout, "Section %d size:         0x%08X\n", i, getle32(ctx->infoheader.section[i].size));
	}

	fprintf(stdout, "Data offset:            0x%08"PRIX64"\n", ctx->offset + 0x1000 + getle32(ctx->infoheader.dataoffset));
}
Exemplo n.º 6
0
int exefs_verify(exefs_context* ctx, u32 index, u32 flags)
{
	exefs_sectionheader* section = (exefs_sectionheader*)(ctx->header.section + index);
	u32 offset;
	u32 size;
	u8 buffer[16 * 1024];
	u8 hash[0x20];
	

	offset = getle32(section->offset) + sizeof(exefs_header);
	size = getle32(section->size);

	if (size == 0)
		return 0;

	fseek(ctx->file, ctx->offset + offset, SEEK_SET);
	ctr_init_counter(&ctx->aes, ctx->key, ctx->counter);
	ctr_add_counter(&ctx->aes, offset / 0x10);

	ctr_sha_256_init(&ctx->sha);

	while(size)
	{
		u32 max = sizeof(buffer);
		if (max > size)
			max = size;

		if (max != fread(buffer, 1, max, ctx->file))
		{
			fprintf(stdout, "Error reading input file\n");
			goto clean;
		}

		if (ctx->encrypted)
			ctr_crypt_counter(&ctx->aes, buffer, buffer, max);

		ctr_sha_256_update(&ctx->sha, buffer, max);

		size -= max;
	}	

	ctr_sha_256_finish(&ctx->sha, hash);

	if (memcmp(hash, ctx->header.hashes[7-index], 0x20) == 0)
		return 1;
clean:
	return 0;
}
Exemplo n.º 7
0
void ivfc_print(ivfc_context* ctx)
{
	u32 i;
	ivfc_header* header = &ctx->header;

	fprintf(stdout, "\nIVFC:\n");

	fprintf(stdout, "Header:                 %.4s\n", header->magic);
	fprintf(stdout, "Id:                     %08x\n", getle32(header->id));

	for(i=0; i<ctx->levelcount; i++)
	{
		ivfc_level* level = ctx->level + i;

		fprintf(stdout, "\n");
		if (level->hashcheck == Unchecked)
			fprintf(stdout, "Level %d:               \n", i);
		else
			fprintf(stdout, "Level %d (%s):          \n", i, level->hashcheck == Good? "GOOD" : "FAIL");
		fprintf(stdout, " Data offset:           0x%08"PRIx64"\n", ctx->offset + level->dataoffset);
		fprintf(stdout, " Data size:             0x%08"PRIx64"\n", level->datasize);
		fprintf(stdout, " Hash offset:           0x%08"PRIx64"\n", ctx->offset + level->hashoffset);
		fprintf(stdout, " Hash block size:       0x%08x\n", level->hashblocksize);
	}
}
Exemplo n.º 8
0
u32 CheckEmuNand(void)
{
    u8* buffer = BUFFER_ADDRESS;
    u32 nand_size_sectors = getMMCDevice(0)->total_size;

    u32 nand_offset;
    if (emunand_no > 0) {
        if (nand_size_sectors > EMUNAND_MULTI_OFFSET_O3DS) {
            nand_offset = EMUNAND_MULTI_OFFSET_N3DS * (emunand_no - 1 );
        } else {
            nand_offset = EMUNAND_MULTI_OFFSET_O3DS * (emunand_no - 1 );
        }
    } else {
        nand_offset = 0;
    }

    // check the MBR for presence of EmuNAND
    sdmmc_sdcard_readsectors(0, 1, buffer);
    if (nand_offset+nand_size_sectors > getle32(buffer + 0x1BE + 0x8))
        return EMUNAND_NOT_READY;

    // check for Gateway type EmuNAND
    sdmmc_sdcard_readsectors(nand_offset+nand_size_sectors, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_GATEWAY;

    // check for RedNAND type EmuNAND
    sdmmc_sdcard_readsectors(nand_offset + 1, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_REDNAND;

    // EmuNAND ready but not set up
    return EMUNAND_READY;
}
Exemplo n.º 9
0
void tik_print(tik_context* ctx)
{
	int i;
	eticket* tik = &ctx->tik;

	fprintf(stdout, "\nTicket content:\n");
	fprintf(stdout,
		"Signature Type:         %08x\n"
		"Issuer:                 %s\n",
		getle32(tik->sig_type), tik->issuer
	);

	fprintf(stdout, "Signature:\n");
	hexdump(tik->signature, 0x100);
	fprintf(stdout, "\n");

	memdump(stdout, "Encrypted Titlekey:     ", tik->encrypted_title_key, 0x10);
	
	if (settings_get_common_keyX(ctx->usersettings))
		memdump(stdout, "Decrypted Titlekey:     ", ctx->titlekey, 0x10);

	memdump(stdout,	"Ticket ID:              ", tik->ticket_id, 0x08);
	fprintf(stdout, "Ticket Version:         %d\n", getle16(tik->ticket_version));
	memdump(stdout,	"Title ID:               ", tik->title_id, 0x08);
	fprintf(stdout, "Common Key Index:       %d\n", tik->commonkey_idx);

	fprintf(stdout, "Content permission map:\n");
	for(i = 0; i < 0x40; i++) {
		printf(" %02x", tik->content_permissions[i]);

		if ((i+1) % 8 == 0)
			printf("\n");
	}
	printf("\n");
}
Exemplo n.º 10
0
Arquivo: ncsd.c Projeto: 3dshax/ctr
void ncsd_process(ncsd_context* ctx, u32 actions)
{
	fseek(ctx->file, ctx->offset, SEEK_SET);
	fread(&ctx->header, 1, 0x200, ctx->file);

	if (getle32(ctx->header.magic) != MAGIC_NCSD)
	{
		fprintf(stdout, "Error, NCSD segment corrupted\n");
		return;
	}


	if (actions & VerifyFlag)
	{
		if (ctx->usersettings)
			ctx->headersigcheck = ncsd_signature_verify(&ctx->header, &ctx->usersettings->keys.ncsdrsakey);
	}

	if (actions & InfoFlag)
		ncsd_print(ctx);

	ncch_set_file(&ctx->ncch, ctx->file);
	ncch_set_offset(&ctx->ncch, 0x4000);
	ncch_set_size(&ctx->ncch, ctx->size - 0x4000);
	ncch_set_usersettings(&ctx->ncch, ctx->usersettings);
	ncch_process(&ctx->ncch, actions);
}
Exemplo n.º 11
0
void ncsd_process(ncsd_context* ctx, u32 actions)
{
	fseeko64(ctx->file, ctx->offset, SEEK_SET);
	fread(&ctx->header, 1, 0x200, ctx->file);

	if (getle32(ctx->header.magic) != MAGIC_NCSD)
	{
		fprintf(stdout, "Error, NCSD segment corrupted\n");
		return;
	}


	if (actions & VerifyFlag)
	{
		if (ctx->usersettings)
			ctx->headersigcheck = ncsd_signature_verify(&ctx->header, &ctx->usersettings->keys.ncsdrsakey);
	}

	if (actions & InfoFlag)
		ncsd_print(ctx);

	if(ctx->ncch_index > 7 || ctx->header.partitiongeometry[ctx->ncch_index].size == 0)
	{
		fprintf(stderr," ERROR NCSD partition %d, does not exist\n",ctx->ncch_index);
		return;
	}
		
	ncch_set_file(&ctx->ncch, ctx->file);
	ncch_set_offset(&ctx->ncch, ctx->header.partitiongeometry[ctx->ncch_index].offset * ncsd_get_mediaunit_size(ctx));
	ncch_set_size(&ctx->ncch, ctx->header.partitiongeometry[ctx->ncch_index].size * ncsd_get_mediaunit_size(ctx));
	ncch_set_usersettings(&ctx->ncch, ctx->usersettings);
	ncch_process(&ctx->ncch, actions);
}
Exemplo n.º 12
0
void keyset_parse_seeddb(keyset* keys, char* path)
{
	//keyset_parse_key128(&keys->seed, keytext, keylen);
	FILE* fp = fopen(path, "rb");
	if (fp == NULL)
	{
		printf("[ERROR] Failed to load SeedDB (failed to open file)\n");
		return;
	}

	seeddb_header hdr;
	fread(&hdr, sizeof(seeddb_header), 1, fp);

	keys->seed_num = getle32(hdr.n_entries);
	for (u32 i = 0; i < 0xC; i++)
	{
		if (hdr.padding[i] != 0x00)
		{
			printf("[ERROR] SeedDB is corrupt. (padding malformed)\n");
			return;
		}
	}
	
	keys->seed_db = (seeddb_entry*)calloc(keys->seed_num, sizeof(seeddb_entry));
	fread(keys->seed_db, keys->seed_num * sizeof(seeddb_entry), 1, fp);
}
Exemplo n.º 13
0
uint32_t getsize(int fd)
{
    int len;
    uint8_t buf[4];

    len=read(fd, buf, 4);
    return getle32(buf);
}
Exemplo n.º 14
0
int main(int argc, char *argv[])
{
	uint32_t olen;
	long ilen;
	unsigned long offs;
	FILE *f;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s compressed_file\n", argv[0]);
		return 1;
	}

	/* Get the information for the compressed kernel image first */

	f = fopen(argv[1], "r");
	if (!f) {
		perror(argv[1]);
		return 1;
	}


	if (fseek(f, -4L, SEEK_END)) {
		perror(argv[1]);
	}
	fread(&olen, sizeof olen, 1, f);
	ilen = ftell(f);
	olen = getle32(&olen);
	fclose(f);

	/*
	 * Now we have the input (compressed) and output (uncompressed)
	 * sizes, compute the necessary decompression offset...
	 */

	offs = (olen > ilen) ? olen - ilen : 0;
	offs += olen >> 12;	/* Add 8 bytes for each 32K block */
	offs += 64*1024 + 128;	/* Add 64K + 128 bytes slack */
	offs = (offs+4095) & ~4095; /* Round to a 4K boundary */

	printf(".section \".rodata..compressed\",\"a\",@progbits\n");
	printf(".globl z_input_len\n");
	printf("z_input_len = %lu\n", ilen);
	printf(".globl z_output_len\n");
	printf("z_output_len = %lu\n", (unsigned long)olen);
	printf(".globl z_extract_offset\n");
	printf("z_extract_offset = 0x%lx\n", offs);
	/* z_extract_offset_negative allows simplification of head_32.S */
	printf(".globl z_extract_offset_negative\n");
	printf("z_extract_offset_negative = -0x%lx\n", offs);

	printf(".globl input_data, input_data_end\n");
	printf("input_data:\n");
	printf(".incbin \"%s\"\n", argv[1]);
	printf("input_data_end:\n");

	return 0;
}
Exemplo n.º 15
0
void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions, const oschar_t* rootpath)
{
	u32 siblingoffset = 0;
	oschar_t* currentpath = NULL;
	romfs_fileentry* entry = &ctx->fileentry;


	if (!romfs_fileblock_readentry(ctx, fileoffset, entry))
		return;


//	fprintf(stdout, "%08X %08X %016llX %016llX %08X ", 
//		getle32(entry->parentdiroffset), getle32(entry->siblingoffset), ctx->datablockoffset+getle64(entry->dataoffset),
//			getle64(entry->datasize), getle32(entry->unknown));
//	fwprintf(stdout, L"%ls\n", entry->name);

	if (rootpath && os_strlen(rootpath))
	{
		currentpath = os_AppendUTF16StrToPath(rootpath, (const utf16char_t*)entry->name);
		if (currentpath)
		{
			fputs("Saving ", stdout);
			os_fputs(currentpath, stdout);
			fputs("...\n", stdout);
			romfs_extract_datafile(ctx, getle64(entry->dataoffset), getle64(entry->datasize), currentpath);
		}
		else
		{
			fputs("Error creating file in root ", stderr);
			os_fputs(rootpath, stderr);
			fputs("\n", stderr);
			return;
		}
	}
	else
	{
		currentpath = os_CopyConvertUTF16Str((const utf16char_t*)entry->name);
		if (settings_get_list_romfs_files(ctx->usersettings))
		{
			u32 i;

			for(i=0; i<depth; i++)
				printf(" ");
			os_fputs(currentpath, stdout);
			fputs("\n", stdout);
		}
		free(currentpath);
		currentpath = NULL;
	}

	siblingoffset = getle32(entry->siblingoffset);

	if (siblingoffset != (~0))
		romfs_visit_file(ctx, siblingoffset, depth, actions, rootpath);

	free(currentpath);
}
Exemplo n.º 16
0
int check_riff(avi_context *ac, uint8_t *buf, int len)
{
    uint32_t tag;
    int c = 0;

    if (len < 12) return -1;
    tag = getle32(buf);
    if (tag != TAG_IT('R','I','F','F')) return -1;
    c+=4;

    ac->riff_end = getle32(buf+c);
    c+=4;

    tag = getle32(buf+c);
    if (tag != TAG_IT('A','V','I',' ') &&
            tag != TAG_IT('A','V','I','X') ) return -1;

    return c+4;
}
Exemplo n.º 17
0
uint8_t* decryptFirmTitleNcch(uint8_t* title, unsigned int size){
	ctr_ncchheader NCCH;
	uint8_t CTR[16];
	PartitionInfo INFO;
	NCCH = *((ctr_ncchheader*)title);
	if(memcmp(NCCH.magic, "NCCH", 4) != 0) return NULL;
	ncch_get_counter(NCCH, CTR, 2);
	INFO.ctr = CTR; INFO.buffer = title + getle32(NCCH.exefsoffset)*0x200; INFO.keyY = NCCH.signature; INFO.size = size; INFO.keyslot = 0x2C;
	DecryptPartition(&INFO);
	uint8_t* firm = (uint8_t*)(INFO.buffer + 0x200);
	return firm;
}
Exemplo n.º 18
0
void ncsd_print(ncsd_context* ctx)
{
	char magic[5];
	ctr_ncsdheader* header = &ctx->header;
	unsigned int i;
	unsigned int mediaunitsize = (unsigned int) ncsd_get_mediaunit_size(ctx);


	memcpy(magic, header->magic, 4);
	magic[4] = 0;

	fprintf(stdout, "Header:                 %s\n", magic);
	if (ctx->headersigcheck == Unchecked)
		memdump(stdout, "Signature:              ", header->signature, 0x100);
	else if (ctx->headersigcheck == Good)
		memdump(stdout, "Signature (GOOD):       ", header->signature, 0x100);
	else
		memdump(stdout, "Signature (FAIL):       ", header->signature, 0x100);       
	fprintf(stdout, "Media size:             0x%08x\n", getle32(header->mediasize));
	fprintf(stdout, "Media id:               %016"PRIx64"\n", getle64(header->mediaid));
	//memdump(stdout, "Partition FS type:      ", header->partitionfstype, 8);
	//memdump(stdout, "Partition crypt type:   ", header->partitioncrypttype, 8);
	//memdump(stdout, "Partition offset/size:  ", header->partitionoffsetandsize, 0x40);
	fprintf(stdout, "\n");
	for(i=0; i<8; i++)
	{
		u32 partitionoffset = header->partitiongeometry[i].offset * mediaunitsize;
		u32 partitionsize = header->partitiongeometry[i].size * mediaunitsize;

		if (partitionsize != 0)
		{
			fprintf(stdout, "Partition %d            \n", i);
			memdump(stdout, " Id:                    ", header->partitionid+i*8, 8);
			fprintf(stdout, " Area:                  0x%08X-0x%08X\n", partitionoffset, partitionoffset+partitionsize);
			fprintf(stdout, " Filesystem:            %02X\n", header->partitionfstype[i]);
			fprintf(stdout, " Encryption:            %02X\n", header->partitioncrypttype[i]);
			fprintf(stdout, "\n");
		}
	}
	memdump(stdout, "Extended header hash:   ", header->extendedheaderhash, 0x20);
	memdump(stdout, "Additional header size: ", header->additionalheadersize, 4);
	memdump(stdout, "Sector zero offset:     ", header->sectorzerooffset, 4);
	memdump(stdout, "Flags:                  ", header->flags, 8);
	fprintf(stdout, " > Mediaunit size:      0x%X\n", mediaunitsize);
	fprintf(stdout, " > Mediatype:           %s\n", ncsd_print_mediatype(header->flags[5]));
	fprintf(stdout, " > Card Device:         %s\n", ncsd_print_carddevice(header->flags[3] | header->flags[7]));

}
Exemplo n.º 19
0
int layout_addsection(u32 sectionid, u8 *section_payload, u32 section_payloadsize)
{
	if(layout_pos+8+section_payloadsize > filebuf_size)
	{
		printf("This additional layout section is too large.\n");
		return 5;
	}

	putle32(&filebuf[layout_pos+0], sectionid);
	putle32(&filebuf[layout_pos+4], 8+section_payloadsize);
	if(section_payload)memcpy(&filebuf[layout_pos+8], section_payload, section_payloadsize);

	layout_pos+= 8+section_payloadsize;

	putle32(layout_header->total_sections, getle32(layout_header->total_sections) + 1);

	return 0;
}
Exemplo n.º 20
0
Arquivo: firm.c Projeto: 3dshax/ctr
void firm_print(firm_context* ctx)
{
	u32 i;
	u32 address;
	u32 type;
	u32 offset;
	u32 size;
	u32 entrypointarm11 = getle32(ctx->header.entrypointarm11);
	u32 entrypointarm9 = getle32(ctx->header.entrypointarm9);

	fprintf(stdout, "\nFIRM:\n");
	if (ctx->headersigcheck == Unchecked)
		memdump(stdout, "Signature:              ", ctx->header.signature, 0x100);
	else if (ctx->headersigcheck == Good)
		memdump(stdout, "Signature (GOOD):       ", ctx->header.signature, 0x100);
	else
		memdump(stdout, "Signature (FAIL):       ", ctx->header.signature, 0x100);

	fprintf(stdout, "\n");
	fprintf(stdout, "Entrypoint ARM9:        0x%08X\n", entrypointarm9);
	fprintf(stdout, "Entrypoint ARM11:       0x%08X\n", entrypointarm11);
	fprintf(stdout, "\n");


	for(i=0; i<4; i++)
	{
		firm_sectionheader* section = (firm_sectionheader*)(ctx->header.section + i);


		offset = getle32(section->offset);
		size = getle32(section->size);
		address = getle32(section->address);
		type = getle32(section->type);

		if (size)
		{
			fprintf(stdout, "Section %d              \n", i);
			fprintf(stdout, " Type:                  %s\n", type==0? "ARM9" : type==1? "ARM11" : "UNKNOWN");
			fprintf(stdout, " Address:               0x%08X\n", address);
			fprintf(stdout, " Offset:                0x%08X\n", offset);
			fprintf(stdout, " Size:                  0x%08X\n", size);			
			if (ctx->hashcheck[i] == Good)
				memdump(stdout, " Hash (GOOD):           ", section->hash, 0x20);
			else if (ctx->hashcheck[i] == Fail)
				memdump(stdout, " Hash (FAIL):           ", section->hash, 0x20);
			else
				memdump(stdout, " Hash:                  ", section->hash, 0x20);
		}
	}
}
Exemplo n.º 21
0
int romfs_fileblock_readentry(romfs_context* ctx, u32 fileoffset, romfs_fileentry* entry)
{
	u32 size_without_name = sizeof(romfs_fileentry) - ROMFS_MAXNAMESIZE;
	u32 namesize;


	if (!ctx->fileblock)
		return 0;

	if (!romfs_fileblock_read(ctx, fileoffset, size_without_name, entry))
		return 0;
	
	namesize = getle32(entry->namesize);
	if (namesize > (ROMFS_MAXNAMESIZE-2))
		namesize = (ROMFS_MAXNAMESIZE-2);
	memset(entry->name + namesize, 0, 2);
	if (!romfs_fileblock_read(ctx, fileoffset + size_without_name, namesize, entry->name))
		return 0;

	return 1;
}
Exemplo n.º 22
0
u32 SeekTitleInNandDb(u32* tid_low, u32* tmd_id, TitleListInfo* title_info)
{
    PartitionInfo* ctrnand_info = GetPartitionInfo(P_CTRNAND);
    u8* titledb = (u8*) 0x20316000;
    
    u32 offset_db;
    u32 size_db;
    if (SeekFileInNand(&offset_db, &size_db, "DBS        TITLE   DB ", ctrnand_info) != 0)
        return 1; // database not found
    if (size_db != 0x64C00)
        return 1; // bad database size
    if (DecryptNandToMem(titledb, offset_db, size_db, ctrnand_info) != 0)
        return 1;
    
    u8* entry_table = titledb + 0x39A80;
    u8* info_data = titledb + 0x44B80;
    if ((getle32(entry_table + 0) != 2) || (getle32(entry_table + 4) != 3))
        return 1; // magic number not found
    *tid_low = 0;
    for (u32 i = 0; i < 1000; i++) {
        u8* entry = entry_table + 0xA8 + (0x2C * i);
        u8* info = info_data + (0x80 * i);
        u32 r;
        if (getle32(entry + 0xC) != title_info->tid_high) continue; // not a title id match
        if (getle32(entry + 0x4) != 1) continue; // not an active entry
        if ((getle32(entry + 0x18) - i != 0x162) || (getle32(entry + 0x1C) != 0x80) || (getle32(info + 0x08) != 0x40)) continue; // fishy title info / offset
        for (r = 0; r < 6; r++) {
            if ((title_info->tid_low[r] != 0) && (getle32(entry + 0x8) == title_info->tid_low[r])) break;
        }
        if (r >= 6) continue;
        *tmd_id = getle32(info + 0x14);
        *tid_low = title_info->tid_low[r];
        break; 
    }
    
    return (*tid_low) ? 0 : 1;
}
Exemplo n.º 23
0
u32 CheckEmuNand(void)
{
    u8* buffer = BUFFER_ADDRESS;
    u32 nand_size_sectors = getMMCDevice(0)->total_size;
    
    // check the MBR for presence of EmuNAND
    sdmmc_sdcard_readsectors(0, 1, buffer);
    if (nand_size_sectors > getle32(buffer + 0x1BE + 0x8))
        return EMUNAND_NOT_READY;
    
    // check for Gateway type EmuNAND
    sdmmc_sdcard_readsectors(nand_size_sectors, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_GATEWAY;
    
    // check for RedNAND type EmuNAND
    sdmmc_sdcard_readsectors(1, 1, buffer);
    if (memcmp(buffer + 0x100, "NCSD", 4) == 0)
        return EMUNAND_REDNAND;
        
    // EmuNAND ready but not set up
    return EMUNAND_READY;
}
Exemplo n.º 24
0
Arquivo: firm.c Projeto: 3dshax/ctr
void firm_process(firm_context* ctx, u32 actions)
{
	u32 i;

	fseek(ctx->file, ctx->offset, SEEK_SET);
	fread(&ctx->header, 1, sizeof(firm_header), ctx->file);

	if (getle32(ctx->header.magic) != MAGIC_FIRM)
	{
		fprintf(stdout, "Error, FIRM segment corrupted\n");
		return;
	}


	if (actions & VerifyFlag)
	{
		firm_verify(ctx, actions);
		firm_signature_verify(ctx);
	}

	if (actions & InfoFlag)
	{
		firm_print(ctx);
	}

	if (actions & ExtractFlag)
	{
		filepath* dirpath = settings_get_firm_dir_path(ctx->usersettings);

		if (dirpath && dirpath->valid)
		{
			makedir(dirpath->pathname);
			for(i=0; i<4; i++)
				firm_save(ctx, i, actions);
		}
	}
}
Exemplo n.º 25
0
uint8_t* decryptFirmTitleNcch(uint8_t* title, size_t *size)
{
	const size_t sector = 512;
	const size_t header = 512;
	ctr_ncchheader NCCH;
	uint8_t CTR[16];
	PartitionInfo INFO;
	NCCH = *((ctr_ncchheader*)title);
	if(memcmp(NCCH.magic, "NCCH", 4) != 0) return NULL;
	ncch_get_counter(NCCH, CTR, 2);
	INFO.ctr = CTR; INFO.buffer = title + getle32(NCCH.exefsoffset)*sector; INFO.keyY = NCCH.signature; INFO.size = getle32(NCCH.exefssize)*sector; INFO.keyslot = 0x2C;
	DecryptPartition(&INFO);

	if (size != NULL)
		*size = INFO.size - header;

	uint8_t* firm = (uint8_t*)(INFO.buffer + header);

	if (getMpInfo() == MPINFO_KTR)
	    if (decryptFirmKtrArm9(firm))
			return NULL;

	return firm;
}
Exemplo n.º 26
0
void ivfc_process(ivfc_context* ctx, u32 actions)
{
	ivfc_fseek(ctx, ctx->offset);
	ivfc_fread(ctx, &ctx->header, 1, sizeof(ivfc_header));

	if (getle32(ctx->header.magic) != MAGIC_IVFC)
	{
		fprintf(stdout, "Error, IVFC segment corrupted\n");
		return;
	}

	if (getle32(ctx->header.id) == 0x10000)
	{
		ctx->levelcount = 3;

		ctx->level[2].hashblocksize = 1 << getle32(ctx->header.level3.blocksize);
		ctx->level[1].hashblocksize = 1 << getle32(ctx->header.level2.blocksize);
		ctx->level[0].hashblocksize = 1 << getle32(ctx->header.level1.blocksize);

		ctx->bodyoffset = align64(IVFC_HEADER_SIZE + getle32(ctx->header.masterhashsize), ctx->level[2].hashblocksize);
		ctx->bodysize = getle64(ctx->header.level3.hashdatasize);
		
		ctx->level[2].dataoffset = ctx->bodyoffset;
		ctx->level[2].datasize = align64(ctx->bodysize, ctx->level[2].hashblocksize);

		ctx->level[0].dataoffset = ctx->level[2].dataoffset + ctx->level[2].datasize;
		ctx->level[0].datasize = align64(getle64(ctx->header.level1.hashdatasize), ctx->level[0].hashblocksize);

		ctx->level[1].dataoffset = ctx->level[0].dataoffset + ctx->level[0].datasize;
		ctx->level[1].datasize = align64(getle64(ctx->header.level2.hashdatasize), ctx->level[1].hashblocksize);

		ctx->level[0].hashoffset = IVFC_HEADER_SIZE;
		ctx->level[1].hashoffset = ctx->level[0].dataoffset;
		ctx->level[2].hashoffset = ctx->level[1].dataoffset;
	}

	if (actions & VerifyFlag)
		ivfc_verify(ctx, actions);

	if (actions & InfoFlag)
		ivfc_print(ctx);		

}
Exemplo n.º 27
0
void romfs_process(romfs_context* ctx, u32 actions)
{
	u32 dirblockoffset = 0;
	u32 dirblocksize = 0;
	u32 fileblockoffset = 0;
	u32 fileblocksize = 0;

	ivfc_set_offset(&ctx->ivfc, ctx->offset);
	ivfc_set_size(&ctx->ivfc, ctx->size);
	ivfc_set_file(&ctx->ivfc, ctx->file);
	ivfc_set_usersettings(&ctx->ivfc, ctx->usersettings);
	ivfc_set_counter(&ctx->ivfc, ctx->counter);
	ivfc_set_key(&ctx->ivfc, ctx->key);
	ivfc_set_encrypted(&ctx->ivfc, ctx->encrypted);
	ivfc_process(&ctx->ivfc, actions);

	romfs_fseek(ctx, ctx->offset);
	romfs_fread(ctx, &ctx->header, 1, sizeof(romfs_header));

	if (getle32(ctx->header.magic) != MAGIC_IVFC)
	{
		fprintf(stdout, "Error, RomFS corrupted\n");
		return;
	}

	ctx->infoblockoffset = (u32) (ctx->offset + 0x1000);

	romfs_fseek(ctx, ctx->infoblockoffset);
	romfs_fread(ctx, &ctx->infoheader, 1, sizeof(romfs_infoheader));
	
	if (getle32(ctx->infoheader.headersize) != sizeof(romfs_infoheader))
	{
		fprintf(stderr, "Error, info header mismatch\n");
		return;
	}

	dirblockoffset = ctx->infoblockoffset + getle32(ctx->infoheader.section[1].offset);
	dirblocksize = getle32(ctx->infoheader.section[1].size);
	fileblockoffset = ctx->infoblockoffset + getle32(ctx->infoheader.section[3].offset);
	fileblocksize = getle32(ctx->infoheader.section[3].size);

	u32 hdrsize = getle32(ctx->infoheader.dataoffset);
	u8 *block = malloc(hdrsize);
	romfs_fseek(ctx, ctx->infoblockoffset);
	romfs_fread(ctx, block, hdrsize, 1);

	ctx->dirblock = malloc(dirblocksize);
	ctx->dirblocksize = dirblocksize;
	if(ctx->dirblock)
		memcpy(ctx->dirblock, block + getle32(ctx->infoheader.section[1].offset), dirblocksize);

	ctx->fileblock = malloc(fileblocksize);
	ctx->fileblocksize = fileblocksize;
	if (ctx->fileblock)
		memcpy(ctx->fileblock, block + getle32(ctx->infoheader.section[3].offset), fileblocksize);

	free(block);

	ctx->datablockoffset = ctx->infoblockoffset + getle32(ctx->infoheader.dataoffset);

	if (actions & InfoFlag)
		romfs_print(ctx);

	if (settings_get_romfs_dir_path(ctx->usersettings)->valid)
		ctx->extractdir = os_CopyConvertCharStr(settings_get_romfs_dir_path(ctx->usersettings)->pathname);
	else
		ctx->extractdir = NULL;

	romfs_visit_dir(ctx, 0, 0, actions, ctx->extractdir);
	free(ctx->extractdir);
}
Exemplo n.º 28
0
void romfs_visit_dir(romfs_context* ctx, u32 diroffset, u32 depth, u32 actions, const oschar_t* rootpath)
{
	u32 siblingoffset;
	u32 childoffset;
	u32 fileoffset;
	oschar_t* currentpath;
	romfs_direntry* entry = &ctx->direntry;


	if (!romfs_dirblock_readentry(ctx, diroffset, entry))
		return;


//	fprintf(stdout, "%08X %08X %08X %08X %08X ", 
//			getle32(entry->parentoffset), getle32(entry->siblingoffset), getle32(entry->childoffset), 
//			getle32(entry->fileoffset), getle32(entry->weirdoffset));
//	fwprintf(stdout, L"%ls\n", entry->name);


	if (rootpath && os_strlen(rootpath))
	{
		if (utf16_strlen((const utf16char_t*)entry->name) > 0)
			currentpath = os_AppendUTF16StrToPath(rootpath, (const utf16char_t*)entry->name);
		else // root dir, use the provided extract path instead of the empty root name.
			currentpath = os_CopyStr(rootpath);

		if (currentpath)
		{
			os_makedir(currentpath);
		}
		else
		{
			fputs("Error creating directory in root ", stderr);
			os_fputs(rootpath, stderr);
			fputs("\n", stderr);
			return;
		}
	}
	else
	{
		currentpath = os_CopyConvertUTF16Str((const utf16char_t*)entry->name);
		if (settings_get_list_romfs_files(ctx->usersettings))
		{
			u32 i;

			for(i=0; i<depth; i++)
				printf(" ");
			os_fputs(currentpath, stdout);
			fputs("\n", stdout);
		}
		free(currentpath);
		currentpath = NULL;
	}
	

	siblingoffset = getle32(entry->siblingoffset);
	childoffset = getle32(entry->childoffset);
	fileoffset = getle32(entry->fileoffset);

	if (fileoffset != (~0))
		romfs_visit_file(ctx, fileoffset, depth+1, actions, currentpath);

	if (childoffset != (~0))
		romfs_visit_dir(ctx, childoffset, depth+1, actions, currentpath);

	if (siblingoffset != (~0))
		romfs_visit_dir(ctx, siblingoffset, depth, actions, rootpath);

	free(currentpath);
}
Exemplo n.º 29
0
void exefs_save(exefs_context* ctx, u32 index, u32 flags)
{
	exefs_sectionheader* section = (exefs_sectionheader*)(ctx->header.section + index);
	char outfname[MAX_PATH];
	char name[64];
	u32 offset;
	u32 size;
	FILE* fout;
	u32 compressedsize = 0;
	u32 decompressedsize = 0;
	u8* compressedbuffer = 0;
	u8* decompressedbuffer = 0;
	filepath* dirpath = 0;
	
	
	offset = getle32(section->offset) + sizeof(exefs_header);
	size = getle32(section->size);
	dirpath = settings_get_exefs_dir_path(ctx->usersettings);

	if (size == 0 || dirpath == 0 || dirpath->valid == 0)
		return;

	if (size >= ctx->size)
	{
		fprintf(stderr, "Error, ExeFS section %d size invalid\n", index);
		return;
	}

	memset(name, 0, sizeof(name));
	memcpy(name, section->name, 8);

	
	memcpy(outfname, dirpath->pathname, MAX_PATH);
	strcat(outfname, "/");

	if (name[0] == '.')
		strcat(outfname, name+1);
	else
		strcat(outfname, name);
	strcat(outfname, ".bin");

	fout = fopen(outfname, "wb");

	if (fout == 0)
	{
		fprintf(stderr, "Error, failed to create file %s\n", outfname);
		goto clean;
	}
	
	

	fseek(ctx->file, ctx->offset + offset, SEEK_SET);
	ctr_init_counter(&ctx->aes, ctx->key, ctx->counter);
	ctr_add_counter(&ctx->aes, offset / 0x10);

	if (index == 0 && (ctx->compressedflag || (flags & CompressCodeFlag)) && ((flags & RawFlag) == 0))
	{
		fprintf(stdout, "Decompressing section %s to %s...\n", name, outfname);

		compressedsize = size;
		compressedbuffer = malloc(compressedsize);

		if (compressedbuffer == 0)
		{
			fprintf(stdout, "Error allocating memory\n");
			goto clean;
		}
		if (compressedsize != fread(compressedbuffer, 1, compressedsize, ctx->file))
		{
			fprintf(stdout, "Error reading input file\n");
			goto clean;
		}

		if (ctx->encrypted)
			ctr_crypt_counter(&ctx->aes, compressedbuffer, compressedbuffer, compressedsize);


		decompressedsize = lzss_get_decompressed_size(compressedbuffer, compressedsize);
		decompressedbuffer = malloc(decompressedsize);
		if (decompressedbuffer == 0)
		{
			fprintf(stdout, "Error allocating memory\n");
			goto clean;
		}

		if (0 == lzss_decompress(compressedbuffer, compressedsize, decompressedbuffer, decompressedsize))
			goto clean;

		if (decompressedsize != fwrite(decompressedbuffer, 1, decompressedsize, fout))
		{
			fprintf(stdout, "Error writing output file\n");
			goto clean;
		}		
	}
	else
	{
		u8 buffer[16 * 1024];

		fprintf(stdout, "Saving section %s to %s...\n", name, outfname);

		while(size)
		{
			u32 max = sizeof(buffer);
			if (max > size)
				max = size;

			if (max != fread(buffer, 1, max, ctx->file))
			{
				fprintf(stdout, "Error reading input file\n");
				goto clean;
			}

			if (ctx->encrypted)
				ctr_crypt_counter(&ctx->aes, buffer, buffer, max);

			if (max != fwrite(buffer, 1, max, fout))
			{
				fprintf(stdout, "Error writing output file\n");
				goto clean;
			}

			size -= max;
		}
	}

clean:
	free(compressedbuffer);
	free(decompressedbuffer);
	return;
}
Exemplo n.º 30
0
uint32_t getsize_buf(uint8_t *buf)
{
    return getle32(buf);
}