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

📄 dumprom.cpp

📁 dumprom source code,use for learning the dumprom.exe tool for wince
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if (buflen!=CEDECOMPRESS_FAILED)
        {
            buf= dcbuf;
        }
        else {
            printf("error decompressing %s\n", filename);
            buflen= end-start;
            delete dcbuf;
            bCompressed=false;
        }
    }

    char fn[1024];
    if (regnr<0)
        _snprintf(fn, 1024, "%s/%s", g_outputdirectory, filename);
    else
        _snprintf(fn, 1024, "%s/%s-%d-%08lx", g_outputdirectory, filename, regnr, realofs);
    FILE *f= fopen(fn, "w+b");
    if (f==NULL)
    {
        perror(fn);
        if (bCompressed)
            delete buf;
        return;
    }
    DWORD nWritten= fwrite(buf, 1, buflen, f);
    if (nWritten!=buflen)
    {
        printf("error writing %ld bytes - wrote %ld\n", buflen, nWritten);
        perror(fn);
    }
    fclose(f);
    if (bCompressed)
        delete buf;
}

bool isObjectContainsSection(const o32_rom& o32, const info& inf)
{
    return o32.o32_rva <= inf.rva && inf.rva+inf.size <= o32.o32_rva + o32.o32_vsize;
}
void CreateOriginalFile(const ROMHDR *rom, const TOCentry *t, const char *filename, const e32_rom *e32, const o32_rom *o32)
{
    char fn[1024];
    _snprintf(fn, 1024, "%s/%s", g_outputdirectory, filename);
    FILE *f= fopen(fn, "w+b");
    if (f==NULL)
    {
        perror(fn);
        return;
    }

    WriteDummyMZHeader(f);

    DWORD dwE32Ofs= ftell(f);
    WriteE32Header(f, rom, e32, t, o32);

    vector<DWORD> o32ofslist;       // list of file offsets to o32_obj structs
    vector<DWORD> dataofslist;      // list of file offsets to start of data objects
    vector<DWORD> datalenlist;      
    typedef map<DWORD, std::pair<DWORD,DWORD> > RvaRvaSizeMap;
    RvaRvaSizeMap rvamap;           // map of rva -> adjusted rva

    memset(g_segmentNameUsage, 0, sizeof(g_segmentNameUsage));
    int i;
    for (i=0 ; i<e32->e32_objcnt ; i++)
    {
        o32ofslist.push_back(ftell(f));
        DWORD rva= WriteO32Header(f, e32, &o32[i]);

        if (rva != o32[i].o32_rva)
            printf("NOTE: section at %08lx iso %08lx for %s\n", rva, o32[i].o32_rva, filename);
        rvamap[o32[i].o32_rva]= std::pair<DWORD,DWORD>(rva, o32[i].o32_vsize);
    }

    WriteAlignment(f, 0x200);

    DWORD dwHeaderSize= ftell(f);

    for (i=0 ; i<e32->e32_objcnt ; i++)
    {
        dataofslist.push_back(ftell(f));
        DWORD datalen= WriteUncompressedData(f, o32[i].o32_dataptr, min(o32[i].o32_vsize, o32[i].o32_psize), o32[i].o32_flags&IMAGE_SCN_COMPRESSED, o32[i].o32_vsize);
        datalenlist.push_back(datalen);

        WriteAlignment(f, 0x200);
    }
    DWORD dwTotalFileSize= ftell(f);

    // fix rawdatalen + dataoffsets in segment list
    for (i=0 ; i<e32->e32_objcnt ; i++)
    {
        fseek(f, o32ofslist[i]+16, SEEK_SET);
        fwrite(&datalenlist[i], 1, sizeof(DWORD), f);   // ofs to o32_psize
        fwrite(&dataofslist[i], 1, sizeof(DWORD), f);   // ofs to o32_dataptr

        // update imp_address's in IMP section
        if (b_use_negative_rva && isObjectContainsSection(o32[i], e32->e32_unit[IMP])) {
            fseek(f, dataofslist[i]+ e32->e32_unit[IMP].rva -o32[i].o32_rva+0x10, SEEK_SET );
            while (1) {
                DWORD imp_addr;
                fread(&imp_addr, 1, sizeof(DWORD), f);  // read ImpHdr.imp_address
                if (imp_addr==0)
                    break;

                // this finds the next rva 
                RvaRvaSizeMap::iterator s= rvamap.upper_bound(imp_addr);
                if (s!=rvamap.end() && s!=rvamap.begin()) {
                    s--;
                    if (imp_addr < (*s).first+(*s).second.second) {
 //                     printf("moving imp %08lx from rva[%08lx-%08lx] -> %08lx-%08lx  : %08lx\n",
 //                             imp_addr, (*s).first, (*s).first+(*s).second.second,
 //                             (*s).second.first, (*s).second.first+(*s).second.second,
 //                             imp_addr-(*s).first +(*s).second.first);
                        imp_addr -= (*s).first -(*s).second.first;
                        fseek(f, -4, SEEK_CUR);
                        fwrite(&imp_addr, 1, sizeof(DWORD), f);
                        fseek(f, 0x10, SEEK_CUR);
                    }
                    else {
                        printf("!!! %08lx after %08lx but not before %08lx\n", imp_addr, (*s).first, (*s).first+(*s).second.second);
                    }
                }
            }
        }
    }

    fseek(f, dwE32Ofs+0x54, SEEK_SET);  // ofs to e32_hdrsize
    fwrite(&dwHeaderSize, 1, sizeof(DWORD), f);

    fseek(f, dwTotalFileSize, SEEK_SET);
    fclose(f);

    //todo: set fileattributes + datetime.
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void DumpXIPChainEntry(int xipnr, XIPCHAIN_ENTRY *xip)
{
    g_regions.MarkRegion(g_mem.GetOfs(xip), sizeof(XIPCHAIN_ENTRY), "xip%d : %s", xipnr, xip->szName);
    g_regions.MarkRegion((DWORD)xip->pvAddr, 0, "start xip%d : %s", xipnr, xip->szName);

    if (g_verbose)
        g_regions.MarkRegion((DWORD)xip->pvAddr+xip->dwLength, 0, "end xip%d : %s", xipnr, xip->szName);
}

void DumpXIPChain(DWORD dwXipOffset)
{
    XIPCHAIN_INFO *xipchain= (XIPCHAIN_INFO *)g_mem.GetPtr(dwXipOffset);
    if (xipchain==NULL)
        return;

    if (xipchain->cXIPs > MAX_ROM)
    {
        printf("ERROR - invalid xipchain\n");
        return;
    }
    g_regions.MarkRegion(dwXipOffset, sizeof(DWORD), "xipchain head");

    XIPCHAIN_ENTRY *xip= &xipchain->xipEntryStart;

    for (DWORD i=0 ; i<xipchain->cXIPs ; ++i)
    {
        DumpXIPChainEntry(i, &xip[i]);
    }
}


typedef std::set<DWORD> DwordSet;
DwordSet g_extensions_processed;
bool extensionAlreadyProcessed(DWORD dwOffset)
{
  DwordSet::iterator it = g_extensions_processed.find(dwOffset);
  return it != g_extensions_processed.end();
}
void recordExtensionProcessed(DWORD dwOffset)
{
    g_extensions_processed.insert(dwOffset);
}
void DumpExtensions(DWORD dwPidOffset)
{
    if (extensionAlreadyProcessed(dwPidOffset))
        return;
    recordExtensionProcessed(dwPidOffset);

    ROMPID *pid= (ROMPID *)g_mem.GetPtr(dwPidOffset);

    if (pid==NULL)
        return;
    // first is inside nk.exe
    pid= (ROMPID*)g_mem.GetPtr(dwPidOffset=(DWORD)pid->pNextExt);
    while (pid) {
        g_regions.MarkRegion(dwPidOffset, sizeof(ROMPID), "rom extension entry %s", pid->s.name);
        g_regions.MarkRegion((DWORD)pid->s.pdata, pid->s.length, "rom extension data %s", pid->s.name);

        pid= (ROMPID*)g_mem.GetPtr(dwPidOffset=(DWORD)pid->pNextExt);
    }
}
void DumpModuleTOCentry(const ROMHDR *rom, int modnr, DWORD ofs)
{
    TOCentry *t= (TOCentry *)g_mem.GetPtr(ofs);
    if (t==NULL)
    {
        printf("invalid modtoc ofs %08lx\n", ofs);
        return;
    }

    char *filename= (char *)g_mem.GetPtr((DWORD)t->lpszFileName);
    if (filename==NULL)
        return;

    g_regions.MarkRegion(ofs, sizeof(TOCentry), "modent %3d %08lx %08lx%08lx %8d %08lx %s",
            modnr, t->dwFileAttributes, t->ftTime.dwHighDateTime, t->ftTime.dwLowDateTime, t->nFileSize, t->ulLoadOffset, filename);

    g_regions.MarkRegion((DWORD)t->lpszFileName, strlen(filename)+1, "modname %s", filename);

    e32_rom *e32= (e32_rom *)g_mem.GetPtr((DWORD)t->ulE32Offset);
    if (e32==NULL)
        return;
    if (b_wm2005_rom) {
        printf("NOTE: removing %08lx from e32 struct for %s\n", *(DWORD*)e32->e32_unit, filename);
        memmove((BYTE*)e32->e32_unit, (BYTE*)e32->e32_unit+4, ROM_EXTRA*sizeof(struct info)+sizeof(DWORD));
    }
    MemRegion &m=  g_regions.MarkRegion((DWORD)t->ulE32Offset, sizeof(e32_rom)+(b_wm2005_rom?4:0), "e32 struct %d objs, img=%04x entrypt=%08lx base=%08lx v%d.%d tp%d %s", 
            e32->e32_objcnt, e32->e32_imageflags, e32->e32_entryrva, e32->e32_vbase, e32->e32_subsysmajor, e32->e32_subsysminor, e32->e32_subsys, filename);

    o32_rom *o32= (o32_rom *)g_mem.GetPtr((DWORD)t->ulO32Offset);
    if (o32==NULL)
        return;
    if (g_verbose) {
        *m.description += dworddumpasstring(t->ulE32Offset, t->ulE32Offset+sizeof(e32_rom)+(b_wm2005_rom?4:0));
    }

    m= g_regions.MarkRegion((DWORD)t->ulO32Offset, e32->e32_objcnt*sizeof(o32_rom), "o32 struct %s", filename);
    for (int i= 0 ; i<e32->e32_objcnt ; ++i)
    {
        m= g_regions.MarkRegion(o32[i].o32_dataptr ? o32[i].o32_dataptr : ofs, min(o32[i].o32_vsize, o32[i].o32_psize), 
                "o32 region_%d rva=%08lx vsize=%08lx real=%08lx psize=%08lx f=%08lx for %s", i, o32[i].o32_rva, o32[i].o32_vsize, o32[i].o32_realaddr, o32[i].o32_psize, o32[i].o32_flags, filename);

//        if (g_outputdirectory)
//            UncompressAndWrite(m.start, m.end, filename, i, o32[i].o32_flags&IMAGE_SCN_COMPRESSED, o32[i].o32_vsize, o32[i].o32_realaddr);
    }

    if (g_outputdirectory)
        CreateOriginalFile(rom, t, filename, e32, o32);
}
void DumpFileTOCentry(int filenr, DWORD ofs)
{
    FILESentry *t= (FILESentry *)g_mem.GetPtr(ofs);
    if (t==NULL)
    {
        printf("invalid filetoc ofs %08lx\n", ofs);
        return;
    }

    char *filename= (char *)g_mem.GetPtr((DWORD)t->lpszFileName);
    if (filename==NULL)
        return;

    g_regions.MarkRegion(ofs, sizeof(FILESentry), "filent %3d %08lx %08lx%08lx %8d %8d %08lx %s",
            filenr, t->dwFileAttributes, t->ftTime.dwHighDateTime, t->ftTime.dwLowDateTime, t->nRealFileSize, t->nCompFileSize, t->ulLoadOffset, filename);
    g_regions.MarkRegion((DWORD)t->lpszFileName, strlen(filename)+1, "filename %s", filename);
    MemRegion &m= g_regions.MarkRegion((DWORD)t->ulLoadOffset, t->nCompFileSize, "filedata %s", filename);


    if (g_outputdirectory)
        UncompressAndWrite(m.start, m.end, filename, -1, t->nCompFileSize!=t->nRealFileSize, t->nRealFileSize, t->ulLoadOffset);
}
void DumpRomHdr(int romnr, DWORD ofs)
{
    ROMHDR *r= (ROMHDR *)g_mem.GetPtr(ofs);
    if (r==NULL)
    {
        printf("invalid romhdr ofs %08lx\n", ofs);
        return;
    }

// r->ulRAMFree r->ulFSRamPercent, 
    MemRegion &m= g_regions.MarkRegion(ofs, sizeof(ROMHDR), 
            "rom_%02d header: dlls=%08lx-%08lx phys=%08lx-%08lx, %d modules, %d files, %d copyentries ext=%08lx  ram=%08lx-%08lx cputype=%08lx", 
            romnr, r->dllfirst, r->dlllast, r->physfirst, r->physlast,
            r->nummods, r->numfiles, r->ulCopyEntries, r->pExtensions,
            r->ulRAMStart, r->ulRAMEnd, r->usCPUType);

    if (g_verbose) {
        *m.description += dworddumpasstring(ofs, ofs+sizeof(ROMHDR));
    }
    g_regions.MarkRegion(r->physfirst, 0, "rom_%02d start", romnr);
    g_regions.MarkRegion(r->physlast, 0, "rom_%02d end", romnr);

    if (r->pExtensions)
        DumpExtensions((DWORD)r->pExtensions);

    DWORD i;
    TOCentry *tm= (TOCentry *)&r[1];
    for (i=0 ; i<r->nummods; i++)
    {
        DumpModuleTOCentry(r, i, g_mem.GetOfs(&tm[i]));
    }
    FILESentry *tf= (FILESentry *)&tm[r->nummods];
    for (i=0 ; i<r->numfiles; i++)
    {
        DumpFileTOCentry(i, g_mem.GetOfs(&tf[i]));
    }

    if (r->ulCopyEntries) {
        COPYentry *cp= (COPYentry *)g_mem.GetPtr(r->ulCopyOffset);
        if (cp==NULL)
            return;
        MemRegion &m= g_regions.MarkRegion(r->ulCopyOffset, sizeof(COPYentry)*r->ulCopyEntries, "rom_%02d copy to ram: ", romnr);
        for (DWORD i=0 ; i<r->ulCopyEntries ; ++i)
        {
            char buf[64];
            _snprintf(buf, 64, " %08lxL%06lx -> %08lxL%06lx", cp->ulSource, cp->ulCopyLen, cp->ulDest, cp->ulDestLen);
            *m.description += buf;
        }
    }
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
typedef map<DWORD,DWORD> MapDwordDword;

    struct ScoreCmp {
        ScoreCmp(const MapDwordDword& map) : m_map(map) {}
        bool operator()(DWORD a, DWORD b) {
            return m_map[a] > m_map[b];
        }
        MapDwordDword m_map;
    };
DWORD FindXipRegion()
{
    // find all occurrences of 'RSA1'
    // '0x48' = offset in struct + xip header
    vector<DWORD> pos;
    for (MemoryMapIterator i(g_mem.begin()) ; i!=g_mem.end() ; i+=4)
    {
        if (i.GetDword()==0x31415352)
            pos.push_back(i.m_ofs-0x48);
    }
    // look for sequence of 'RSA1'
    MapDwordDword posscore;
    DWORD start=0;
    for(vector<DWORD>::iterator i= pos.begin() ; i!=pos.end() ; ++i)
    {
        if (!start || *i != start+0x290) {
            start= *i;
            posscore[start]++;
        }
        else {
            posscore[start]++;
        }
    }
    
    sort(pos.begin(), pos.end(), ScoreCmp(posscore));
    // try in descending nr of hits
    for (MapDwordDword::iterator i= posscore.begin() ; i!=posscore.end() ; ++i)
    {
        if ((*i).first % 0x1000)
            continue;
        DWORD nxips= g_mem.GetDword((*i).first);

        if (nxips>= (*i).second)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -