void GetNcchAesCounter(ncch_info *ctx, u8 counter[16], u8 type) { u8 *titleId = ctx->titleId; u32 i; u32 x = 0; memset(counter, 0, 16); if (ctx->formatVersion == 2 || ctx->formatVersion == 0) { endian_memcpy(counter,titleId,8,LE); counter[8] = type; } else if (ctx->formatVersion == 1) { switch(type){ case ncch_exhdr : x = ctx->exhdrOffset; break; case ncch_exefs : x = ctx->exefsOffset; break; case ncch_romfs : x = ctx->romfsOffset; break; } for(i=0; i<8; i++) counter[i] = titleId[i]; for(i=0; i<4; i++) counter[12+i] = x>>((3-i)*8); } //memdump(stdout,"CTR: ",counter,16); }
//MISC void char_to_int_array(unsigned char destination[], char source[], int size, int endianness, int base) { char tmp[size][2]; unsigned char *byte_array = malloc(size*sizeof(unsigned char)); memset(byte_array, 0, size); memset(destination, 0, size); memset(tmp, 0, size*2); for (int i = 0; i < size; i ++){ tmp[i][0] = source[(i*2)]; tmp[i][1] = source[((i*2)+1)]; tmp[i][2] = '\0'; byte_array[i] = (unsigned char)strtol(tmp[i], NULL, base); } endian_memcpy(destination,byte_array,size,endianness); /** for (int i = 0; i < size; i++){ switch (endianness){ case(BIG_ENDIAN): destination[i] = byte_array[i]; break; case(LITTLE_ENDIAN): destination[i] = byte_array[((size-1)-i)]; break; } } **/ _free(byte_array); }
/* Disassembler entry point */ int gnu_disppc_str(char *str, const u8 *inst, ut64 offset) { struct disassemble_info info; str[0] = '\0'; buf_global = str; Offset = (unsigned long)offset; endian_memcpy(bytes, inst, 4); // TODO handle thumb /* prepare disassembler */ memset(&info,'\0', sizeof(struct disassemble_info)); info.buffer = bytes; info.read_memory_func = &ppc_buffer_read_memory; info.symbol_at_address_func = &symbol_at_address; info.memory_error_func = &hoho; info.print_address_func = &print_address; info.buffer_vma = Offset; info.buffer_length = 4; info.endian = 0;//config_get_i("cfg.bigendian"); info.fprintf_func = buf_fprintf; //info.fprintf_func = &cons_fprintf; info.stream = stdout; // endian is controlled by radare if (print_insn_big_powerpc((bfd_vma)Offset, &info) == -1) { strcpy(str, " (data)"); return 1; } return 0; }
//MISC void char_to_int_array(unsigned char destination[], char source[], int size, int endianness, int base) { char tmp[size][2]; unsigned char *byte_array = malloc(size*sizeof(unsigned char)); memset(byte_array, 0, size); memset(destination, 0, size); memset(tmp, 0, size*2); for (int i = 0; i < size; i ++){ tmp[i][0] = source[(i*2)]; tmp[i][1] = source[((i*2)+1)]; tmp[i][2] = '\0'; byte_array[i] = (unsigned char)strtol(tmp[i], NULL, base); } endian_memcpy(destination,byte_array,size,endianness); _free(byte_array); }
int PrepAESMAC(AESMAC_CTX *ctx) { u8 savegame_type[6][8] = {"CTR-EXT0","CTR-SYS0","CTR-NOR0","CTR-SAV0","CTR-SIGN","CTR-9DB0"}; memset(ctx->hash,0,0x20); if(ctx->type == 0) return Fail; else if(ctx->type == mac_import_db){ db_sha256_block finalblock; memset(&finalblock,0,sizeof(db_sha256_block)); memcpy(finalblock.savegame_type,savegame_type[CTR_9DB0],8); u32_to_u8(finalblock.db_id,0x3,LE); memcpy(finalblock.diff_header,ctx->header,0x100); ctr_sha(&finalblock,sizeof(db_sha256_block),ctx->hash,CTR_SHA_256); } else if(ctx->type == mac_title_db){ db_sha256_block finalblock; memset(&finalblock,0,sizeof(db_sha256_block)); memcpy(finalblock.savegame_type,savegame_type[CTR_9DB0],8); u32_to_u8(finalblock.db_id,0x2,LE); memcpy(finalblock.diff_header,ctx->header,0x100); ctr_sha(&finalblock,sizeof(db_sha256_block),ctx->hash,CTR_SHA_256); } else if(ctx->type == mac_extdata){ extdata_sha256_block finalblock; memset(&finalblock,0,sizeof(extdata_sha256_block)); memcpy(finalblock.savegame_type,savegame_type[CTR_EXT0],8); endian_memcpy(finalblock.image_id,ctx->image_id,4,LE); endian_memcpy(finalblock.subdir_id,ctx->subdir_id,4,LE); u32_to_u8(finalblock.unknown,ctx->is_quote_dat,LE); endian_memcpy(finalblock.image_id_dup,ctx->image_id,4,LE); endian_memcpy(finalblock.subdir_id_dup,ctx->subdir_id,4,LE); memcpy(finalblock.diff_header,ctx->header,0x100); ctr_sha(&finalblock,sizeof(extdata_sha256_block),ctx->hash,CTR_SHA_256); } else if(ctx->type == mac_sys_save){ sys_savedata_sha256_block finalblock; memset(&finalblock,0,sizeof(sys_savedata_sha256_block)); memcpy(finalblock.savegame_type,savegame_type[CTR_SYS0],8); endian_memcpy(finalblock.save_id,ctx->saveid,8,LE); memcpy(finalblock.disa_header,ctx->header,0x100); ctr_sha(&finalblock,sizeof(sys_savedata_sha256_block),ctx->hash,CTR_SHA_256); } else if(ctx->type == mac_sd_save){ sdcard_savegame_sha256_block finalblock; memset(&finalblock,0,sizeof(sdcard_savegame_sha256_block)); memcpy(finalblock.savegame_type,savegame_type[CTR_SIGN],8); endian_memcpy(finalblock.program_id,ctx->programid,8,LE); // Generating CTR_SAV0 hash ctr_sav0_sha256_block pre_block; memset(&pre_block,0,sizeof(ctr_sav0_sha256_block)); memcpy(pre_block.savegame_type,savegame_type[CTR_SAV0],8); memcpy(pre_block.disa_header,ctx->header,0x100); ctr_sha(&pre_block,sizeof(ctr_sav0_sha256_block),finalblock.ctr_sav0_block_hash,CTR_SHA_256); // ctr_sha(&finalblock,sizeof(sdcard_savegame_sha256_block),ctx->hash,CTR_SHA_256); } else if(ctx->type == mac_card_save){ gamecard_savegame_sha256_block finalblock; memset(&finalblock,0,sizeof(gamecard_savegame_sha256_block)); memcpy(finalblock.savegame_type,savegame_type[CTR_SAV0],8); // Generating CTR_NOR0 hash ctr_nor0_sha256_block pre_block; memset(&pre_block,0,sizeof(ctr_nor0_sha256_block)); memcpy(pre_block.savegame_type,savegame_type[CTR_NOR0],8); memcpy(pre_block.disa_header,ctx->header,0x100); ctr_sha(&pre_block,sizeof(ctr_nor0_sha256_block),finalblock.ctr_nor0_block_hash,CTR_SHA_256); // ctr_sha(&finalblock,sizeof(gamecard_savegame_sha256_block),ctx->hash,CTR_SHA_256); } else return Fail; return 0; }