[ create a new paste ] login | about

Link: http://codepad.org/PrARwNoM    [ raw code | fork ]

C, pasted on Mar 9:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <openssl/md5.h>


typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;

typedef struct {
    u8 zeroes[128]; // padding
    u32 imet; // "IMET"
    u8 unk[8];  // 0x0000060000000003 fixed, unknown purpose
    u32 sizes[3]; // icon.bin, banner.bin, sound.bin
    u32 flag1; // unknown
	u8 names[7][84]; // JP, EN, DE, FR, ES, IT, NL
    u8 zeroes_2[840]; // padding
    u8 crypto[16]; // MD5 of 0x40 to 0x640 in header. crypto should be all 0's when calculating final MD5
} IMET;

typedef struct {
	u32 imd5; // 'IMD5'
	u32 filesize; //size of rest of file
	u8 zeroes[8]; //padding
	u8 crypto[16]; //MD5 of rest of file
} IMD5;



u16 be16(const u8 *p)
{
	return (p[0] << 8) | p[1];
}

u32 be32(const u8 *p)
{
	return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}

u32 filesize (FILE *file)
{
	u32 curpos, endpos;
	if ( file == NULL )
	{
		return -1;
	}
	curpos = ftell ( file );
	fseek ( file, 0, 2 );
	endpos = ftell ( file );
	fseek ( file, curpos, 0 );
	return endpos;
}

void IMETSign (const char * mainfile, const char * destfile, const char * channelname, const char * iconbinfile, const char * bannerbinfile, const char * soundbinfile)
{
	IMET header;
	FILE * infile, * outfile, * bannerbin, * iconbin, * soundbin;
	u32 fsize;
	char * buffer;
	char tag [] = {'T', 'E', 'M', 'I'};
	int i, j, k;
	
	memset(header.zeroes, 0, sizeof(u8) * 128);
	
	header.imet = be32((u8 *) &tag);
	
	memset(header.unk, 0, sizeof(u8) * 8);
	header.unk[2] = 6;
	header.unk[7] = 3;
	
	iconbin = fopen(iconbinfile, "r");
	if (iconbin==NULL) 
	{
		printf ("icon.bin file error.\n");
		return;
	}
	
	bannerbin = fopen(bannerbinfile, "r");
	if (bannerbin==NULL) 
	{
		printf ("banner.bin file error.\n");
		return;
	}
	
	soundbin = fopen(soundbinfile, "r");
	if (soundbin==NULL) 
	{
		printf ("sound.bin file error.\n");
		return;
	}
	
	header.sizes[0] = htonl(filesize(bannerbin));
	header.sizes[1] = htonl(filesize(bannerbin));
	header.sizes[2] = htonl(filesize(soundbin));
	
	fclose(bannerbin);
	fclose(iconbin);
	fclose(soundbin);
	
	header.flag1 = 0x00;
	
	memset(header.names, 0, sizeof(u8) * 84 * 7);
	
	for(i=0, k=0; i<strlen(channelname); i++)
	{
		for(j=0; j<8; j++)
		{
			header.names[j][k]=0;
		}
		k++;
		for(j=0; j<8; j++)
		{
			header.names[j][k]=channelname[i];
		}
		k++;
	}
	
	memset(header.zeroes_2, 0, sizeof(u8) * 840);
	memset(header.crypto, 0, sizeof(u8) * 16);
	MD5(((u8 *) &header) + 0x40, 0x600, (u8 *) header.crypto);
	
	infile = fopen(mainfile, "r");
	if (infile==NULL) 
	{
		printf ("Input file error.\n");
		return;
	}
	fseek (infile , 0 , SEEK_END);
	fsize = ftell (infile);
	rewind (infile);
	buffer = (char *) malloc( sizeof(char) * fsize);
	if (buffer == NULL) 
	{
		printf ("Buffer error.\n"); 
		return;
	}
	fread (buffer, 1, fsize, infile);
	fclose (infile);
	
	outfile = fopen(destfile, "w");
	if (outfile==NULL) 
	{
		printf ("Output file error.\n");
		return;
	}
	
	fwrite (&header, 1, sizeof(IMET), outfile );
	fwrite (buffer, 1, fsize, outfile );
	
	fclose(outfile);
	free (buffer);
}

void IMD5Sign (const char * mainfile, const char * destfile)
{
	IMD5 header;
	FILE * infile, * outfile;
	u32 fsize;
	unsigned char * buffer;
	char tag [] = {'5', 'D', 'M', 'I'};
	
	infile = fopen(mainfile, "r");
	if (infile==NULL) 
	{
		printf ("Input file error.\n");
		return;
	}
	
	fseek (infile , 0 , SEEK_END);
	fsize = ftell (infile);
	rewind (infile);
	
	buffer = (unsigned char *) malloc( sizeof(char) * fsize);
	if (buffer == NULL) 
	{
		printf ("Buffer error.\n"); 
		return;
	}
	
	fread (buffer, 1, fsize, infile);
	printf("Read input file.\n");
	fclose (infile);
	
	header.imd5 = be32((u8 *) &tag);
	header.filesize = htonl(fsize);
	memset(header.zeroes, 0, sizeof(u8) * 8);
	MD5(buffer, fsize, (u8 *) header.crypto);
	
	outfile = fopen(destfile, "w");
	if (outfile==NULL) 
	{
		printf ("Output file error.\n");
		return;
	}
	
	fwrite (&header, 1, sizeof(IMD5), outfile );
	fwrite (buffer, 1, fsize, outfile );
	printf("Output new file with IMD5 header.\n");
	
	fclose(outfile);
	free (buffer);
}


int main (int argc, const char *argv[]) 
{
    if(argc < 4)
	{
		printf("Usage: bannersigner -IMET/IMD5 <infile> <outfile> [\"CHANNELNAME\" icon.bin banner.bin sound.bin]\n-IMET = IMET header, used in 00000000.app\n-IMD5 = IMD5 header, used in banner.bin, sound.bin, and icon.bin\n[\"CHANNELNAME\" banner.bin icon.bin sound.bin] = Required for -IMET, otherwise ignored.\n");
		return 0;
	}
	
	if(strncmp(argv[1], "-IMET", 5)==0) //IMET
	{
		IMETSign(argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
	}
	else if(strncmp(argv[1], "-IMD5", 5)==0) //IMD5 STUFF
	{
		IMD5Sign(argv[2], argv[3]);
	}
	else
	{
		printf("Usage: bannersigner -IMET/IMD5 <infile> <outfile> [CHANNELNAME icon.bin banner.bin sound.bin]\n-IMET = IMET header, used in 00000000.app\n-IMD5 = IMD5 header, used in banner.bin, sound.bin, and icon.bin\n[CHANNELNAME banner.bin icon.bin sound.bin] = Required for -IMET, otherwise ignored.\n");
		return 0;
	}
	
    return 0;
}


Create a new paste based on this one


Comments: