Пример #1
0
void ivfc_fseek(ivfc_context* ctx, u64 offset)
{
	u64 data_pos = offset - ctx->offset;
	fseeko64(ctx->file, offset, SEEK_SET);
	ctr_init_counter(&ctx->aes, ctx->key, ctx->counter);
	ctr_add_counter(&ctx->aes, (u32) (data_pos / 0x10));
}
Пример #2
0
void exefs_read_header(exefs_context* ctx, u32 flags)
{
	fseek(ctx->file, ctx->offset, SEEK_SET);
	fread(&ctx->header, 1, sizeof(exefs_header), ctx->file);

	ctr_init_counter(&ctx->aes, ctx->key, ctx->counter);

	if (ctx->encrypted)
		ctr_crypt_counter(&ctx->aes, (u8*)&ctx->header, (u8*)&ctx->header, sizeof(exefs_header));
}
Пример #3
0
int VerifyNCCHSection(USER_CONTEXT *ctx, u8 cxi_key[0x10], u32 offset, FILE *ncch)
{
	NCCH_STRUCT *cxi_ctx = malloc(sizeof(NCCH_STRUCT));
	if(cxi_ctx == NULL){
		printf("[!] Memory Allocation Failure\n");
		return Fail;
	}
	memset(cxi_ctx,0x0,sizeof(NCCH_STRUCT));
	GetCXIStruct(cxi_ctx,offset,ncch);
	
	u8 HeaderSignature[0x100];
	u8 Header[0x100];
	u8 HeaderSHAHash[0x20];
	u8 ExHeader[0x800];
	memset(&HeaderSignature,0x0,0x100);
	memset(&Header,0x0,0x100);
	memset(&HeaderSHAHash,0x0,0x20);
	fseek(ncch,offset+0x0,SEEK_SET);
	fread(HeaderSignature,0x100,1,ncch);
	fread(Header,0x100,1,ncch);
	ctr_sha(&Header,0x100,HeaderSHAHash,CTR_SHA_256);
	
	RSA_2048_KEY HeaderRSA;
	memset(&HeaderRSA,0x0,sizeof(RSA_2048_KEY));
	u8 Exponent[0x3] = {0x01,0x00,0x01};
	memcpy(HeaderRSA.e,Exponent,0x3);
		
	if(cxi_ctx->is_cfa == True)
		memcpy(HeaderRSA.n,ctx->keys.NcsdCfa.n,0x100);
		
	else{
		memset(&ExHeader,0x0,0x800);
		fseek(ncch,offset+cxi_ctx->exheader_offset,SEEK_SET);
		fread(&ExHeader,0x800,1,ncch);
		if(cxi_ctx->encrypted == True){
			u8 counter[0x10];
			ncch_get_counter(cxi_ctx,counter,NCCHTYPE_EXHEADER);
			ctr_aes_context aes_ctx;
			memset(&aes_ctx,0x0,sizeof(ctr_aes_context));
			ctr_init_counter(&aes_ctx, cxi_key, counter);
			ctr_crypt_counter(&aes_ctx, ExHeader, ExHeader, 0x800);
			if(memcmp((ExHeader+0x200),cxi_ctx->programID,8) != 0){
				printf("[!] CXI decryption failed\n");
				return Fail;
			}
		}
		memcpy(HeaderRSA.n,ExHeader+0x500,0x100);
	}
		
	return ctr_rsa(HeaderSHAHash,HeaderSignature,HeaderRSA.n,NULL,RSA_2048_SHA256,CTR_RSA_VERIFY);
}
Пример #4
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;
}
Пример #5
0
void CryptNcchRegion(u8 *buffer, u64 size, u64 src_pos, ncch_info *ctx, u8 key[16], u8 type)
{
	if(type < 1 || type > 3)
		return;
	u8 counter[0x10];
	ctr_aes_context aes_ctx;
	memset(&aes_ctx,0x0,sizeof(ctr_aes_context));
	
	GetNcchAesCounter(ctx,counter,type);	
	ctr_init_counter(&aes_ctx, key, counter);
	
	if(src_pos > 0){
		u32 carry = 0;
		carry = align(src_pos,0x10);
		carry /= 0x10;
		ctr_add_counter(&aes_ctx,carry);
	}
	
	ctr_crypt_counter(&aes_ctx, buffer, buffer, size);
	return;
}
Пример #6
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;
}