diff --git a/Makefile b/Makefile index d9734a1..b2a1b0e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CC=gcc +CC=g++ CFLAGS=-g -O0 -Wall OS_TARGET=scetool LDFLAGS=-lz diff --git a/frontend.cpp b/frontend.cpp index b06949e..c52da07 100644 --- a/frontend.cpp +++ b/frontend.cpp @@ -327,13 +327,19 @@ void frontend_print_infos(s8 *file) if(sce_decrypt_header(ctxt, meta_info, keyset)) { _LOG_VERBOSE("Header decrypted.\n"); - if(sce_decrypt_data(ctxt)) - _LOG_VERBOSE("Data decrypted.\n"); - else - printf("[*] Warning: Could not decrypt data.\n"); + + //Just deal with spkg_hdr.1 files now, no need to decrypt whole PKG. + if(ctxt->sceh->header_type != SCE_HEADER_TYPE_PKG) + { + if(sce_decrypt_data(ctxt)) + _LOG_VERBOSE("Data decrypted.\n"); + else + printf("[*] Warning: Could not decrypt data.\n"); + } } else printf("[*] Warning: Could not decrypt header.\n"); + sce_print_info(stdout, ctxt); if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SELF) self_print_info(stdout, ctxt); @@ -341,6 +347,7 @@ void frontend_print_infos(s8 *file) rvk_print(stdout, ctxt); else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SPP && ctxt->mdec == TRUE) spp_print(stdout, ctxt); + free(ctxt); } else diff --git a/sce.cpp b/sce.cpp index dd647cf..ab3d377 100644 --- a/sce.cpp +++ b/sce.cpp @@ -26,7 +26,7 @@ void _print_sce_header(FILE *fp, sce_header_t *h) { const s8 *name; - const s8 *key_revision; + //const s8 *key_revision; fprintf(fp, "[*] SCE Header:\n"); fprintf(fp, " Magic 0x%08X [%s]\n", h->magic, (h->magic == SCE_HEADER_MAGIC ? "OK" : "ERROR")); @@ -320,7 +320,7 @@ void sce_compress_data(sce_buffer_ctxt_t *ctxt) else { free(buf); - _LOG_VERBOSE("Skipped compression of section %03d (0x%08X >= 0x%08X)\n", i, size_comp, sec->size); + _LOG_VERBOSE("Skipped compression of section %03d (0x%08lu >= 0x%08X)\n", i, size_comp, sec->size); } } else @@ -840,6 +840,9 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) aes_setkey_dec(&aes_ctxt, ks->erk, KEYBITS(ks->erklen)); memcpy(iv, ks->riv, 0x10); //!!! aes_crypt_cbc(&aes_ctxt, AES_DECRYPT, sizeof(metadata_info_t), iv, (u8 *)ctxt->metai, (u8 *)ctxt->metai); + + //Dump to file. + _write_buffer("metai_dec.bin", (u8 *) ctxt->metai, sizeof(metadata_info_t)); } else { @@ -850,6 +853,10 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) if(ctxt->metai->key_pad[0] != 0x00 || ctxt->metai->iv_pad[0] != 0x00) return FALSE; + //Backup IV, next aes_crypt_ctr alters last 2 bytes + u8 biv[0x10]; + memcpy(&biv, ctxt->metai->iv, 0x10); + //Decrypt metadata header, metadata section headers and keys. nc_off = 0; aes_setkey_enc(&aes_ctxt, ctxt->metai->key, METADATA_INFO_KEYBITS); @@ -857,8 +864,16 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) ctxt->sceh->header_len - (sizeof(sce_header_t) + ctxt->sceh->metadata_offset + sizeof(metadata_info_t)), &nc_off, ctxt->metai->iv, sblk, (u8 *)ctxt->metah, (u8 *)ctxt->metah); + //Restore IV from its backup if changed + if(memcmp(ctxt->metai->iv, biv, 0x10) != 0) + memcpy(ctxt->metai->iv, &biv, 0x10); + + //Dump to file. + _write_buffer("metah_dec.bin", (u8 *) ctxt->metah, ctxt->sceh->header_len - (sizeof(sce_header_t) + ctxt->sceh->metadata_offset + sizeof(metadata_info_t))); + //Fixup headers. _es_metadata_header(ctxt->metah); + for(i = 0; i < ctxt->metah->section_count; i++) _es_metadata_section_header(&ctxt->metash[i]); @@ -869,6 +884,10 @@ BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset) ctxt->keys = (u8 *)ctxt->metash + sizeof(metadata_section_header_t) * ctxt->metah->section_count; ctxt->keys_len = ctxt->metah->key_count * 0x10; + //Dump to file. + _write_buffer("keys_file.bin", (u8 *) ctxt->metash + sizeof(metadata_section_header_t) * ctxt->metah->section_count, ctxt->metah->key_count * 0x10); + _write_buffer("signature.bin", (u8 *) ctxt->keys + ctxt->metah->key_count * 0x10, 0x30); + //Set SELF only headers. if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SELF) {