Advertising (This ad goes away for registered users. You can Login or Register)

[CODE] PS3 Minis Header Endian Swapping Sample 0.0.1

Underground PS3 information and discussions
Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
Post Reply
arnold
Posts: 100
Joined: Tue Nov 23, 2010 10:17 am

[CODE] PS3 Minis Header Endian Swapping Sample 0.0.1

Post by arnold » Tue Apr 02, 2013 12:39 am

Hi all,

This is some code that will change the endianness of certain entries within the header and ISO block table of PS3 minis.

I wrote this with very short notice and very quickly. There may be silly mistakes and stuff that just doesn't make sense. With that data that I was provided, the app works fine.

If this ends up being of no use, I don't mind. It's not particularly fascinating anyway.

Hello to all PSP Devs, PS3 Devs and zecoxao.

Tested under gcc i686-apple-darwin11


http://pb.arnoldbronson.comli.com/index.php?show=91

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>

/*
 *	PS3 Minis Header Endian Swapping Sample 0.0.1
 *	by arnold, zecoxao Tues 2 April 2013
 *
 */

typedef char s8;
typedef unsigned char u8;
typedef unsigned int u32;

//Endian swap for u32.
#define _ES32(val) \
	((u32)(((((u32)val) & 0xff000000) >> 24) | \
	       ((((u32)val) & 0x00ff0000) >> 8 ) | \
	       ((((u32)val) & 0x0000ff00) << 8 ) | \
	       ((((u32)val) & 0x000000ff) << 24)))


typedef struct MINIS_ISO_BIN_HEADER {
	u32 magic1;				// 0x0 - NPUMDIMG
	u32 magic2;				// 0x4
	u32 unk1;				// 0x8
	u32 block_size;			// 0xC
	u8 content_id[0x24];	// 0x10	e.g. UP4123-NPUZ00119_00-ANGRYBIRDSGAME01
	u8 junk0[0x14];			// 0x34
	u32 unk2;				// 0x48
	u32 junk1[2];			// 0x4C
	u32 lba_start;			// 0x54
	u32 junk2;				// 0x58
	u32 unk3;				// 0x5C
	u32 junk3;				// 0x60
	u32 lba_end;			// 0x64
	u32 unk4;				// 0x68
	u32 np_table_addr;		// 0x6C
	u8 game_id[10];			// 0x70 - e.g. NPUZ-00119
	u8 junk4[0x26];			// 0x7A
	u8 header_key[0x10];	// 0xA0
	u8 junk5[0x50];			// 0xB0
}MINIS_ISO_BIN_HEADER;


//0x100 - 
typedef struct MINIS_ISO_BIN_BLOCK_TABLE_ENTRY
{
	u8 block_mac[0x10];		// 0x00
	u32 block_offset;		// 0x10
	u32 block_size;			// 0x14
	u8 padding[8];			// 0x18
}MINIS_ISO_BIN_BLOCK_TABLE_ENTRY;


int ReadFile(char *file, int seek, void *buf, int size);
int WriteFile(char *file, void *buf, int size);

int ProcessHeader(char* inFile, char* outFile);

u32 GetNumberOfBlocks(char* inFile);
int ProcessIsoTable(char* inFile, char* outFile, int blockCount);


int main(int args, char* argp[])
{
	if (args < 6)
	{
		printf("Usage: <toolname> <header_in.bin> <header_out.bin> <isotable_in.bin> <isotable_out.bin> <final_out.bin>\n");
		
		return -1;
	}
	
	printf("PS3 Minis Header Endian Swapping Sample 0.0.1\n");
	printf("by arnold with info from zecoxao\nBuilt %s\n\n", __DATE__);
	
	
	if (ProcessHeader(argp[1], argp[2]) < 0)
	{
		printf("Error Processing Header\n");
		return -2;
	}
	
	int blocks = GetNumberOfBlocks(argp[1]);
	
	//printf("%d\n", blocks);
	
	if (ProcessIsoTable(argp[3], argp[4], blocks) < 0)
	{
		printf("Error Processing ISO Table\n");
		return -3;
	}
	
	
	printf("Writing final result to %s\n", argp[5]);
	
	char* finalBuffer = malloc(sizeof(MINIS_ISO_BIN_HEADER) + blocks * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));
	
	ReadFile(argp[2], 0, finalBuffer, sizeof(MINIS_ISO_BIN_HEADER));
	
	ReadFile(argp[4], 0, finalBuffer + sizeof(MINIS_ISO_BIN_HEADER), blocks * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));
	
	WriteFile(argp[5], finalBuffer, sizeof(MINIS_ISO_BIN_HEADER) + blocks * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));
	
	free(finalBuffer);
	
	return 0;
}


int ReadFile(char *file, int seek, void *buf, int size)
{
	
	long fileSize = -1;
	
	size_t res = -1;
	
	FILE* fd = fopen(file, "rb");
	
	if (fd == NULL)
	{
		printf("ReadFile: Error, File cannot be opened\n");
		return -2;
	}
	
	// Get file size
	fseek(fd, 0, SEEK_END);
	
	fileSize = ftell(fd);
	
	rewind(fd);
	
	res = fread (buf, 1, size, fd);
	
	fclose (fd);
	
	return res;
}

int WriteFile(char *file, void *buf, int size)
{	
	FILE* fd = fopen(file, "wb");
	
	if (fd < 0)
	{
		return -1; //fd;
	}
	
	int written = fwrite(buf, 1, size, fd);
	
	fclose(fd);
	
	return written;
}


int ProcessHeader(char* inFile, char* outFile)
{
	printf("Processing Header...\n");
	
	u8* headerBuffer = malloc(1024);
	
	memset(headerBuffer, 0, 1024);
	
	printf("Input: %s \nOutput: %s\n", inFile, outFile);
	
	// Read the header to memory
	ReadFile(inFile, 0, headerBuffer, 256);
	
	
	MINIS_ISO_BIN_HEADER* minisHeader = (MINIS_ISO_BIN_HEADER*)headerBuffer;
	
	// Check MAGIC
	
	if (minisHeader->magic1 != 0x4D55504E &&
		minisHeader->magic2 != 0x474D4944)
	{
		printf("Not a valid header input\n");
		return -1;
	}
	
	// Swap the required header entries
	printf("Swapping required header entries\n");
	
	minisHeader->unk1 = _ES32(minisHeader->unk1);
	
	minisHeader->block_size = _ES32(minisHeader->block_size);
	
	minisHeader->unk2 = _ES32(minisHeader->unk2);
	
	minisHeader->lba_start = _ES32(minisHeader->lba_start);
	
	minisHeader->unk3 = _ES32(minisHeader->unk3);
	
	minisHeader->lba_end = _ES32(minisHeader->lba_end);
	
	minisHeader->unk4 = _ES32(minisHeader->unk4);
	
	minisHeader->np_table_addr = _ES32(minisHeader->np_table_addr);	
	
	
	// Write the file to disk
	printf("Writing new header to disk\n");
	WriteFile(outFile, headerBuffer, 256);
	
	printf("Done Processing Header.\n");
	
	free(headerBuffer);
	
	return 0;
}

u32 GetNumberOfBlocks(char* inFile)
{
	u32 blockCount = 0;
	
	/*
	LBA start    (np_header+0x54)
	LBA end      (np_header+0x64)
	block_size   (np_header+0x0c)
	lba_size     (end-start+1)
	total_blocks (lba_size+block_size-1)/block_size
	*/
	
	printf("Getting Header Data for Block Count...\n");
	
	u8* headerBuffer = malloc(1024);
	
	memset(headerBuffer, 0, 1024);
	
	printf("Input: %s\n", inFile);
	
	// Read the header to memory
	ReadFile(inFile, 0, headerBuffer, 256);
	
	
	MINIS_ISO_BIN_HEADER* minisHeader = (MINIS_ISO_BIN_HEADER*)headerBuffer;
	
	// Check MAGIC
	
	if (minisHeader->magic1 != 0x4D55504E &&
		minisHeader->magic2 != 0x474D4944)
	{
		printf("Not a valid header input\n");
		return -1;
	}
	
	u32 lba_start = minisHeader->lba_start;
	u32 lba_end = minisHeader->lba_end;
	u32 block_size = minisHeader->block_size;
	u32 lba_size = lba_end - lba_start + 1;
	
	
	blockCount = (lba_size + block_size - 1)/block_size;
	
	printf("blockCount: %d = (%d + %d - 1)/%d\n", blockCount, lba_size, block_size, block_size);
	
	
	free(headerBuffer);
	
	return blockCount;
}

int ProcessIsoTable(char* inFile, char* outFile, int blockCount)
{
	printf("Processing ISO table...\n");
	
	u8* dataBuffer = malloc(blockCount * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));
	
	MINIS_ISO_BIN_BLOCK_TABLE_ENTRY* block_table = (MINIS_ISO_BIN_BLOCK_TABLE_ENTRY*)dataBuffer;
	
	memset(dataBuffer, 0, blockCount * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));
	
	printf("Input: %s \nOutput: %s\n", inFile, outFile);
	
	// Read the header to memory
	ReadFile(inFile, 0, dataBuffer, blockCount * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));

	printf("Total blocks to swap: %d\n", blockCount);
	
	int i = 0;
	
	for (i = 0; i < blockCount; i++) 
	{
		block_table[i].block_offset = _ES32(block_table[i].block_offset);
		block_table[i].block_size = _ES32(block_table[i].block_size);
	}
	
	printf("Swapped data in %d entries in ISO table\n", i);
	
	// Write the file to disk
	printf("Writing new ISO table to disk\n");
	WriteFile(outFile, block_table, blockCount * sizeof(MINIS_ISO_BIN_BLOCK_TABLE_ENTRY));
	
	printf("Done Processing ISO Table.\n");
	
	free(block_table);
	
	return 0;
}

Advertising

Post Reply

Return to “Programming & security”