// func for building the SCE hdr (for SPP) int build_spp_sce_hdr(sce_header_t* pSceHdr, u64 ContentSizeOriginal) { sce_header_t* pSce_Header = NULL; int retval = -1; // validate input params if (pSceHdr == NULL) goto exit; // populate the SCE-HDR fields for PKG build pSce_Header = (sce_header_t*)pSceHdr; memset(pSceHdr, 0, sizeof(sce_header_t)); wbe32((u8*)&pSce_Header->magic, SCE_HEADER_MAGIC); // magic wbe32((u8*)&pSce_Header->version, SCE_HEADER_VERSION_2); // version wbe16((u8*)&pSce_Header->key_revision, KEY_REVISION_0); // key revision wbe16((u8*)&pSce_Header->header_type, SCE_HEADER_TYPE_SPP); // SCE header type; pkg wbe32((u8*)&pSce_Header->metadata_offset, 0); // meta offset wbe64((u8*)&pSce_Header->header_len, sizeof(sce_header_t) + sizeof(SPP_META_HDR)); // header len wbe64((u8*)&pSce_Header->data_len, ContentSizeOriginal); // status success retval = STATUS_SUCCESS; exit: return retval; }
static void build_sce_hdr(void) { memset(sce_hdr, 0, sizeof sce_hdr); wbe32(sce_hdr + 0x00, 0x53434500); // magic wbe32(sce_hdr + 0x04, 2); // version wbe16(sce_hdr + 0x08, 0); // dunno, sdk type? wbe16(sce_hdr + 0x0a, 3); // SCE header type; pkg wbe32(sce_hdr + 0x0c, 0); // meta offset wbe64(sce_hdr + 0x10, sizeof sce_hdr + sizeof meta_hdr); wbe64(sce_hdr + 0x18, 0x80 + pkg_real_size); }
static void save_checksum(u8 *x) { u32 i; u16 sum, nsum; slot_checksum(x + 8); slot_checksum(x + 8 + 0x0a94); slot_checksum(x + 8 + 2*0x0a94); sum = 0; for (i = 0; i < 0x0ffe; i++) sum += be16(x + 2*i); nsum = -(sum + 0x0ffe); wbe16(x + 0x1ffc, sum); wbe16(x + 0x1ffe, nsum); }
void fs_hmac_meta(const unsigned char *super_data, short super_blk, unsigned char *hmac) { unsigned char extra[0x40]; memset(extra,0,0x40); wbe16(extra + 0x12, super_blk); fs_hmac_generic(super_data,0x40000,extra,0x40,hmac); }
static void build_sce_hdr(void) { memset(sce_header, 0, sizeof sce_header); wbe32(sce_header + 0x00, 0x53434500); // magic wbe32(sce_header + 0x04, 2); // version wbe16(sce_header + 0x08, sdk_type); // dunno, sdk type? wbe16(sce_header + 0x0a, 1); // SCE header type; self wbe32(sce_header + 0x0c, meta_offset); wbe64(sce_header + 0x10, header_size); wbe64(sce_header + 0x18, round_up(elf_size, ALIGNMENT)); wbe64(sce_header + 0x20, 3); // dunno, has to be 3 wbe64(sce_header + 0x28, info_offset); wbe64(sce_header + 0x30, elf_offset); wbe64(sce_header + 0x38, phdr_offset); wbe64(sce_header + 0x40, shdr_offset); wbe64(sce_header + 0x48, sec_offset); wbe64(sce_header + 0x50, version_offset); wbe64(sce_header + 0x58, ctrl_offset); wbe64(sce_header + 0x60, 0x70); // ctrl size }
void fs_hmac_data(const unsigned char *data, int uid, const unsigned char *name, int entry_n, int x3, short blk, unsigned char *hmac) { int i,j; unsigned char extra[0x40]; memset(extra,0,0x40); wbe32(extra, uid); memcpy(extra+4,name,12); wbe16(extra + 0x12, blk); wbe32(extra + 0x14, entry_n); wbe32(extra + 0x18, x3); // fprintf(stderr,"extra (%s): \nX ",name); // for(i=0;i<0x20;++i){ // fprintf(stderr,"%02X ",extra[i]); // if(!((i+1)&0xf)) fprintf(stderr,"\nX "); // } fs_hmac_generic(data,0x4000,extra,0x40,hmac); }
u8 patch_sdk(u32 size, u8 *ptr) { u32 i; u8 patched; patched = 0; for (i = 0 ; i < size ; i++) { if (memcmp(ptr + i, sys_proc_param, 4) == 0) { patched = 1; printf("Found at offset %08x\n", i); print_hash((ptr + i), 0x10); printf("\n"); printf("Replace %04x with %04x\n", be16(ptr+i+9), 0x3400); wbe16(ptr + i + 9, 0x3400); print_hash((ptr + i), 0x10); printf("\n"); break; } } return patched; }
static void dol2elf(char *inname, char *outname) { u8 dolheader[0x100]; u8 elfheader[0x400] = {0}; u8 segheader[0x400] = {0}; u8 secheader[0x400] = {0}; u8 strings[0x400] = "\0.strtab"; u32 str_offset = 9; struct section section[19]; FILE *in, *out; u32 n_text, n_data, n_total; u32 entry; u32 elf_offset; u32 i; u8 *p; in = fopen(inname, "rb"); fread(dolheader, 1, sizeof dolheader, in); elf_offset = 0x1000; // 7 text, 11 data for (i = 0; i < 18; i++) { section[i].offset = be32(dolheader + 4*i); section[i].addr = be32(dolheader + 0x48 + 4*i); section[i].size = be32(dolheader + 0x90 + 4*i); section[i].elf_offset = elf_offset; elf_offset += -(-section[i].size & -0x100); } // bss section[18].offset = 0; section[18].addr = be32(dolheader + 0xd8); section[18].size = be32(dolheader + 0xdc); section[18].elf_offset = elf_offset; entry = be32(dolheader + 0xe0); n_text = 0; for (i = 0; i < 7; i++) if (section[i].size) { sprintf(strings + str_offset, ".text.%d", n_text); section[i].str_offset = str_offset; str_offset += 8; n_text++; } n_data = 0; for ( ; i < 18; i++) if (section[i].size) { sprintf(strings + str_offset, ".data.%d", n_data); section[i].str_offset = str_offset; str_offset += i < 16 ? 8 : 9; n_data++; } n_total = n_text + n_data; if (section[18].size) { sprintf(strings + str_offset, ".bss"); section[i].str_offset = str_offset; str_offset += 5; n_total++; } printf("%d text sections, %d data sections, %d total (includes bss)\n", n_text, n_data, n_total); printf("entry point = %08x\n", entry); memset(elfheader, 0, sizeof elfheader); elfheader[0] = 0x7f; elfheader[1] = 0x45; elfheader[2] = 0x4c; elfheader[3] = 0x46; elfheader[4] = 0x01; elfheader[5] = 0x02; elfheader[6] = 0x01; wbe16(elfheader + 0x10, 2); wbe16(elfheader + 0x12, 0x14); wbe32(elfheader + 0x14, 1); wbe32(elfheader + 0x18, entry); wbe32(elfheader + 0x1c, 0x400); wbe32(elfheader + 0x20, 0x800); wbe32(elfheader + 0x24, 0); wbe16(elfheader + 0x28, 0x34); wbe16(elfheader + 0x2a, 0x20); wbe16(elfheader + 0x2c, n_total); wbe16(elfheader + 0x2e, 0x28); wbe16(elfheader + 0x30, n_total + 2); wbe16(elfheader + 0x32, 1); p = segheader; for (i = 0; i < 19; i++) if (section[i].size) { wbe32(p + 0x00, 1); wbe32(p + 0x04, section[i].elf_offset); wbe32(p + 0x08, section[i].addr); wbe32(p + 0x0c, section[i].addr); wbe32(p + 0x10, i == 18 ? 0 : section[i].size); wbe32(p + 0x14, section[i].size); wbe32(p + 0x18, i < 7 ? 5 : 6); wbe32(p + 0x1c, 0x20); p += 0x20; } p = secheader + 0x28; wbe32(p + 0x00, 1); wbe32(p + 0x04, 3); wbe32(p + 0x08, 0); wbe32(p + 0x0c, 0); wbe32(p + 0x10, 0xc00); wbe32(p + 0x14, 0x400); wbe32(p + 0x18, 0); wbe32(p + 0x1c, 0); wbe32(p + 0x20, 1); wbe32(p + 0x24, 0); p += 0x28; for (i = 0; i < 19; i++) if (section[i].size) { wbe32(p + 0x00, section[i].str_offset); wbe32(p + 0x04, i == 18 ? 8 : 1); wbe32(p + 0x08, i < 7 ? 6 : 3); wbe32(p + 0x0c, section[i].addr); wbe32(p + 0x10, section[i].elf_offset); wbe32(p + 0x14, section[i].size); wbe32(p + 0x18, 0); wbe32(p + 0x1c, 0); wbe32(p + 0x20, 0x20); wbe32(p + 0x24, 0); p += 0x28; } out = fopen(outname, "wb"); fwrite(elfheader, 1, sizeof elfheader, out); fwrite(segheader, 1, sizeof segheader, out); fwrite(secheader, 1, sizeof secheader, out); fwrite(strings, 1, sizeof strings, out); for (i = 0; i < 19; i++) if (section[i].size) { p = malloc(section[i].size); fseek(in, section[i].offset, SEEK_SET); fread(p, 1, section[i].size, in); fseek(out, section[i].elf_offset, SEEK_SET); fwrite(p, 1, section[i].size, out); free(p); } fclose(out); fclose(in); }