mirror of
https://github.com/naehrwert/scetool.git
synced 2025-04-24 13:47:47 +00:00
Updated to v.0.2.12
- Enabled options to compress and skip sections for SPU selfs. - Extended information about the NPDRM selfs.
This commit is contained in:
parent
4b0402d598
commit
3aba4846ea
7 changed files with 132 additions and 33 deletions
|
@ -85,6 +85,9 @@ OPTIONS Possible Values Explanation
|
|||
-j, --np-add-sig TRUE/FALSE(default) Whether to add a NP sig. or not.
|
||||
|
||||
==> History <==
|
||||
Version 0.2.12
|
||||
- Enabled options to compress and skip sections for SPU selfs.
|
||||
- Extended information about the NPDRM selfs.
|
||||
Version 0.2.11
|
||||
- Added .klic files support for easy decryption of the free-license-type NPDRM selfs.
|
||||
- "PS3" path environment variable will now be searched for "data", "raps" and "klics" directories.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define _CONFIG_H_
|
||||
|
||||
/*! scetool base version. */
|
||||
#define SCETOOL_VERSION_BASE "0.2.11"
|
||||
#define SCETOOL_VERSION_BASE "0.2.12"
|
||||
|
||||
/*! Private build. */
|
||||
//#define CONFIG_PRIVATE_BUILD
|
||||
|
|
|
@ -55,7 +55,7 @@ BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
|
|||
u8 npdrm_key[0x10];
|
||||
u8 npdrm_iv[0x10];
|
||||
int i;
|
||||
|
||||
|
||||
if((np = _sce_find_ci_npdrm(ctxt)) == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@ -183,7 +183,7 @@ BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp)
|
|||
return FALSE;
|
||||
|
||||
cinp->magic = _ES32(NP_CI_MAGIC);
|
||||
cinp->unknown_0 = _ES32(1);
|
||||
cinp->version = _ES32(1);
|
||||
cinp->license_type = _ES32(npconf->license_type);
|
||||
cinp->app_type = _ES32(npconf->app_type);
|
||||
memcpy(cinp->content_id, npconf->content_id, 0x30);
|
||||
|
@ -193,8 +193,8 @@ BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp)
|
|||
//Better than boring random bytes!
|
||||
memcpy(cinp->rndpad, CONFIG_NPDRM_WATERMARK, 0x10);
|
||||
#endif
|
||||
cinp->unknown_1 = _ES64(0);
|
||||
cinp->unknown_2 = _ES64(0);
|
||||
cinp->limited_time_start = _ES64(0);
|
||||
cinp->limited_time_end = _ES64(0);
|
||||
|
||||
//Generate control info hash key.
|
||||
for(i = 0; i < 0x10; i++)
|
||||
|
|
|
@ -381,7 +381,8 @@ typedef struct _ci_data_npdrm
|
|||
{
|
||||
/*! Magic. */
|
||||
u32 magic;
|
||||
u32 unknown_0;
|
||||
/*! Version. */
|
||||
u32 version;
|
||||
/*! License type. */
|
||||
u32 license_type;
|
||||
/*! Application type. */
|
||||
|
@ -394,8 +395,10 @@ typedef struct _ci_data_npdrm
|
|||
u8 hash_cid_fname[0x10];
|
||||
/*! Control info hash. */
|
||||
u8 hash_ci[0x10];
|
||||
u64 unknown_1;
|
||||
u64 unknown_2;
|
||||
/*! Start of the Validity period. */
|
||||
u64 limited_time_start;
|
||||
/*! End of the Validity period. */
|
||||
u64 limited_time_end;
|
||||
} ci_data_npdrm_t;
|
||||
|
||||
/*! Optional header. */
|
||||
|
|
129
src/self.cpp
129
src/self.cpp
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
|
@ -120,6 +121,8 @@ void _print_sce_version(FILE *fp, sce_version_t *sv)
|
|||
void _print_control_info(FILE *fp, control_info_t *ci)
|
||||
{
|
||||
const s8 *name;
|
||||
time_t t;
|
||||
tm* aTm;
|
||||
|
||||
fprintf(fp, "[*] Control Info\n");
|
||||
|
||||
|
@ -158,16 +161,63 @@ void _print_control_info(FILE *fp, control_info_t *ci)
|
|||
ci_data_npdrm_t *np = (ci_data_npdrm_t *)((u8 *)ci + sizeof(control_info_t));
|
||||
//Was already fixed in decrypt_header.
|
||||
//_es_ci_data_npdrm(np);
|
||||
fprintf(fp, " Magic 0x%08X [%s]\n", _ES32(np->magic), (_ES32(np->magic) == NP_CI_MAGIC ? "OK" : "ERROR"));
|
||||
fprintf(fp, " unknown_0 0x%08X\n", _ES32(np->unknown_0));
|
||||
fprintf(fp, " Licence Type 0x%08X\n", _ES32(np->license_type));
|
||||
fprintf(fp, " App Type 0x%08X\n", _ES32(np->app_type));
|
||||
fprintf(fp, " ContentID %s\n", np->content_id);
|
||||
_hexdump(fp, " Random Pad ", 0, np->rndpad, 0x10, FALSE);
|
||||
_hexdump(fp, " CID_FN Hash ", 0, np->hash_cid_fname, 0x10, FALSE);
|
||||
_hexdump(fp, " CI Hash ", 0, np->hash_ci, 0x10, FALSE);
|
||||
fprintf(fp, " unknown_1 0x%016llX\n", _ES64(np->unknown_1));
|
||||
fprintf(fp, " unknown_2 0x%016llX\n", _ES64(np->unknown_2));
|
||||
fprintf(fp, " Magic 0x%08X [%s]\n", _ES32(np->magic), (_ES32(np->magic) == NP_CI_MAGIC ? "OK" : "ERROR"));
|
||||
fprintf(fp, " Version 0x%08X\n", _ES32(np->version));
|
||||
|
||||
name = _get_name(_np_license_types, _ES32(np->license_type));
|
||||
if(name != NULL)
|
||||
{
|
||||
fprintf(fp, " Licence Type ");
|
||||
_PRINT_RAW(fp, "0x%08X ", _ES32(np->license_type));
|
||||
fprintf(fp, "[%s]\n", name);
|
||||
}
|
||||
else
|
||||
fprintf(fp, " Licence Type 0x%08X\n", _ES32(np->license_type));
|
||||
|
||||
name = _get_name(_np_app_types, _ES32(np->app_type));
|
||||
if(name != NULL)
|
||||
{
|
||||
fprintf(fp, " App Type ");
|
||||
_PRINT_RAW(fp, "0x%08X ", _ES32(np->app_type));
|
||||
fprintf(fp, "[%s]\n", name);
|
||||
}
|
||||
else
|
||||
fprintf(fp, " App Type 0x%08X\n", _ES32(np->app_type));
|
||||
|
||||
fprintf(fp, " ContentID %s\n", np->content_id);
|
||||
_hexdump(fp, " Random Pad ", 0, np->rndpad, 0x10, FALSE);
|
||||
_hexdump(fp, " CID_FN Hash ", 0, np->hash_cid_fname, 0x10, FALSE);
|
||||
_hexdump(fp, " CI Hash ", 0, np->hash_ci, 0x10, FALSE);
|
||||
|
||||
t = (time_t)(_ES64(np->limited_time_start) / 1000);
|
||||
aTm = localtime(&t);
|
||||
if(_ES64(np->limited_time_start) != 0)
|
||||
{
|
||||
fprintf(fp, " Validity Start ");
|
||||
_PRINT_RAW(fp, "0x%016llX ", _ES64(np->limited_time_start));
|
||||
fprintf(fp, "[%04d/%02d/%02d %02d:%02d:%02d]\n",aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(fp, " Validity Start ");
|
||||
_PRINT_RAW(fp, "0x%016llX ", _ES64(np->limited_time_start));
|
||||
fprintf(fp, "[Unlimited]\n");
|
||||
}
|
||||
|
||||
t = (time_t)(_ES64(np->limited_time_end) / 1000);
|
||||
aTm = localtime(&t);
|
||||
if(_ES64(np->limited_time_end) != 0)
|
||||
{
|
||||
fprintf(fp, " Validity End ");
|
||||
_PRINT_RAW(fp, "0x%016llX ", _ES64(np->limited_time_end));
|
||||
fprintf(fp, "[%04d/%02d/%02d %02d:%02d:%02d]\n",aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(fp, " Validity End ");
|
||||
_PRINT_RAW(fp, "0x%016llX ", _ES64(np->limited_time_end));
|
||||
fprintf(fp, "[Unlimited]\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -222,7 +272,7 @@ void _print_opt_header(FILE *fp, opt_header_t *oh)
|
|||
fprintf(fp, " Flags 0x%016llX [ ", cf->flags);
|
||||
_print_cap_flags_flags(fp, cf);
|
||||
fprintf(fp, "]\n");
|
||||
|
||||
|
||||
fprintf(fp, " unknown_6 0x%08X\n", cf->unk6);
|
||||
fprintf(fp, " unknown_7 0x%08X\n", cf->unk7);
|
||||
}
|
||||
|
@ -573,11 +623,25 @@ BOOL self_write_to_elf(sce_buffer_ctxt_t *ctxt, const s8 *elf_out)
|
|||
{
|
||||
if(_ES32(msh[i].type) == METADATA_SECTION_TYPE_PHDR)
|
||||
{
|
||||
_es_elf32_phdr(&ph[_ES32(msh[i].index)]);
|
||||
fseek(fp, ph[_ES32(msh[i].index)].p_offset, SEEK_SET);
|
||||
fwrite(ctxt->scebuffer + _ES64(msh[i].data_offset), sizeof(u8), _ES64(msh[i].data_size), fp);
|
||||
if(_ES32(msh[i].compressed) == METADATA_SECTION_COMPRESSED)
|
||||
{
|
||||
_es_elf32_phdr(&ph[_ES32(msh[i].index)]);
|
||||
u8 *data = (u8 *)malloc(ph[_ES32(msh[i].index)].p_filesz);
|
||||
|
||||
_zlib_inflate(ctxt->scebuffer + _ES64(msh[i].data_offset), _ES64(msh[i].data_size), data, ph[_ES32(msh[i].index)].p_filesz);
|
||||
fseek(fp, ph[_ES32(msh[i].index)].p_offset, SEEK_SET);
|
||||
fwrite(data, sizeof(u8), ph[_ES32(msh[i].index)].p_filesz, fp);
|
||||
|
||||
free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
_es_elf32_phdr(&ph[_ES32(msh[i].index)]);
|
||||
fseek(fp, ph[_ES32(msh[i].index)].p_offset, SEEK_SET);
|
||||
fwrite(ctxt->scebuffer + _ES64(msh[i].data_offset), sizeof(u8), _ES64(msh[i].data_size), fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Write section headers.
|
||||
if(_ES64(ctxt->self.selfh->shdr_offset) != 0)
|
||||
|
@ -827,7 +891,7 @@ static BOOL _create_optional_headers(sce_buffer_ctxt_t *ctxt, self_config_t *sco
|
|||
_set_cap_flags(self_type, capf);
|
||||
else
|
||||
memcpy(capf, sconf->cap_flags, 0x20);
|
||||
|
||||
|
||||
list_add_back(ctxt->self.ohs, oh);
|
||||
}
|
||||
break;
|
||||
|
@ -850,7 +914,7 @@ static BOOL _create_optional_headers(sce_buffer_ctxt_t *ctxt, self_config_t *sco
|
|||
if(sconf->indiv_seed != NULL)
|
||||
memcpy(is, sconf->indiv_seed, sconf->indiv_seed_size);
|
||||
#endif
|
||||
|
||||
|
||||
list_add_back(ctxt->self.ohs, oh);
|
||||
}
|
||||
break;
|
||||
|
@ -916,7 +980,7 @@ static BOOL _build_self_32(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
|
|||
_es_elf32_ehdr(ehdr);
|
||||
|
||||
//Copy program headers.
|
||||
ctxt->makeself->phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff , sizeof(Elf32_Phdr) * ehdr->e_phnum);
|
||||
ctxt->makeself->phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff, sizeof(Elf32_Phdr) * ehdr->e_phnum);
|
||||
ctxt->makeself->phsize = sizeof(Elf32_Phdr) * ehdr->e_phnum;
|
||||
phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff, sizeof(Elf32_Phdr) * ehdr->e_phnum);
|
||||
|
||||
|
@ -933,17 +997,33 @@ static BOOL _build_self_32(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
|
|||
|
||||
//Copy sections, fill section infos and metadata section headers.
|
||||
ctxt->self.si = (section_info_t *)malloc(sizeof(section_info_t) * ehdr->e_phnum);
|
||||
u32 loff = 0xFFFFFFFF, skip = 0;
|
||||
for(i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
_es_elf32_phdr(&phdrs[i]);
|
||||
void *sec = _memdup(ctxt->makeself->elf + phdrs[i].p_offset, phdrs[i].p_filesz);
|
||||
//Never compress sections on SPU SELFs.
|
||||
sce_add_data_section(ctxt, sec, phdrs[i].p_filesz, FALSE);
|
||||
|
||||
//Add section info.
|
||||
_add_phdr_section(ctxt, phdrs[i].p_type, phdrs[i].p_filesz, i);
|
||||
//Fill metadata section header.
|
||||
sce_set_metash(ctxt, METADATA_SECTION_TYPE_PHDR, phdrs[i].p_type == PT_LOAD ? TRUE : FALSE, i);
|
||||
|
||||
//Fill metadata section header but skip identical program header offsets.
|
||||
if(sconf->skip_sections == TRUE && (phdrs[i].p_offset == loff || !(phdrs[i].p_type == PT_LOAD || phdrs[i].p_type == PT_PS3_PRX_RELOC || phdrs[i].p_type == 0x700000A8)))
|
||||
{
|
||||
const s8 *name = _get_name(_ph_types, phdrs[i].p_type);
|
||||
if(name != NULL)
|
||||
_LOG_VERBOSE("Skipped program header %-8s @ 0x%08X (0x%08X)\n", name, phdrs[i].p_offset, phdrs[i].p_filesz);
|
||||
else
|
||||
_LOG_VERBOSE("Skipped program header 0x%08X @ 0x%08X (0x%08X)\n", phdrs[i].p_type, phdrs[i].p_offset, phdrs[i].p_filesz);
|
||||
skip++;
|
||||
}
|
||||
else
|
||||
{
|
||||
void *sec = _memdup(ctxt->makeself->elf + phdrs[i].p_offset, phdrs[i].p_filesz);
|
||||
//SPU sections may be compressed.
|
||||
sce_add_data_section(ctxt, sec, phdrs[i].p_filesz, TRUE);
|
||||
sce_set_metash(ctxt, METADATA_SECTION_TYPE_PHDR, TRUE /*(phdrs[i].p_type == PT_LOAD || phdrs[i].p_type == PT_PS3_PRX_RELOC || phdrs[i].p_type == 0x700000A8) ? TRUE : FALSE*/, i - skip);
|
||||
}
|
||||
|
||||
loff = phdrs[i].p_offset;
|
||||
}
|
||||
|
||||
//Section info count.
|
||||
|
@ -953,10 +1033,11 @@ static BOOL _build_self_32(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
|
|||
|
||||
//Add a section for the section headers.
|
||||
if(sconf->add_shdrs == TRUE)
|
||||
if(_add_shdrs_section(ctxt, i) == TRUE)
|
||||
if(_add_shdrs_section(ctxt, i - skip) == TRUE)
|
||||
i++;
|
||||
|
||||
//Metadata.
|
||||
i -= skip;
|
||||
ctxt->metah->section_count = _ES32(i);
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -58,6 +58,15 @@ id_to_name_t _optional_header_types[] =
|
|||
{0, NULL}
|
||||
};
|
||||
|
||||
/*! NPDRM license types. */
|
||||
id_to_name_t _np_license_types[] =
|
||||
{
|
||||
{NP_LICENSE_NETWORK, "NETWORK"},
|
||||
{NP_LICENSE_LOCAL, "LOCAL"},
|
||||
{NP_LICENSE_FREE, "FREE"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/*! NPDRM application types. */
|
||||
id_to_name_t _np_app_types[] =
|
||||
{
|
||||
|
@ -65,7 +74,7 @@ id_to_name_t _np_app_types[] =
|
|||
{NP_TYPE_EXEC, "EXEC"},
|
||||
{NP_TYPE_USPRX, "USPRX"},
|
||||
{NP_TYPE_UEXEC, "UEXEC"},
|
||||
{0, NULL},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/*! Auth IDs. */
|
||||
|
|
|
@ -21,6 +21,9 @@ extern id_to_name_t _control_info_types[];
|
|||
/*! Optional header types. */
|
||||
extern id_to_name_t _optional_header_types[];
|
||||
|
||||
/*! NPDRM license types. */
|
||||
extern id_to_name_t _np_license_types[];
|
||||
|
||||
/*! NPDRM application types. */
|
||||
extern id_to_name_t _np_app_types[];
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue