?? dumprom.cpp
字號(hào):
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)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -