?? dumprom.cpp
字號:
return (*i).first;
}
return 0;
}
#define IMGOFSINCREMENT 0x1000
void ScanRom()
{
set<DWORD> romhdrs;
// future: fix iterating over memblocks, now it does not handle 'holes' in the memory range very well.
int romnr= 0;
for (DWORD romofs= (g_mem.FirstAddress()+IMGOFSINCREMENT-1)&~(IMGOFSINCREMENT-1); romofs<g_mem.LastAddress(); romofs+=IMGOFSINCREMENT)
{
DWORD *rom= (DWORD*)g_mem.GetPtr(romofs);
if (rom==NULL)
continue;
if (rom[ROM_SIGNATURE_OFFSET/sizeof(DWORD)]==ROM_SIGNATURE)
{
if (rom[0] == 0xea0003fe)
g_regions.MarkRegion(romofs, 4, "JUMP to kernel start");
if (b_wm2005_rom)
g_regions.MarkRegion(g_mem.GetOfs(&rom[16]), 12, "'ECEC' -> %08lx %08lx", rom[17], rom[18]);
else
g_regions.MarkRegion(g_mem.GetOfs(&rom[16]), 8, "'ECEC' -> %08lx", rom[17]);
if (romhdrs.find(rom[17])==romhdrs.end())
{
DumpRomHdr(romnr++, rom[17]);
romhdrs.insert(rom[17]); // keep track of multiple pointers to same header.
}
}
}
}
// parse string of format: <ofs>:<len>:<desc>
// or: <start>-<end>:<desc>
bool ParseRegionSpec(const string& spec, DWORD& start, DWORD& length, string& description)
{
string::size_type pos_colon= spec.find(':');
string::size_type pos_2ndcolon= spec.find(':', pos_colon+1);
string::size_type pos_dash= spec.find('-');
if (pos_colon==spec.npos || (pos_2ndcolon==spec.npos && pos_dash==spec.npos))
return false;
if (pos_dash==spec.npos) // it is <ofs>:<len>:<desc>
{
start= strtoul(spec.substr(0, pos_colon).c_str(), 0, 0);
length= strtoul(spec.substr(pos_colon+1, pos_2ndcolon-pos_colon-1).c_str(), 0, 0);
description= spec.substr(pos_2ndcolon+1);
return true;
}
else if (pos_dash < pos_colon) // it is <ofs>-<end>:<desc>
{
start= strtoul(spec.substr(0, pos_dash).c_str(), 0, 0);
DWORD end= strtoul(spec.substr(pos_dash+1, pos_colon-pos_dash-1).c_str(), 0, 0);
length= end-start;
description= spec.substr(pos_colon+1);
return true;
}
else
return false;
}
struct B000FFHeader {
char signature[7];
DWORD imgstart;
DWORD imglength;
DWORD blockstart;
DWORD blocklength;
DWORD blockchecksum;
BYTE data[1];
};
DWORD GetFileSize(FILE *f)
{
fseek(f, 0, SEEK_END);
return ftell(f);
}
typedef enum { FT_B000FF, FT_NBF, FT_BIN } FileType;
bool isNBFHeader(char *hdr)
{
return (hdr[10]=='-' && hdr[15]=='-' && hdr[19]=='-');
}
bool DetermineFileType(FILE *f, DWORD& start, DWORD& length, FileType& type)
{
BYTE buf[32];
fseek(f, 0, SEEK_SET);
if (1!=fread(buf, 32, 1, f))
{
perror("fread");
return false;
}
fseek(f, 0, SEEK_END);
DWORD filesize= ftell(f);
if (strnicmp((char*)buf, "B000FF", 6)==0)
{
B000FFHeader *hdr= (B000FFHeader *)buf;
type= FT_B000FF;
start= 7+5*4;
length= hdr->blocklength;
if (hdr->imglength!=hdr->blocklength || hdr->imgstart!=hdr->blockstart)
return false;
return true;
}
else if (isNBFHeader((char*)buf))
{
type= FT_NBF;
start= 0x20;
length= filesize-start;
return true;
}
else {
type= FT_BIN;
start= 0;
length= filesize;
return true;
}
}
bool ReadDword(FILE *f, DWORD offset, DWORD& dword)
{
if (fseek(f, offset, SEEK_SET))
return false;
if (1!=fread(&dword, sizeof(DWORD), 1, f))
return false;
return true;
}
// this function tries to determine where in the file the image starts.
// it first checks the filetype, checks for ECEC -> knownvalue
// else scan file for 'ECEC', then returns ofs-0x40
bool DetermineImageOffset(FILE *f, DWORD& imagestart, DWORD& imagelength)
{
FileType type;
if (DetermineFileType(f, imagestart, imagelength, type))
{
DWORD sig;
if (ReadDword(f, imagestart+0x40, sig)
&& sig==ROM_SIGNATURE)
return true;
}
// scan for ECEC
fseek(f, 0, SEEK_SET);
BYTE buf[65536+4];
memset(buf, 0, 4);
DWORD ofs=0;
while(1)
{
DWORD nRead= fread(buf+4, 1, 65536, f);
for (BYTE *p= buf ; p<buf+nRead+4 ; p++)
if (*(DWORD*)p==ROM_SIGNATURE)
{
imagestart= ofs+(p-buf-4)-0x40;
imagelength= GetFileSize(f)-imagestart;
return true;
}
memcpy(buf, buf+nRead, 4);
ofs += nRead;
}
return false;
}
// this function tries to find what offset the image is loaded at in ROM.
bool DetermineLoadOffset(FILE *f, DWORD imagestart, DWORD imagelength, DWORD& offset)
{
int max= -1;
DWORD maxbase= 0;
map<DWORD, int> bases;
bool res= false;
#define IMGOFSINCREMENT 0x1000
// imgofs is scanning for 'ECEC' headers
for (DWORD imgofs= 0 ; (imgofs + IMGOFSINCREMENT)<imagelength ; imgofs+=IMGOFSINCREMENT)
{
DWORD sig;
if (!ReadDword(f, imagestart+imgofs+64, sig))
goto err_exit;
if (sig!=ROM_SIGNATURE)
continue;
DWORD romhdr;
if (!ReadDword(f, imagestart+imgofs+68, romhdr))
goto err_exit;
// find imgbase, such that imgbase+imgofs== romhdr[8] = file[romhdr-imgbase+imagestart+8]
for (DWORD imgbase=(romhdr+imagestart- imagelength)&~0xfff ; imgbase< romhdr+imagestart ; imgbase+=0x1000)
{
DWORD physfirst;
if (!ReadDword(f, romhdr+imagestart-imgbase+8, physfirst))
continue;
if (physfirst==imgofs+imgbase)
{
printf("img %08lx : hdr=%08lx base=%08lx commandlineoffset=%08lx\n", imgofs, romhdr, imgbase, imgbase-imagestart);
bases[imgbase]++;
if (bases[imgbase] > max)
{
max= bases[imgbase];
maxbase= imgbase;
}
}
}
}
if (max>0)
{
offset= maxbase-imagestart;
res= true;
}
err_exit:
return res;
}
void usage()
{
printf("Usage: dumprom [options] imagefile [offset [imagefile offset ...]]\n");
printf(" -d <dirpath> - save found files/modules to this path\n");
printf(" -v - verbose : print alignment, struct contents\n");
printf(" -q - quiet : don't print anything\n");
printf(" -n - don't use negative rva fix\n");
printf(" -u <ofs>L<len>:desc - add user defined memory regions to complete image\n");
printf(" -x <offset> - process XIP chain at offset\n");
printf(" -i <offset> - specifiy image start offset\n");
printf(" -3 - use wince3.x decompression\n");
printf(" -4 - use wince4.x decompression [ default ]\n");
printf(" -5 - use wince4.x decompress, and e32rom for wm2005\n");
}
typedef vector<string> stringlist;
#define HANDLEULOPTION(var, type) (argv[i][2] ? var= (type)strtoul(argv[i]+2, 0, 0) : i+1<argc ? var= (type)strtoul(argv[++i], 0, 0) : 0)
#define HANDLESTROPTION(var) (argv[i][2] ? var= argv[i]+2 : i+1<argc ? var= argv[++i] : 0)
int main( int argc, char *argv[])
{
bool bQuiet= false;
char *imagefilename=NULL;
stringlist userregions;
DWORD dwXipOffset= 0;
char *userregionstr= NULL;
FILE *f= NULL;
bool bHaveImageStart= false;
DWORD imagestart=0, imagelength=0;
int argsfound=0;
for (int i=1 ; i<argc ; i++)
{
if (argv[i][0]=='-')
switch(argv[i][1])
{
case 'd':
HANDLESTROPTION(g_outputdirectory);
break;
case 'v':
g_verbose++;
break;
case 'q':
bQuiet= true;
break;
case 'u':
if (HANDLESTROPTION(userregionstr))
userregions.push_back(userregionstr);
break;
case 'x':
HANDLEULOPTION(dwXipOffset, DWORD);
break;
case 'i':
if (HANDLEULOPTION(imagestart, DWORD))
bHaveImageStart= true;
break;
case 'n':
b_use_negative_rva= false;
break;
case '5':
cedecompress= CEDecompressROM;
b_wm2005_rom= true;
break;
case '4':
cedecompress= CEDecompressROM;
break;
case '3':
cedecompress= CEDecompress;
g_iswince3rom= true;
break;
default:
usage();
return 1;
}
else if (argsfound&1) {
DWORD loadoffset= strtoul(argv[i],0,0);
if (!g_mem.LoadFile(loadoffset, imagefilename, 0, 0))
return 1;
argsfound++;
}
else {
imagefilename= argv[i];
if (f) fclose(f);
f= fopen(imagefilename, "rb");
if (f==NULL)
{
perror(imagefilename);
return 1;
}
argsfound++;
}
}
if (argsfound&1) {
if (bHaveImageStart)
imagelength= GetFileSize(f);
if (!bHaveImageStart && !DetermineImageOffset(f, imagestart, imagelength))
{
printf("unable to determine image start offset\n");
return 1;
}
DWORD loadoffset;
if (!DetermineLoadOffset(f, imagestart, imagelength, loadoffset))
{
printf("unable to determine loading offset for %s\n", imagefilename);
return 1;
}
if (!g_mem.LoadFile(loadoffset, imagefilename, 0, 0))
return 1;
}
if (f) fclose(f);
if (argsfound==0) {
usage();
return 1;
}
ScanRom();
// ... not working yet.
// if (dwXipOffset==0)
// dwXipOffset= FindXipRegion();
if (dwXipOffset)
DumpXIPChain(dwXipOffset);
for (stringlist::iterator i= userregions.begin() ; i!= userregions.end() ; ++i)
{
DWORD start, length;
string description;
if (ParseRegionSpec(*i, start, length, description))
g_regions.MarkRegion(start, length, "%s", description.c_str());
}
if (!bQuiet)
g_regions.DumpMemoryMap();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -