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

📄 dumprom.cpp

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