示例#1
0
/* calculate size of a patched file directly */
static PyObject *
patchedsize(PyObject *self, PyObject *args)
{
	long orig, start, end, len, outlen = 0, last = 0, pos = 0;
	Py_ssize_t patchlen;
	char *bin;

	if (!PyArg_ParseTuple(args, "ls#", &orig, &bin, &patchlen))
		return NULL;

	while (pos >= 0 && pos < patchlen) {
		start = getbe32(bin + pos);
		end = getbe32(bin + pos + 4);
		len = getbe32(bin + pos + 8);
		if (start > end)
			break; /* sanity check */
		pos += 12 + len;
		outlen += start - last;
		last = end;
		outlen += len;
	}

	if (pos != patchlen) {
		if (!PyErr_Occurred())
			PyErr_SetString(mpatch_Error, "patch cannot be decoded");
		return NULL;
	}

	outlen += orig - last;
	return Py_BuildValue("l", outlen);
}
示例#2
0
/* decode a binary patch into a hunk list */
static struct flist *decode(const char *bin, Py_ssize_t len)
{
	struct flist *l;
	struct frag *lt;
	int pos = 0;

	/* assume worst case size, we won't have many of these lists */
	l = lalloc(len / 12);
	if (!l)
		return NULL;

	lt = l->tail;

	while (pos >= 0 && pos < len) {
		lt->start = getbe32(bin + pos);
		lt->end = getbe32(bin + pos + 4);
		lt->len = getbe32(bin + pos + 8);
		if (lt->start > lt->end)
			break; /* sanity check */
		lt->data = bin + pos + 12;
		pos += 12 + lt->len;
		lt++;
	}

	if (pos != len) {
		if (!PyErr_Occurred())
			PyErr_SetString(mpatch_Error, "patch cannot be decoded");
		lfree(l);
		return NULL;
	}

	l->tail = lt;
	return l;
}
示例#3
0
文件: image.c 项目: d0k3/GodMode9
u32 IdentifyImage(const char* path) {
    u8 header[0x200];
    FIL file;
    if (f_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK)
        return 0;
    f_lseek(&file, 0);
    f_sync(&file);
    UINT fsize = f_size(&file);
    UINT bytes_read;
    if ((f_read(&file, header, 0x200, &bytes_read) != FR_OK) || (bytes_read != 0x200)) {
        f_close(&file);
        return 0;
    }
    f_close(&file);
    if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
        (getbe64(header + 0x108) == (u64) 0) && (fsize >= 0x8FC8000)) {
        return IMG_NAND;
    } else if (getbe16(header + 0x1FE) == 0x55AA) { // migt be FAT or MBR
        if ((strncmp((char*) header + 0x36, "FAT12   ", 8) == 0) || (strncmp((char*) header + 0x36, "FAT16   ", 8) == 0) ||
            (strncmp((char*) header + 0x36, "FAT     ", 8) == 0) || (strncmp((char*) header + 0x52, "FAT32   ", 8) == 0)) {
            return IMG_FAT; // this is an actual FAT header
        } else if (((getle32(header + 0x1BE + 0x8) + getle32(header + 0x1BE + 0xC)) < (fsize / 0x200)) && // check file size
            (getle32(header + 0x1BE + 0x8) > 0) && (getle32(header + 0x1BE + 0xC) >= 0x800) && // check first partition sanity
            ((header[0x1BE + 0x4] == 0x1) || (header[0x1BE + 0x4] == 0x4) || (header[0x1BE + 0x4] == 0x6) || // filesystem type
             (header[0x1BE + 0x4] == 0xB) || (header[0x1BE + 0x4] == 0xC) || (header[0x1BE + 0x4] == 0xE))) {
            return IMG_FAT; // this might be an MBR -> give it the benefit of doubt
        }
    }
    return 0;
}
示例#4
0
ctr_tmd_body *tmd_get_body(tmd_context *ctx) 
{
	unsigned int type = getbe32(ctx->buffer);
	ctr_tmd_body *body = NULL;

	if (type == TMD_RSA_2048_SHA256 || type == TMD_RSA_2048_SHA1)
	{
		body = (ctr_tmd_body*)(ctx->buffer + sizeof(ctr_tmd_header_2048));
	}
	else if (type == TMD_RSA_4096_SHA256 || type == TMD_RSA_4096_SHA1)
	{
		body = (ctr_tmd_body*)(ctx->buffer + sizeof(ctr_tmd_header_4096));
	}

	return body;
}
示例#5
0
int main(int argc, char* argv[])
{
	int result = 0;

	fprintf(stdout, "stripiosplugin - based on IOS ELF stripper - by neimod\n");
	if (argc < 3 )
	{
		fprintf(stderr,"Usage: %s <in.elf> <out.bin> [strip addr]\n", argv[0]);

		return -1;
	}

	FILE* fin = fopen(argv[1], "rb");
	FILE* fout = fopen(argv[2], "wb");

	if (fin == 0 || fout == 0)
	{
		if (fin == 0)
			fprintf(stderr,"ERROR opening file %s\n", argv[1]);
		if (fout == 0)
			fprintf(stderr,"ERROR opening file %s\n", argv[2]);
		return 1;
	}

	elfheader header;

	if (fread(&header, sizeof(elfheader), 1, fin) != 1)
	{
		fprintf(stderr,"ERROR reading ELF header\n");
		return 1;
	}

	unsigned long elfmagicword = getbe32(&header.ident0);

	if (elfmagicword != 0x7F454C46)
	{
		fprintf(stderr,"ERROR not a valid ELF\n");
		return 1;
	}

	unsigned long shoff = getbe32(&header.shoff);
	unsigned short shentsize = getbe16(&header.shentsize);
	unsigned short shnum = getbe16(&header.shnum);
	unsigned long memsz = 0, filesz = 0;
	unsigned long vaddr = 0, paddr = 0;

	//printf("shoff %lx\n", shoff);
	//printf("size %x\n", shentsize);
	//printf("entries %x\n", shnum);

	elfshentry* entry = new elfshentry[shnum];

	fseek(fin, shoff, SEEK_SET);
	if (fread(entry, sizeof(elfshentry), shnum, fin) != shnum)
	{
		fprintf(stderr,"ERROR reading sections header\n");
		return 1;
	}

	unsigned short i = 0;
	while (i < shnum)
	{
  		unsigned long addr = getbe32(&entry[i].shaddr);
  		unsigned long offset = getbe32(&entry[i].shoffset);
		unsigned long size = getbe32(&entry[i].shsize);
		if ((addr & ~0xfff) == 0x1377E000) {
  			printf("addr:%lx - ",addr);
			printf("offset:%lx - ",offset);  
			printf("size: %lx\n", size);
		fseek(fin, offset, SEEK_SET);
		char *buf = new char[size];
		if (!buf) {
			fprintf(stderr, "Error allocating memory\n");
			return 2;
		}
		fread(buf, sizeof(char), size, fin);
		if (fwrite(buf, sizeof(char), size, fout) != size) {
			fprintf(stderr, "Error writing output file\n");
			return 2;
		}
		delete [] buf;
		}
		i++;
	}

	if (entry)
		delete[] entry;
	if (fout)
		fclose(fout);

	if (fin)
		fclose(fin);

	return result;
}
示例#6
0
void tmd_print(tmd_context* ctx)
{
	unsigned int type = getbe32(ctx->buffer);
	ctr_tmd_header_4096* header4096 = 0;
	ctr_tmd_header_2048* header2048 = 0;
	ctr_tmd_body* body = 0;
	unsigned int contentcount = 0;
	unsigned int savesize = 0;
	unsigned int titlever = 0;
	unsigned int i;

	if (type == TMD_RSA_2048_SHA256 || type == TMD_RSA_2048_SHA1)
	{
		header2048 = (ctr_tmd_header_2048*)ctx->buffer;
	}
	else if (type == TMD_RSA_4096_SHA256 || type == TMD_RSA_4096_SHA1)
	{
		header4096 = (ctr_tmd_header_4096*)ctx->buffer;
	}
	else
	{
		return;
	}

	body = tmd_get_body(ctx);

	contentcount = getbe16(body->contentcount);
	savesize = getle32(body->savedatasize);
	titlever = getbe16(body->titleversion);
	
	fprintf(stdout, "\nTMD header:\n");
	fprintf(stdout, "Signature type:         %s\n", tmd_get_type_string(type));
	fprintf(stdout, "Issuer:                 %s\n", body->issuer);
	fprintf(stdout, "Version:                %d\n", body->version);
	fprintf(stdout, "CA CRL version:         %d\n", body->ca_crl_version);
	fprintf(stdout, "Signer CRL version:     %d\n", body->signer_crl_version);
	memdump(stdout, "System version:         ", body->systemversion, 8);
	memdump(stdout, "Title id:               ", body->titleid, 8);
	fprintf(stdout, "Title type:             %08x\n", getbe32(body->titletype));
	fprintf(stdout, "Group id:               %04x\n", getbe16(body->groupid));
	if(savesize < sizeKB)
		fprintf(stdout, "Save Size:              %08x\n", savesize);
	else if(savesize < sizeMB)
		fprintf(stdout, "Save Size:              %dKB (%08x)\n", savesize/sizeKB, savesize);
	else
		fprintf(stdout, "Save Size:              %dMB (%08x)\n", savesize/sizeMB, savesize);
	fprintf(stdout, "Access rights:          %08x\n", getbe32(body->accessrights));
	fprintf(stdout, "Title version:          %d.%d.%d (v%d)\n", (titlever >> 10) & 0x3F, (titlever >> 4) & 0x3F, titlever & 0xF, titlever);
	fprintf(stdout, "Content count:          %04x\n", getbe16(body->contentcount));
	fprintf(stdout, "Boot content:           %04x\n", getbe16(body->bootcontent));
	memdump(stdout, "Hash:                   ", body->hash, 32);

	fprintf(stdout, "\nTMD content info:\n");
	for(i = 0; i < TMD_MAX_CONTENTS; i++)
	{
		ctr_tmd_contentinfo* info = (ctr_tmd_contentinfo*)(body->contentinfo + sizeof(ctr_tmd_contentinfo)*i);

		if (getbe16(info->commandcount) == 0)
			continue;

		fprintf(stdout, "Content index:          %04x\n", getbe16(info->index));
		fprintf(stdout, "Command count:          %04x\n", getbe16(info->commandcount));
		memdump(stdout, "Unknown:                ", info->unk, 32);
	}
	fprintf(stdout, "\nTMD contents:\n");
	for(i = 0; i < contentcount; i++)
	{
		ctr_tmd_contentchunk* chunk = (ctr_tmd_contentchunk*)(body->contentinfo + 36*64 + i*48);
		unsigned short type = getbe16(chunk->type);

		fprintf(stdout, "Content id:             %08x\n", getbe32(chunk->id));
		fprintf(stdout, "Content index:          %04x\n", getbe16(chunk->index));
		fprintf(stdout, "Content type:           %04x", getbe16(chunk->type));
		if (type)
		{
			fprintf(stdout, " ");
			if (type & 1)
				fprintf(stdout, "[encrypted]");
			if (type & 2)
				fprintf(stdout, "[disc]");
			if (type & 4)
				fprintf(stdout, "[cfm]");
			if (type & 0x4000)
				fprintf(stdout, "[optional]");
			if (type & 0x8000)
				fprintf(stdout, "[shared]");
		}
		fprintf(stdout, "\n");
		fprintf(stdout, "Content size:           %016"PRIx64"\n", getbe64(chunk->size));

		switch(ctx->content_hash_stat[i]) {
			case 1:  memdump(stdout, "Content hash [OK]:      ", chunk->hash, 32); break;
			case 2:  memdump(stdout, "Content hash [FAIL]:    ", chunk->hash, 32); break;
			default: memdump(stdout, "Content hash:           ", chunk->hash, 32); break; 
		}

		fprintf(stdout, "\n");
	}
}
示例#7
0
u32 SdPadgen(u32 param)
{
    (void) (param); // param is unused here
    SdInfo *info = (SdInfo*) 0x20316000;

    // setup AES key from SD
    SetupSdKeyY0x34(false, NULL);
    
    if (!DebugFileOpen("SDinfo.bin"))
        return 1;
    if (!DebugFileRead(info, 4, 0)) {
        FileClose();
        return 1;
    }
    if (!info->n_entries || info->n_entries > MAX_ENTRIES) {
        FileClose();
        Debug("Bad number of entries!");
        return 1;
    }
    if (!DebugFileRead(info->entries, info->n_entries * sizeof(SdInfoEntry), 4)) {
        FileClose();
        return 1;
    }
    FileClose();
    
    Debug("Number of entries: %i", info->n_entries);
    for(u32 i = 0; i < info->n_entries; i++) {
        PadInfo padInfo = {.keyslot = 0x34, .setKeyY = 0, .size_mb = info->entries[i].size_mb, .mode = AES_CNT_CTRNAND_MODE};
        memcpy(padInfo.ctr, info->entries[i].ctr, 16);
        memcpy(padInfo.filename, info->entries[i].filename, 180);
        Debug ("%2i: %s (%iMB)", i, info->entries[i].filename, info->entries[i].size_mb);
        if (CreatePad(&padInfo) != 0)
            return 1; // this can't fail anyways
    }

    return 0;
}

u32 SdPadgenDirect(u32 param)
{
    (void) (param); // param is unused here
    SdInfo *info = (SdInfo*) 0x20316000;
    char basepath[256];
    u8 movable_keyY[16];
    
    if (SetupSdKeyY0x34(true, movable_keyY) != 0)
        return 1; // movable.sed has to be present in NAND
    
    Debug("");
    if (SdFolderSelector(basepath, movable_keyY) != 0)
        return 1;
    Debug("");
    if (SdInfoGen(info, basepath) != 0)
        return 1;
    if (!info->n_entries) {
        Debug("Nothing found in folder");
        return 1;
    }
    
    Debug("Number of entries: %i", info->n_entries);
    for(u32 i = 0; i < info->n_entries; i++) {
        PadInfo padInfo = {.keyslot = 0x34, .setKeyY = 0, .size_mb = info->entries[i].size_mb, .mode = AES_CNT_CTRNAND_MODE};
        memcpy(padInfo.ctr, info->entries[i].ctr, 16);
        memcpy(padInfo.filename, info->entries[i].filename, 180);
        Debug ("%2i: %s (%iMB)", i, info->entries[i].filename, info->entries[i].size_mb);
        if (CreatePad(&padInfo) != 0)
            return 1; // this can't fail anyways
    }

    return 0;
}

