|
Homebrew Developer
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
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
|