View Single Post
Old 01-25-2013   #70
anaria
Homebrew Developer
 
anaria's Avatar
 
Join Date: Feb 2009
Posts: 80
Likes: 34
Liked 93 Times in 27 Posts
Mentioned: 16 Post(s)
Tagged: 0 Thread(s)
Originally Posted by defyboy View Post
Thank you for this most useful tool, I'm glad my painstaking reverse engineering and documentation came in handy for someone.

I would like to upload this to the wiki's download section if you don't mind.

Also, just a comment on checking the 0x00 and 0xFF areas, I have a few samples where areas that usually are 0xFF are indeed 0x00. I am not sure what conditions cause this but I assume it's from different boundaries from previous firmwares.

Basically, areas that are 0xFF will be so because NOR flash memory in it's "erased" state contains all 1's, a write operation is able to change a 1 to a 0 however a block erase operation is required to revert 0's to 1's. Areas that are 0x00 are simply where blank data has been written over an erased block, usually to fill up a boundary.

As for a final report, it would be nice to give a pass or warnings on what specific parts of flash are incorrect.
You're most welcome. But You are the one who deserves the thanks

Of course, please do upload it it's my pleasure, if this is confirmed to definitely be useful I hope it can profit to all of us.

You exactly confirm what I was scared of, this seems to be the problem in ros/revocation ...
This means that I'll have to find a routine to check these areas for both cases, in which case I should check if we have only 00 or only FF but never other value.

I worked on below draft but it cannot be valid in all cases.
Code:
uint8_t CheckFilledData (FILE *FileToRead, uint32_t *PercentCheck){
	int Cursor=0;
	int Cursor2=0;
	uint32_t SizedCheck=0;
	uint8_t Status=EXIT_SUCCESS;
	uint8_t Status2=EXIT_SUCCESS;
	uint32_t bootldrSize;
	uint32_t bootldrFilledSize;
	uint32_t metldrSize;
	uint32_t metldrFilledSize;
	uint32_t trvk_prg0Size;
	uint32_t trvk_prg0FilledSize;
    uint32_t trvk_prg1Size;
	uint32_t trvk_prg1FilledSize;
    uint32_t trvk_pkg0Size;
	uint32_t trvk_pkg0FilledSize;
    uint32_t trvk_pkg1Size;
	uint32_t trvk_pkg1FilledSize;
    uint32_t ros0Size;
	uint32_t ros0FilledSize;
    uint32_t ros1Size;
	uint32_t ros1FilledSize;

    uint32_t LastFileTOC;
    uint32_t LastFileOffset;
    uint32_t LastFileSize;

    char *DataRead;

	char *metldrOffset0;
	char *bootldrOffset0;
	char *trvk_prg0Offset0;
    char *trvk_prg1Offset0;
    char *trvk_pkg0Offset0;
    char *trvk_pkg1Offset0;
	//    char *ros0Offset0;
	//    char *ros1Offset0;
    //uint32_t ros0Offset0;
    //uint32_t ros1Offset0;

	DataRead = malloc(0x10);

	metldrOffset0  = malloc(5);
	bootldrOffset0  = malloc(5);
	trvk_prg0Offset0 = malloc(5);
    trvk_prg1Offset0 = malloc(5);
    trvk_pkg0Offset0 = malloc(5);
    trvk_pkg1Offset0 = malloc(5);
	//    ros0Offset0 = malloc(5);
	//    ros1Offset0 = malloc(5);

	printf("******************************\n");
	printf("* Area filled with 00 or FF  *\n");
	printf("******************************\n");

	GetSection(FileToRead, SectionTOC[asecure_loader].Offset+0x42, 0x02, HexaType, metldrOffset0);	
	metldrSize = (strtol(metldrOffset0,NULL,16))*0x10+0x40;
	metldrFilledSize = 0x2F000 - metldrSize - SectionTOC[asecure_loader].Offset - 0x40;

	GetSection(FileToRead, SectionTOC[bootldr].Offset+0x02, 0x02, HexaType, bootldrOffset0);	
	bootldrSize = (strtol(bootldrOffset0,NULL,16))*0x10+0x40;
	bootldrFilledSize = 0x1000000 - bootldrSize - SectionTOC[bootldr].Offset;

	GetSection(FileToRead, SectionTOC[trvk_prg0].Offset+0x0E, 0x02, HexaType, trvk_prg0Offset0);
	trvk_prg0Size = strtol(trvk_prg0Offset0,NULL,16);
	trvk_prg0FilledSize = 0x040FF0 - trvk_prg0Size - SectionTOC[trvk_prg0].Offset - 0x10;
    printf("debug: trvk_prg0Size:'0x%08X' trvk_prg0FilledSize:'0x%08X' \n",trvk_prg0Size,trvk_prg0FilledSize);
	
	GetSection(FileToRead, SectionTOC[trvk_prg1].Offset+0x0E, 0x02, HexaType, trvk_prg1Offset0);
	trvk_prg1Size = strtol(trvk_prg1Offset0,NULL,16);
	trvk_prg1FilledSize = 0x060FF0 - trvk_prg1Size - SectionTOC[trvk_prg1].Offset - 0x10;
    printf("debug: trvk_prg1Size:'0x%08X' trvk_prg1FilledSize:'0x%08X' \n",trvk_prg1Size,trvk_prg1FilledSize);
	
	GetSection(FileToRead, SectionTOC[trvk_pkg0].Offset+0x0E, 0x02, HexaType, trvk_pkg0Offset0);
	trvk_pkg0Size = strtol(trvk_pkg0Offset0,NULL,16);
	trvk_pkg0FilledSize = 0x080FF0 - trvk_pkg0Size - SectionTOC[trvk_pkg0].Offset - 0x10;
    printf("debug: trvk_pkg0Size:'0x%08X' trvk_pkg0FilledSize:'0x%08X' \n",trvk_pkg0Size,trvk_pkg0FilledSize);
	
	GetSection(FileToRead, SectionTOC[trvk_pkg1].Offset+0x0E, 0x02, HexaType, trvk_pkg1Offset0);
	trvk_pkg1Size = strtol(trvk_pkg1Offset0,NULL,16);
	trvk_pkg1FilledSize = 0x0A0FF0 - trvk_pkg1Size - SectionTOC[trvk_pkg1].Offset - 0x10;
    printf("debug: trvk_pkg1Size:'0x%08X' trvk_pkg1FilledSize:'0x%08X' \n",trvk_pkg1Size,trvk_pkg1FilledSize);
	//at ros0 offset + 0x14: nb of files, (nb of files) * 0x30 = size of TOC
    GetSection(FileToRead, SectionTOC[ros0].Offset+0x14, 0x04, HexaType, DataRead);
	LastFileTOC = (strtol(DataRead,NULL,16))*0x30-0x10;
	//last file position found at (ros0 offset) + (size of TOC) - 0x10
    GetSection(FileToRead, SectionTOC[ros0].Offset+LastFileTOC, 0x08, HexaType, DataRead);
    LastFileOffset = strtol(DataRead,NULL,16);
	//+ 0x8 for its size.
    GetSection(FileToRead, SectionTOC[ros0].Offset+LastFileTOC+0x08, 0x08, HexaType, DataRead);
    LastFileSize = strtol(DataRead,NULL,16);
    ros0Size = 0x10 + LastFileOffset + LastFileSize;
	//From end of last file pos + size to next section - 0x10 : full of 00
    //last 0x10 bytes are full of FF !!??
    ros0FilledSize = SectionTOC[ros1].Offset - SectionTOC[ros0].Offset - ros0Size -0x10;
    //printf("debug: ros0Size:'0x%08X' ros0FilledSize:'0x%08X' \n",ros0Size,ros0FilledSize);

	//at ros1 offset + 0x14: nb of files, (nb of files) * 0x30 = size of TOC
    GetSection(FileToRead, SectionTOC[ros1].Offset+0x14, 0x04, HexaType, DataRead);
	LastFileTOC = (strtol(DataRead,NULL,16))*0x30-0x10;
	//last file position found at (ros1 offset) + (size of TOC) - 0x10
    GetSection(FileToRead, SectionTOC[ros1].Offset+LastFileTOC, 0x08, HexaType, DataRead);
    LastFileOffset = strtol(DataRead,NULL,16);
	//+ 0x8 for its size.
    GetSection(FileToRead, SectionTOC[ros1].Offset+LastFileTOC+0x08, 0x08, HexaType, DataRead);
    LastFileSize = strtol(DataRead,NULL,16);
    ros1Size = 0x10 + LastFileOffset + LastFileSize;
	//From end of last file pos + size to next section - 0x10 : full of 00
    //last 0x10 bytes are full of FF !!??
    ros1FilledSize = SectionTOC[cvtrm].Offset - SectionTOC[ros1].Offset - ros1Size -0x10;
    //printf("debug: ros1Size:'0x%08X' ros1FilledSize:'0x%08X' \n",ros1Size,ros1FilledSize);

	struct Sections SectionFilled[] = {
		{"flashformat", 0x000210, 0x01F0, HexaType+DisplayFailOnly, 1, "FF"},
		{"asecure_loader", SectionTOC[asecure_loader].Offset+0x40+metldrSize, metldrFilledSize, HexaType+DisplayFailOnly, 1, "00"},
		{"eEID", 0x030DD0, 0xE230, HexaType+DisplayFailOnly, 1, "FF"},
		{"cISD", 0x03F270, 0x0590, HexaType+DisplayFailOnly, 1, "FF"},
		{"cCSD", 0x03F850, 0x07B0, HexaType+DisplayFailOnly, 1, "FF"},

		// need to investigate size at trvk_prg0 offset + 0x0E
		// until 40FF0 : 00
		// from 40FF0 to next section : FF

		{"trvk_prg0", SectionTOC[trvk_prg0].Offset+0x10+trvk_prg0Size, trvk_prg0FilledSize, HexaType+DisplayFailOnly, 1, "00"},
		{"trvk_prg0", 0x040FF0, 0x01F010, HexaType+DisplayFailOnly, 1, "FF"},
        {"trvk_prg1", SectionTOC[trvk_prg1].Offset+0x10+trvk_prg1Size, trvk_prg1FilledSize, HexaType+DisplayFailOnly, 1, "00"},
        {"trvk_prg1", 0x060FF0, 0x01F010, HexaType+DisplayFailOnly, 1, "FF"},
		{"trvk_pkg0", SectionTOC[trvk_pkg0].Offset+0x10+trvk_pkg0Size, trvk_pkg0FilledSize, HexaType+DisplayFailOnly, 1, "00"},
        {"trvk_pkg0", 0x080FF0, 0x01F010, HexaType+DisplayFailOnly, 1, "FF"},
		{"trvk_pkg1", SectionTOC[trvk_pkg1].Offset+0x10+trvk_pkg1Size, trvk_pkg1FilledSize, HexaType+DisplayFailOnly, 1, "00"},
        {"trvk_pkg1", 0x0A0FF0, 0x01F010, HexaType+DisplayFailOnly, 1, "FF"},

		{"ros0", SectionTOC[ros0].Offset + ros0Size, ros0FilledSize, HexaType+DisplayFailOnly, 1, "00"},  // need to investigate
		{"ros0", SectionTOC[ros0].Offset + ros0Size + ros0FilledSize, 0x10, HexaType+DisplayFailOnly, 1, "FF"},  // need to investigate
		{"ros1", SectionTOC[ros1].Offset + ros1Size, ros1FilledSize, HexaType+DisplayFailOnly, 1, "00"},  // need to investigate
		{"ros1", SectionTOC[ros1].Offset + ros1Size + ros1FilledSize, 0x10, HexaType+DisplayFailOnly, 1, "FF"},  // need to investigate
		//{"cvtrm", 0xECxxxx, 0x0xxxxx, HexaType+DisplayFailOnly, 1, "00"},  // need to investigate
		{"CELL_EXTNOR_AREA", 0xF20040, 0x01C0, HexaType+DisplayFailOnly, 1, "00"},
		{"CELL_EXTNOR_AREA", 0xF20240, 0x01FDC0, HexaType+DisplayFailOnly, 1, "00"},
		{"CELL_EXTNOR_AREA", 0xF40030, 0x01FFD0, HexaType+DisplayFailOnly, 1, "00"},
		{"CELL_EXTNOR_AREA", 0xF60060, 0x93A0, HexaType+DisplayFailOnly, 1, "00"}, // need to calculate the correct start, size seems to be found at 0xF60000E on 2 bytes ?
		{"CELL_EXTNOR_AREA", 0xF69530, 0x06D0, HexaType+DisplayFailOnly, 1, "00"},
		{"CELL_EXTNOR_AREA", 0xF69C00, 0x015400, HexaType+DisplayFailOnly, 1, "FF"},
		{"CELL_EXTNOR_AREA", 0xF80030, 0x01FFD0, HexaType+DisplayFailOnly, 1, "00"},
		{"CELL_EXTNOR_AREA", 0xFA0060, 0x93A0, HexaType+DisplayFailOnly, 1, "00"}, // need to calculate the correct start, size seems to be found at 0xFA0000E on 2 bytes ?
		{"CELL_EXTNOR_AREA", 0xFA9530, 0x06D0, HexaType+DisplayFailOnly, 1, "00"},
		{"CELL_EXTNOR_AREA", 0xFA9C00, 0x015400, HexaType+DisplayFailOnly, 1, "FF"},
		{"bootldr", SectionTOC[bootldr].Offset+bootldrSize, bootldrFilledSize, HexaType+DisplayFailOnly, 1, "FF"},
		{NULL, 0, 0, 0, 0, NULL}
	};

	while (SectionFilled[Cursor].name!=NULL) {
		for (Cursor2=0;Cursor2<SectionFilled[Cursor].Size;Cursor2++) {
			if ((Status2 = ReadSection(SectionFilled[Cursor].name
				, FileToRead
				, SectionFilled[Cursor].Offset+Cursor2
				, 1
				, SectionFilled[Cursor].DisplayType
				, SectionFilled[Cursor].Check
				, SectionFilled[Cursor].Pattern))) {
					printf ("Error at '0x%08X\n",SectionFilled[Cursor].Offset+Cursor2);
			}
			
		}
		if (!Status2) {
			printf ("Succesfully checked '%s' From '0x%08X' size: '0x%08X' full of '0x%s'\n",SectionFilled[Cursor].name,SectionFilled[Cursor].Offset, SectionFilled[Cursor].Size, SectionFilled[Cursor].Pattern);
		}
		else {
			printf ("Some error occured when checking '%s'\n",SectionFilled[Cursor].name);
		}
		Cursor++;
		Status = Status | Status2;
		Status2 = EXIT_SUCCESS;
		SizedCheck = SizedCheck + SectionFilled[Cursor].Size;
	}
	//printf("debug: SectionTOC[trvk_prg0].Offset:'0x%08X' SectionTOC[trvk_prg0].Offset+0x10+trvk_prg0Size:'0x%08X' trvk_pkg0FilledSize:'0x%08X'\n",SectionTOC[trvk_prg0].Offset,SectionTOC[trvk_prg0].Offset+0x10+trvk_prg0Size,trvk_pkg0FilledSize);

	*PercentCheck = SizedCheck;

    free(DataRead);
	free(metldrOffset0);
	free(bootldrOffset0);
    free(trvk_prg0Offset0);
    free(trvk_prg1Offset0);
    free(trvk_pkg0Offset0);
    free(trvk_pkg1Offset0);
    //free(ros0Offset0);
    //free(ros1Offset0);

	return Status;
}
@Sarah1331 I've started to include a global status which should raise a FAIL or PASS after tests are completed.
At the same time I may include a percentage indicating on how much exactly of the NOR has been analyzed.
BTW it is for now exactly checking 30.56% of the NOR's bytes.

@Arcidodo & @nzie , Yep I was too lazy to treat both cases, also I was thinking that reversing is done fast and easily with good tools.

As I mentioned before, I'll do the improvement as far as I can go then document it in accordence to the wiki.
And then I'll have to do 2 things:
- port it for NAND
- evolve it for both bytes order

and I don't know what else...

Last edited by anaria; 01-25-2013 at 05:00 AM. Reason: Typo
anaria is offline   Reply With Quote
Likes: (4)