u32 AnyPadgen(u32 param)
{
    (void) (param); // param is unused here
    AnyPadInfo *info = (AnyPadInfo*) 0x20316000;
    
    // get header
    if ((FileGetData("anypad.bin", info, 16, 0) != 16) || !info->n_entries || info->n_entries > MAX_ENTRIES) {
        Debug("Corrupt or not existing: anypad.bin");
        return 1;
    }
    
    // get data
    u32 data_size = info->n_entries * sizeof(AnyPadInfoEntry);
    if (FileGetData("anypad.bin", (u8*) info + 16, data_size, 16) != data_size) {
        Debug("File is missing data: anypad.bin");
        return 1;
    }
    
    Debug("Processing anypad.bin...");
    Debug("Number of entries: %i", info->n_entries);
    for (u32 i = 0; i < info->n_entries; i++) { // this translates all entries to a standard padInfo struct
        AnyPadInfoEntry* entry = &(info->entries[i]);
        PadInfo padInfo = {.keyslot = entry->keyslot, .setKeyY = 0, .size_mb = 0, .size_b = entry->size_b, .mode = entry->mode};
        memcpy(padInfo.filename, entry->filename, 80);
        memcpy(padInfo.ctr, entry->ctr, 16);
        // process keys
        if (entry->setNormalKey)
            setup_aeskey(entry->keyslot, entry->normalKey);
        if (entry->setKeyX)
            setup_aeskeyX(entry->keyslot, entry->keyX);
        if (entry->setKeyY)
            setup_aeskeyY(entry->keyslot, entry->keyY);
        use_aeskey(entry->keyslot);
        // process flags
        if (entry->flags & (AP_USE_NAND_CTR|AP_USE_SD_CTR)) {
            u32 ctr_add = getbe32(padInfo.ctr + 12);
            u8 shasum[32];
            u8 cid[16];
            sdmmc_get_cid((entry->flags & AP_USE_NAND_CTR) ? 1 : 0, (uint32_t*) cid);
            if (entry->mode == AES_CNT_TWLNAND_MODE) {
                sha_quick(shasum, cid, 16, SHA1_MODE);
                for (u32 i = 0; i < 16; i++)
                    padInfo.ctr[i] = shasum[15-i];
            } else {
                sha_quick(shasum, cid, 16, SHA256_MODE);
                memcpy(padInfo.ctr, shasum, 16);
            }
            add_ctr(padInfo.ctr, ctr_add);
        }
        // create the pad
        Debug ("%2i: %s (%ikB)", i, entry->filename, entry->size_b / 1024);
        if (CreatePad(&padInfo) != 0)
            return 1; // this can't fail anyways
    }

    return 0;
}

u32 CtrNandPadgen(u32 param)
{
    char* filename = (param & PG_FORCESLOT4) ? "nand.fat16.slot0x04.xorpad" : "nand.fat16.xorpad";
    u32 keyslot;
    u32 nand_size;

    // legacy sizes & offset, to work with Python 3DSFAT16Tool
    if (GetUnitPlatform() == PLATFORM_3DS) {
        if (param & PG_FORCESLOT4) {
            Debug("This is a N3DS only feature");
            return 1;
        }
        keyslot = 0x4;
        nand_size = 758;
    } else {
        keyslot = (param & PG_FORCESLOT4) ? 0x4 : 0x5;
        nand_size = 1055;
    }

    Debug("Creating NAND FAT16 xorpad. Size (MB): %u", nand_size);
    Debug("Filename: %s", filename);

    PadInfo padInfo = {
        .keyslot = keyslot,
        .setKeyY = 0,
        .size_mb = nand_size,
        .mode = AES_CNT_CTRNAND_MODE
    };
    strncpy(padInfo.filename, filename, 64);
    if(GetNandCtr(padInfo.ctr, 0xB930000) != 0)
        return 1;

    return CreatePad(&padInfo);
}

u32 TwlNandPadgen(u32 param)
{
    (void) (param); // param is unused here
    PartitionInfo* twln_info = GetPartitionInfo(P_TWLN);
    u32 size_mb = (twln_info->size + (1024 * 1024) - 1) / (1024 * 1024);
    Debug("Creating TWLN FAT16 xorpad. Size (MB): %u", size_mb);
    Debug("Filename: twlnand.fat16.xorpad");

    PadInfo padInfo = {
        .keyslot = twln_info->keyslot,
        .setKeyY = 0,
        .size_mb = size_mb,
        .filename = "twlnand.fat16.xorpad",
        .mode = AES_CNT_TWLNAND_MODE
    };
    if(GetNandCtr(padInfo.ctr, twln_info->offset) != 0)
        return 1;

    return CreatePad(&padInfo);
}

u32 Firm0Firm1Padgen(u32 param)
{
    (void) (param); // param is unused here
    PartitionInfo* firm0_info = GetPartitionInfo(P_FIRM0);
    PartitionInfo* firm1_info = GetPartitionInfo(P_FIRM1);
    u32 size_mb = (firm0_info->size + firm1_info->size + (1024 * 1024) - 1) / (1024 * 1024);
    Debug("Creating FIRM0FIRM1 xorpad. Size (MB): %u", size_mb);
    Debug("Filename: firm0firm1.xorpad");

    PadInfo padInfo = {
        .keyslot = firm0_info->keyslot,
        .setKeyY = 0,
        .size_mb = size_mb,
        .filename = "firm0firm1.xorpad",
        .mode = AES_CNT_CTRNAND_MODE
    };
    if(GetNandCtr(padInfo.ctr, firm0_info->offset) != 0)
        return 1;

    return CreatePad(&padInfo);
}
示例#8
0
文件: cia.c 项目: 44670/Project_CTR
void cia_save(cia_context* ctx, u32 type, u32 flags)
{
	u32 offset;
	u32 size;
	u16 contentflags;
	u8 docrypto;
	filepath* path = 0;
	ctr_tmd_body *body;
	ctr_tmd_contentchunk *chunk;
	int i;
	char tmpname[255];

	switch(type)
	{
		case CIATYPE_CERTS:
			offset = ctx->offsetcerts;
			size = ctx->sizecert;
			path = settings_get_certs_path(ctx->usersettings);
		break;

		case CIATYPE_TIK:
			offset = ctx->offsettik;
			size = ctx->sizetik;
			path = settings_get_tik_path(ctx->usersettings);
		break;

		case CIATYPE_TMD:
			offset = ctx->offsettmd;
			size = ctx->sizetmd;
			path = settings_get_tmd_path(ctx->usersettings);
		break;
		
		case CIATYPE_CONTENT:
			offset = ctx->offsetcontent;
			size = ctx->sizecontent;
			path = settings_get_content_path(ctx->usersettings);
			
		break;

		case CIATYPE_META:
			offset = ctx->offsetmeta;
			size = ctx->sizemeta;
			path = settings_get_meta_path(ctx->usersettings);;
		break;

		default:
			fprintf(stderr, "Error, unknown CIA type specified\n");
			return;	
		break;
	}

	if (path == 0 || path->valid == 0)
		return;

	switch(type)
	{
		case CIATYPE_CERTS: fprintf(stdout, "Saving certs to %s\n", path->pathname); break;
		case CIATYPE_TIK: fprintf(stdout, "Saving tik to %s\n", path->pathname); break;
		case CIATYPE_TMD: fprintf(stdout, "Saving tmd to %s\n", path->pathname); break;
		case CIATYPE_CONTENT:

			body  = tmd_get_body(&ctx->tmd);
			chunk = (ctr_tmd_contentchunk*)(body->contentinfo + (sizeof(ctr_tmd_contentinfo) * TMD_MAX_CONTENTS));

			for(i = 0; i < getbe16(body->contentcount); i++) {
				sprintf(tmpname, "%s.%04x.%08x", path->pathname, getbe16(chunk->index), getbe32(chunk->id));
				fprintf(stdout, "Saving content #%04x to %s\n", getbe16(chunk->index), tmpname);
				
				contentflags = getbe16(chunk->type);
				docrypto = contentflags & 1 && !(flags & PlainFlag);

				if(docrypto) // Decrypt if needed
				{
					ctx->iv[0] = (getbe16(chunk->index) >> 8) & 0xff;
					ctx->iv[1] = getbe16(chunk->index) & 0xff;

					ctr_init_cbc_decrypt(&ctx->aes, ctx->titlekey, ctx->iv);
				}

				cia_save_blob(ctx, tmpname, offset, getbe64(chunk->size) & 0xffffffff, docrypto);

				offset += getbe64(chunk->size) & 0xffffffff;
				chunk++;
			}

			memset(ctx->iv, 0, 16);

			return;
		break;

		case CIATYPE_META: fprintf(stdout, "Saving meta to %s\n", path->pathname); break;
	}

	cia_save_blob(ctx, path->pathname, offset, size, 0);
}
示例#9
0
u32 DebugSeekTitleInNand(u32* offset_tmd, u32* size_tmd, u32* offset_app, u32* size_app, TitleListInfo* title_info, u32 max_cnt)
{
    PartitionInfo* ctrnand_info = GetPartitionInfo(P_CTRNAND);
    u8* buffer = (u8*) 0x20316000;
    u32 cnt_count = 0;
    u32 tid_low = 0;
    u32 tmd_id = 0;
    
    Debug("Searching title \"%s\"...", title_info->name);
    Debug("Method 1: Search in title.db...");
    if (SeekTitleInNandDb(&tid_low, &tmd_id, title_info) == 0) {
        char path[64];
        sprintf(path, "TITLE      %08X   %08X   CONTENT    %08XTMD", (unsigned int) title_info->tid_high, (unsigned int) tid_low, (unsigned int) tmd_id);
        if (SeekFileInNand(offset_tmd, size_tmd, path, ctrnand_info) != 0)
            tid_low = 0;
    }
    if (!tid_low) {
        Debug("Method 2: Search in file system...");
        for (u32 i = 0; i < 6; i++) {
            char path[64];
            if (title_info->tid_low[i] == 0)
                continue;
            sprintf(path, "TITLE      %08X   %08X   CONTENT    ????????TMD", (unsigned int) title_info->tid_high, (unsigned int) title_info->tid_low[i]);
            if (SeekFileInNand(offset_tmd, size_tmd, path, ctrnand_info) == 0) {
                tid_low = title_info->tid_low[i];
                break;
            }
        }
    }
    if (!tid_low) {
        Debug("Failed!");
        return 1;
    }
    Debug("Found title %08X%08X", title_info->tid_high, tid_low);
    
    Debug("TMD0 found at %08X, size %ub", *offset_tmd, *size_tmd);
    if ((*size_tmd < 0xC4 + (0x40 * 0x24)) || (*size_tmd > 0x4000)) {
        Debug("TMD has bad size!");
        return 1;
    }
    if (DecryptNandToMem(buffer, *offset_tmd, *size_tmd, ctrnand_info) != 0)
        return 1;
    u32 size_sig = (buffer[3] == 3) ? 0x240 : (buffer[3] == 4) ? 0x140 : (buffer[3] == 5) ? 0x80 : 0;         
    if ((size_sig == 0) || (memcmp(buffer, "\x00\x01\x00", 3) != 0)) {
        Debug("Unknown signature type: %08X", getbe32(buffer));
        return 1;
    }
    cnt_count = getbe16(buffer + size_sig + 0x9E);
    u32 size_tmd_expected = size_sig + 0xC4 + (0x40 * 0x24) + (cnt_count * 0x30);
    if (*size_tmd < size_tmd_expected) {
        Debug("TMD bad size (expected %ub)!", size_tmd_expected );
        return 1;
    }
    buffer += size_sig + 0xC4 + (0x40 * 0x24);
    
    for (u32 i = 0; i < cnt_count && i < max_cnt; i++) {
        char path[64];
        u32 cnt_id = getbe32(buffer + (0x30 * i));
        if (i >= max_cnt) {
            Debug("APP%i was skipped", i);
            continue;
        }
        sprintf(path, "TITLE      %08X   %08X   CONTENT    %08XAPP", (unsigned int) title_info->tid_high, (unsigned int) tid_low, (unsigned int) cnt_id);
        if (SeekFileInNand(offset_app + i, size_app + i, path, ctrnand_info) != 0) {
            Debug("APP%i not found or fragmented!", i);
            return 1;
        }
        Debug("APP%i found at %08X, size %ukB", i, offset_app[i], size_app[i] / 1024);
    }
    
    return 0;
}
示例#10
0
int mload_elf(void *my_elf, data_elf *data_elf)
{
int n,m;
int p;
u8 *adr;
u32 elf=(u32) my_elf;

if(elf & 3) return -1; // aligned to 4 please!

elfheader *head=(void *) elf;
elfphentry *entries;

if(head->ident0!=0x7F454C46) return -1;
if(head->ident1!=0x01020161) return -1;
if(head->ident2!=0x01000000) return -1;

p=head->phoff;

data_elf->start=(void *)  head->entry;

for(n=0; n<head->phnum; n++)
	{
	entries=(void *) (elf+p);
	p+=sizeof(elfphentry);

	if(entries->type == 4)
		{
		adr=(void *) (elf + entries->offset);

        if(getbe32(0)!=0) return -2; // bad info (sure)

		for(m=4; m < entries->memsz; m+=8)
			{
			switch(getbe32(m))
				{
				case 0x9:
					data_elf->start= (void *) getbe32(m+4);
					break;
				case 0x7D:
					data_elf->prio= getbe32(m+4);
					break;
				case 0x7E:
					data_elf->size_stack= getbe32(m+4);
					break;
				case 0x7F:
					data_elf->stack= (void *) (getbe32(m+4));
					break;
				
				}

			}

		}
    else
	if(entries->type == 1  && entries->memsz != 0 && entries->vaddr!=0)
		{

		if(mload_memset((void *) entries->vaddr, 0, entries->memsz)<0) return -1;
		if(mload_seek(entries->vaddr, SEEK_SET)<0) return -1;
	    if(mload_write((void *) (elf + entries->offset), entries->filesz)<0) return -1;
			
		}
	}

return 0;
}