⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dumprom.cpp

📁 dumprom source code,use for learning the dumprom.exe tool for wince
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            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 + -