📄 dumprom.cpp
字号:
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#endif
#define STD_EXTRA 16
// see c:\local\WINCE420\PUBLIC\COMMON\OAK\INC\pehdr.h
// indexes into 'e32_unit'
#define EXP 0 /* Export table position */
#define IMP 1 /* Import table position */
#define RES 2 /* Resource table position */
#define EXC 3 /* Exception table position */
#define SEC 4 /* Security table position */
#define FIX 5 /* Fixup table position */
#define DEB 6 /* Debug table position */
#define IMD 7 /* Image description table position */
#define MSP 8 /* Machine specific table position */
#define TLS 9 /* Thread Local Storage */
#define CBK 10 /* Callbacks */
#define RS1 11 /* Reserved */
#define RS2 12 /* Reserved */
#define RS3 13 /* Reserved */
#define RS4 14 /* Reserved */
#define RS5 15 /* Reserved */
// value for e32_cpu
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
// this is the 'FILE HEADER VALUES' in dumpbin output
typedef struct e32_exe { /* PE 32-bit .EXE header */
unsigned char e32_magic[4]; /* Magic number E32_MAGIC */
unsigned short e32_cpu; /* The CPU type */
unsigned short e32_objcnt; /* Number of memory objects */
unsigned long e32_timestamp; /* Time EXE file was created/modified */
unsigned long e32_symtaboff; /* Offset to the symbol table */
unsigned long e32_symcount; /* Number of symbols */
unsigned short e32_opthdrsize; /* Optional header size */
unsigned short e32_imageflags; /* Image flags */
unsigned short e32_coffmagic; /* Coff magic number (usually 0x10b) */
unsigned char e32_linkmajor; /* The linker major version number */
unsigned char e32_linkminor; /* The linker minor version number */
unsigned long e32_codesize; /* Sum of sizes of all code sections */
unsigned long e32_initdsize; /* Sum of all initialized data size */
unsigned long e32_uninitdsize;/* Sum of all uninitialized data size */
unsigned long e32_entryrva; /* Relative virt. addr. of entry point */
unsigned long e32_codebase; /* Address of beginning of code section*/
unsigned long e32_database; /* Address of beginning of data section*/
unsigned long e32_vbase; /* Virtual base address of module */
unsigned long e32_objalign; /* Object Virtual Address align. factor*/
unsigned long e32_filealign; /* Image page alignment/truncate factor*/
unsigned short e32_osmajor; /* The operating system major ver. no. */
unsigned short e32_osminor; /* The operating system minor ver. no. */
unsigned short e32_usermajor; /* The user major version number */
unsigned short e32_userminor; /* The user minor version number */
unsigned short e32_subsysmajor;/* The subsystem major version number */
unsigned short e32_subsysminor;/* The subsystem minor version number */
unsigned long e32_res1; /* Reserved bytes - must be 0 */
unsigned long e32_vsize; /* Virtual size of the entire image */
unsigned long e32_hdrsize; /* Header information size */
unsigned long e32_filechksum; /* Checksum for entire file */
unsigned short e32_subsys; /* The subsystem type */
unsigned short e32_dllflags; /* DLL flags */
unsigned long e32_stackmax; /* Maximum stack size */
unsigned long e32_stackinit; /* Initial committed stack size */
unsigned long e32_heapmax; /* Maximum heap size */
unsigned long e32_heapinit; /* Initial committed heap size */
unsigned long e32_res2; /* Reserved bytes - must be 0 */
unsigned long e32_hdrextra; /* Number of extra info units in header*/
struct info e32_unit[STD_EXTRA]; /* Array of extra info units */
} e32_exe, *LPe32_exe;
// this is the 'section header' in dumpbin output
#define E32OBJNAMEBYTES 8 /* Name bytes */
typedef struct o32_obj { /* .EXE memory object table entry */
unsigned char o32_name[E32OBJNAMEBYTES];/* Object name */
unsigned long o32_vsize; /* Virtual memory size */
unsigned long o32_rva; /* Object relative virtual address */
unsigned long o32_psize; /* Physical file size of init. data */
unsigned long o32_dataptr; /* Image pages offset */
unsigned long o32_realaddr; /* pointer to actual */
unsigned long o32_access; /* assigned access */
unsigned long o32_temp3;
unsigned long o32_flags; /* Attribute flags for the object */
} o32_obj, *LPo32_obj;
typedef DWORD (*CEDECOMPRESSFN)(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip, DWORD n, DWORD blocksize);
extern "C" DWORD CEDecompressROM(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip, DWORD n, DWORD blocksize);
extern "C" DWORD CEDecompress(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip, DWORD n, DWORD blocksize);
CEDECOMPRESSFN cedecompress= CEDecompressROM;
bool g_iswince3rom= false;
#define CECOMPRESS_ALLZEROS 0
#define CECOMPRESS_FAILED 0xffffffffUL
#define CEDECOMPRESS_FAILED 0xffffffffUL
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
/*----------- functions to recreate original file -----------*/
void WriteBlanks(FILE *f, DWORD nblanks)
{
fseek(f, nblanks, SEEK_CUR);
}
void WriteAlignment(FILE *f, DWORD pagesize)
{
DWORD curofs= ftell(f);
if (curofs%pagesize)
WriteBlanks(f, pagesize-(curofs%pagesize));
}
void WriteDummyMZHeader(FILE *f)
{
IMAGE_DOS_HEADER dos;
memset(&dos, 0, sizeof(dos));
dos.e_magic= IMAGE_DOS_SIGNATURE;
dos.e_cblp = 0x90; // Bytes on last page of file
dos.e_cp = 3; // Pages in file
dos.e_cparhdr= 0x4; // Size of header in paragraphs
dos.e_maxalloc= 0xffff; // Maximum extra paragraphs needed
dos.e_sp= 0xb8; // Initial SP value
dos.e_lfarlc= 0x40; // File address of relocation table
dos.e_lfanew= 0xc0; // File address of new exe header
BYTE doscode[]= {
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f,
0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
fwrite(&dos, 1, sizeof(dos), f);
fwrite(&doscode, 1, sizeof(doscode), f);
WriteBlanks(f, 0x40);
// ftell should be 0xc0 here.
}
DWORD FindFirstSegment(const o32_rom *o32, DWORD objcnt, int segtypeflag)
{
for (DWORD i= 0 ; i<objcnt ; i++)
{
if (o32[i].o32_flags&segtypeflag)
return o32[i].o32_rva;
}
return 0;
}
DWORD CalcSegmentSizeSum(const o32_rom *o32, DWORD objcnt, int segtypeflag)
{
DWORD size= 0;
for (DWORD i= 0 ; i<objcnt ; i++)
{
// vsize is not entirely correct, I should use the uncompressed size,
// but, I don't know that here yet.
if (o32[i].o32_flags&segtypeflag)
size += o32[i].o32_vsize;
}
return size;
}
DWORD FiletimeToTime_t(const FILETIME *pft)
{
__int64 t; t= pft->dwHighDateTime; t<<=32; t |= pft->dwLowDateTime;
t /= 10000000LL;
t -= 11644473600LL;
return (DWORD)t;
}
void WriteE32Header(FILE *f, const ROMHDR *rom, const e32_rom *e32, const TOCentry *t, const o32_rom *o32)
{
e32_exe pe32;
memset(&pe32, 0, sizeof(pe32));
pe32.e32_magic[0]= 'P';
pe32.e32_magic[1]= 'E';
pe32.e32_cpu= rom->usCPUType;
pe32.e32_objcnt= e32->e32_objcnt;
pe32.e32_timestamp= FiletimeToTime_t(&t->ftTime);
pe32.e32_symtaboff=0;
pe32.e32_symcount=0;
pe32.e32_opthdrsize= 0xe0;
pe32.e32_imageflags= e32->e32_imageflags | IMAGE_FILE_RELOCS_STRIPPED;
pe32.e32_coffmagic= 0x10b;
pe32.e32_linkmajor= 6;
pe32.e32_linkminor= 1;
pe32.e32_codesize= CalcSegmentSizeSum(o32, e32->e32_objcnt, IMAGE_SCN_CNT_CODE);
pe32.e32_initdsize= CalcSegmentSizeSum(o32, e32->e32_objcnt, IMAGE_SCN_CNT_INITIALIZED_DATA);
pe32.e32_uninitdsize= CalcSegmentSizeSum(o32, e32->e32_objcnt, IMAGE_SCN_CNT_UNINITIALIZED_DATA);
pe32.e32_entryrva= e32->e32_entryrva;
pe32.e32_codebase= FindFirstSegment(o32, e32->e32_objcnt, IMAGE_SCN_CNT_CODE);
pe32.e32_database= FindFirstSegment(o32, e32->e32_objcnt, IMAGE_SCN_CNT_INITIALIZED_DATA);
pe32.e32_vbase= e32->e32_vbase;
pe32.e32_objalign= 0x1000;
pe32.e32_filealign= 0x200;
pe32.e32_osmajor= 4;
pe32.e32_osminor= 0;
pe32.e32_usermajor;
pe32.e32_userminor;
pe32.e32_subsysmajor= e32->e32_subsysmajor;
pe32.e32_subsysminor= e32->e32_subsysminor;
pe32.e32_res1;
pe32.e32_vsize= e32->e32_vsize;
pe32.e32_hdrsize; // *** set at a later moment - after alignment is known
pe32.e32_filechksum= 0;
pe32.e32_subsys= e32->e32_subsys;
pe32.e32_dllflags;
pe32.e32_stackmax= e32->e32_stackmax;
pe32.e32_stackinit=0x1000; // ?
pe32.e32_heapmax=0x100000; // ?
pe32.e32_heapinit=0x1000; // ?
pe32.e32_res2;
pe32.e32_hdrextra=STD_EXTRA; // nr of directories
pe32.e32_unit[EXP]= e32->e32_unit[EXP];
pe32.e32_unit[IMP]= e32->e32_unit[IMP];
pe32.e32_unit[RES]= e32->e32_unit[RES];
pe32.e32_unit[EXC]= e32->e32_unit[EXC];
pe32.e32_unit[SEC]= e32->e32_unit[SEC]; // always 0
// relocation info is always missing
// pe32.e32_unit[FIX]= e32->e32_unit[FIX];
// deb struct has pointer outside known filearea
//pe32.e32_unit[DEB]= e32->e32_unit[DEB];
pe32.e32_unit[IMD]= e32->e32_unit[IMD]; // always 0
pe32.e32_unit[MSP]= e32->e32_unit[MSP]; // always 0
pe32.e32_unit[RS4].rva= e32->e32_sect14rva;
pe32.e32_unit[RS4].size= e32->e32_sect14size;
fwrite(&pe32, 1, sizeof(pe32), f);
}
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define ST_TEXT 0
#define ST_DATA 1
#define ST_PDATA 2
#define ST_RSRC 3
#define ST_OTHER 4
DWORD g_segmentNameUsage[5];
char *g_segmentNames[5]= { ".text", ".data", ".pdata", ".rsrc", ".other" };
DWORD WriteO32Header(FILE *f, const e32_rom *e32, const o32_rom *o32)
{
o32_obj po32;
memset(&po32, 0, sizeof(po32));
int segtype;
if (e32->e32_unit[RES].rva==o32->o32_rva && e32->e32_unit[RES].size==o32->o32_vsize)
segtype= ST_RSRC;
else if (e32->e32_unit[EXC].rva==o32->o32_rva && e32->e32_unit[EXC].size==o32->o32_vsize)
segtype= ST_PDATA;
else if (o32->o32_flags&IMAGE_SCN_CNT_CODE)
segtype= ST_TEXT;
else if (o32->o32_flags&IMAGE_SCN_CNT_INITIALIZED_DATA)
segtype= ST_DATA;
else if (o32->o32_flags&IMAGE_SCN_CNT_UNINITIALIZED_DATA)
segtype= ST_PDATA;
else
segtype= ST_OTHER;
if (g_segmentNameUsage[segtype])
{
_snprintf((char*)po32.o32_name, 8, "%s%ld", g_segmentNames[segtype], g_segmentNameUsage[segtype]);
}
else
{
_snprintf((char*)po32.o32_name, 8, "%s", g_segmentNames[segtype]);
}
g_segmentNameUsage[segtype]++;
po32.o32_vsize= o32->o32_vsize;
po32.o32_rva= g_iswince3rom ? o32->o32_rva : o32->o32_realaddr-e32->e32_vbase;
po32.o32_psize= 0; // *** set at a later moment - after uncompressed size is known
po32.o32_dataptr= 0; // *** set at a later moment - after uncompressed size is known
po32.o32_realaddr= 0; // file pointer to relocation table
po32.o32_access= 0; // file pointer to line numbers
po32.o32_temp3= 0; // number of relocations + number of line numbers
po32.o32_flags= o32->o32_flags & ~IMAGE_SCN_COMPRESSED;
fwrite(&po32, 1, sizeof(po32), f);
return po32.o32_rva;
}
DWORD WriteUncompressedData(FILE *f, DWORD dataptr, DWORD datasize, BOOL bCompressed, DWORD maxUncompressedSize)
{
BYTE *buf= (BYTE*)g_mem.GetPtr(dataptr);
if (buf==NULL)
return 0;
DWORD buflen= datasize;
if (g_iswince3rom && datasize==maxUncompressedSize) {
// bug in wince3, compressed flag set, while data is not compressed.
}
else if (bCompressed) {
BYTE *dcbuf= new BYTE[maxUncompressedSize+4096];
buflen= cedecompress(buf, datasize, dcbuf, maxUncompressedSize, 0, 1, 4096);
if (buflen!=CEDECOMPRESS_FAILED)
{
buf= dcbuf;
}
else {
printf("error decompressing %08lxL%08lx\n", dataptr, datasize);
buflen= datasize;
bCompressed= false;
delete dcbuf;
}
}
size_t nWritten= fwrite(buf, 1, buflen, f);
if (nWritten!=buflen)
{
perror("fwrite");
printf("error writing uncompressed data\n");
}
if (bCompressed)
delete buf;
return nWritten;
}
void UncompressAndWrite(DWORD start, DWORD end, char *filename, int regnr, BOOL bCompressed, DWORD size, DWORD realofs)
{
BYTE *buf= (BYTE*)g_mem.GetPtr(start);
if (buf==NULL)
return;
DWORD buflen= end-start;
if (g_iswince3rom && end-start==size) {
// bug in wince3, compressed flag set, while data is not compressed.
}
else if (bCompressed) {
BYTE *dcbuf= new BYTE[size+4096];
buflen= cedecompress(buf, end-start, dcbuf, size, 0, 1, 4096);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -