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; }
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; }
int exefs_write_section(exefs_context* ctx, u32 index, u32 flags) { exefs_sectionheader* section = (exefs_sectionheader*)(ctx->header.section + index); filepath* sectionpath = settings_get_exefs_section_path(ctx->usersettings, index); u8 buffer[16 * 1024]; u8 hash[0x20]; u32 size; FILE* sectionfile; if(sectionpath == 0 || !sectionpath->valid) goto clean; sectionfile=fopen(sectionpath->pathname,"rb"); if(sectionfile == 0) { fprintf(stdout, "Error reading input section file\n"); goto clean; } fseek(sectionfile, 0, SEEK_END); size = ftell(sectionfile); fseek(sectionfile, 0, SEEK_SET); putle32(section->offset, ftell(ctx->file)-sizeof(exefs_header)); ctr_sha_256_init(&ctx->sha); if((flags & CompressCodeFlag) && !memcmp(settings_get_exefs_section_name(ctx->usersettings, index), ".code", 0x6)) { unsigned char* pak_buffer = BLZ_Encode(sectionpath->pathname, &size, BLZ_NORMAL); if (!pak_buffer) { fprintf(stdout, "Error reading input file\n"); goto clean; } fwrite(pak_buffer, 1, size, ctx->file); ctr_sha_256_update(&ctx->sha, pak_buffer, size); free(pak_buffer); }else{ u32 k=size; while(k) { u32 max = sizeof(buffer); if (max > k) max = k; if (max != fread(buffer, 1, max, sectionfile)) { fprintf(stdout, "Error reading input file\n"); goto clean; } fwrite(buffer, 1, max, ctx->file); ctr_sha_256_update(&ctx->sha, buffer, max); k -= max; } } ctr_sha_256_finish(&ctx->sha, hash); putle32(section->size, size); memcpy(ctx->header.hashes[7-index], hash, 0x20); fclose(sectionfile); clean: return 0; }