VirtualBox

Changeset 73148 in vbox for trunk/src/VBox/Debugger


Ignore:
Timestamp:
Jul 16, 2018 9:57:37 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
123738
Message:

DBGCDumpImage: Updates. :-)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/DBGCDumpImage.cpp

    r73131 r73148  
    3939#include <iprt/formats/elf32.h>
    4040#include <iprt/formats/elf64.h>
     41#include <iprt/formats/codeview.h>
    4142
    4243#include "DBGCInternal.h"
     44
     45
     46/*********************************************************************************************************************************
     47*   Structures and Typedefs                                                                                                      *
     48*********************************************************************************************************************************/
     49/**
     50 * PE dumper instance.
     51 */
     52typedef struct DUMPIMAGEPE
     53{
     54    /** Pointer to the image base address variable. */
     55    PCDBGCVAR                   pImageBase;
     56    /** Pointer to the file header. */
     57    PCIMAGE_FILE_HEADER         pFileHdr;
     58    /** Pointer to the NT headers. */
     59    union
     60    {
     61        PCIMAGE_NT_HEADERS32    pNt32;
     62        PCIMAGE_NT_HEADERS64    pNt64;
     63        void                   *pv;
     64    } u;
     65    /** Pointer to the section headers. */
     66    PCIMAGE_SECTION_HEADER      paShdrs;
     67    /** Number of section headers. */
     68    unsigned                    cShdrs;
     69    /** Number of RVA and sizes (data directory entries). */
     70    unsigned                    cDataDir;
     71    /** Pointer to the data directory. */
     72    PCIMAGE_DATA_DIRECTORY      paDataDir;
     73
     74    /** The command descriptor (for failing the command). */
     75    PCDBGCCMD                   pCmd;
     76} DUMPIMAGEPE;
     77/** Pointer to a PE dumper instance. */
     78typedef DUMPIMAGEPE *PDUMPIMAGEPE;
    4379
    4480
     
    96132        case IMAGE_FILE_MACHINE_ARM64        : return "ARM64";
    97133    }
    98     return "";
    99 }
    100 
    101 static int dbgcDumpImagePeSectionHdrs(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase,
    102                                       unsigned cShdrs, IMAGE_SECTION_HEADER const *paShdrs)
     134    return "??";
     135}
     136
     137
     138static const char *dbgcPeDataDirName(unsigned iDir)
     139{
     140    switch (iDir)
     141    {
     142        case IMAGE_DIRECTORY_ENTRY_EXPORT:          return "EXPORT";
     143        case IMAGE_DIRECTORY_ENTRY_IMPORT:          return "IMPORT";
     144        case IMAGE_DIRECTORY_ENTRY_RESOURCE:        return "RESOURCE";
     145        case IMAGE_DIRECTORY_ENTRY_EXCEPTION:       return "EXCEPTION";
     146        case IMAGE_DIRECTORY_ENTRY_SECURITY:        return "SECURITY";
     147        case IMAGE_DIRECTORY_ENTRY_BASERELOC:       return "BASERELOC";
     148        case IMAGE_DIRECTORY_ENTRY_DEBUG:           return "DEBUG";
     149        case IMAGE_DIRECTORY_ENTRY_ARCHITECTURE:    return "ARCHITECTURE";
     150        case IMAGE_DIRECTORY_ENTRY_GLOBALPTR:       return "GLOBALPTR";
     151        case IMAGE_DIRECTORY_ENTRY_TLS:             return "TLS";
     152        case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:     return "LOAD_CONFIG";
     153        case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:    return "BOUND_IMPORT";
     154        case IMAGE_DIRECTORY_ENTRY_IAT:             return "IAT";
     155        case IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:    return "DELAY_IMPORT";
     156        case IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:  return "COM_DESCRIPTOR";
     157    }
     158    return "??";
     159}
     160
     161
     162static const char *dbgPeDebugTypeName(uint32_t uType)
     163{
     164    switch (uType)
     165    {
     166        case IMAGE_DEBUG_TYPE_UNKNOWN:       return "UNKNOWN";
     167        case IMAGE_DEBUG_TYPE_COFF:          return "COFF";
     168        case IMAGE_DEBUG_TYPE_CODEVIEW:      return "CODEVIEW";
     169        case IMAGE_DEBUG_TYPE_FPO:           return "FPO";
     170        case IMAGE_DEBUG_TYPE_MISC:          return "MISC";
     171        case IMAGE_DEBUG_TYPE_EXCEPTION:     return "EXCEPTION";
     172        case IMAGE_DEBUG_TYPE_FIXUP:         return "FIXUP";
     173        case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:   return "OMAP_TO_SRC";
     174        case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC: return "OMAP_FROM_SRC";
     175        case IMAGE_DEBUG_TYPE_BORLAND:       return "BORLAND";
     176        case IMAGE_DEBUG_TYPE_RESERVED10:    return "RESERVED10";
     177        case IMAGE_DEBUG_TYPE_CLSID:         return "CLSID";
     178        case IMAGE_DEBUG_TYPE_VC_FEATURE:    return "VC_FEATURE";
     179        case IMAGE_DEBUG_TYPE_POGO:          return "POGO";
     180        case IMAGE_DEBUG_TYPE_ILTCG:         return "ILTCG";
     181        case IMAGE_DEBUG_TYPE_MPX:           return "MPX";
     182        case IMAGE_DEBUG_TYPE_REPRO:         return "REPRO";
     183    }
     184    return "??";
     185}
     186
     187
     188static int dbgcDumpImagePeDebugDir(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pDataAddr, uint32_t cbData)
     189{
     190    uint32_t cEntries = cbData / sizeof(IMAGE_DEBUG_DIRECTORY);
     191    for (uint32_t i = 0; i < cEntries; i++)
     192    {
     193        /*
     194         * Read the entry into memory.
     195         */
     196        DBGCVAR DbgDirAddr;
     197        int rc = DBGCCmdHlpEval(pCmdHlp, &DbgDirAddr, "%DV + %#RX32", pDataAddr, i * sizeof(IMAGE_DEBUG_DIRECTORY));
     198        if (RT_FAILURE(rc))
     199            return DBGCCmdHlpFailRc(pCmdHlp, pThis->pCmd, rc, "DBGCCmdHlpEval failed on debug entry %u", i);
     200
     201        IMAGE_DEBUG_DIRECTORY DbgDir;
     202        rc = DBGCCmdHlpMemRead(pCmdHlp, &DbgDir, sizeof(DbgDir), &DbgDirAddr, NULL);
     203        if (RT_FAILURE(rc))
     204            return DBGCCmdHlpFailRc(pCmdHlp, pThis->pCmd, rc, "Failed to read %zu at %Dv", sizeof(DbgDir), &DbgDirAddr);
     205
     206        /*
     207         * Dump it.
     208         */
     209        DBGCVAR DebugDataAddr = *pThis->pImageBase;
     210        rc = DBGCCmdHlpEval(pCmdHlp, &DebugDataAddr, "%DV + %#RX32", pThis->pImageBase, DbgDir.AddressOfRawData);
     211        DBGCCmdHlpPrintf(pCmdHlp, "  Debug[%u]: %Dv/%08RX32 LB %06RX32 %u (%s) v%u.%u file=%RX32 ts=%08RX32 fl=%RX32\n",
     212                         i, &DebugDataAddr, DbgDir.AddressOfRawData, DbgDir.SizeOfData, DbgDir.Type,
     213                         dbgPeDebugTypeName(DbgDir.Type), DbgDir.MajorVersion, DbgDir.MinorVersion, DbgDir.PointerToRawData,
     214                         DbgDir.TimeDateStamp, DbgDir.Characteristics);
     215        union
     216        {
     217            uint8_t             abPage[0x1000];
     218            CVPDB20INFO         Pdb20;
     219            CVPDB70INFO         Pdb70;
     220            IMAGE_DEBUG_MISC    Misc;
     221        } uBuf;
     222        RT_ZERO(uBuf);
     223
     224        if (DbgDir.Type == IMAGE_DEBUG_TYPE_CODEVIEW)
     225        {
     226            if (   DbgDir.SizeOfData < sizeof(uBuf)
     227                && DbgDir.SizeOfData > 16
     228                && DbgDir.AddressOfRawData > 0
     229                && RT_SUCCESS(rc))
     230            {
     231                rc = DBGCCmdHlpMemRead(pCmdHlp, &uBuf, DbgDir.SizeOfData, &DebugDataAddr, NULL);
     232                if (RT_FAILURE(rc))
     233                    return DBGCCmdHlpFailRc(pCmdHlp, pThis->pCmd, rc, "Failed to read %zu at %Dv",
     234                                            DbgDir.SizeOfData, &DebugDataAddr);
     235
     236                if (   uBuf.Pdb20.u32Magic   == CVPDB20INFO_MAGIC
     237                    && uBuf.Pdb20.offDbgInfo == 0
     238                    && DbgDir.SizeOfData > RT_UOFFSETOF(CVPDB20INFO, szPdbFilename) )
     239                    DBGCCmdHlpPrintf(pCmdHlp, "    PDB2.0: ts=%08RX32 age=%RX32 %s\n",
     240                                     uBuf.Pdb20.uTimestamp, uBuf.Pdb20.uAge, uBuf.Pdb20.szPdbFilename);
     241                else if (   uBuf.Pdb20.u32Magic == CVPDB70INFO_MAGIC
     242                         && DbgDir.SizeOfData > RT_UOFFSETOF(CVPDB70INFO, szPdbFilename) )
     243                    DBGCCmdHlpPrintf(pCmdHlp, "    PDB7.0: %RTuuid age=%u %s\n",
     244                                     &uBuf.Pdb70.PdbUuid, uBuf.Pdb70.uAge, uBuf.Pdb70.szPdbFilename);
     245                else
     246                    DBGCCmdHlpPrintf(pCmdHlp, "    Unknown PDB/codeview magic: %.8Rhxs\n", uBuf.abPage);
     247            }
     248        }
     249        else if (DbgDir.Type == IMAGE_DEBUG_TYPE_MISC)
     250        {
     251            if (   DbgDir.SizeOfData < sizeof(uBuf)
     252                && DbgDir.SizeOfData > RT_UOFFSETOF(IMAGE_DEBUG_MISC, Data)
     253                && DbgDir.AddressOfRawData > 0
     254                && RT_SUCCESS(rc) )
     255            {
     256                rc = DBGCCmdHlpMemRead(pCmdHlp, &uBuf, DbgDir.SizeOfData, &DebugDataAddr, NULL);
     257                if (RT_FAILURE(rc))
     258                    return DBGCCmdHlpFailRc(pCmdHlp, pThis->pCmd, rc, "Failed to read %zu at %Dv",
     259                                            DbgDir.SizeOfData, &DebugDataAddr);
     260
     261                if (   uBuf.Misc.DataType == IMAGE_DEBUG_MISC_EXENAME
     262                    && uBuf.Misc.Length   == DbgDir.SizeOfData)
     263                {
     264                    if (!uBuf.Misc.Unicode)
     265                        DBGCCmdHlpPrintf(pCmdHlp, "    Misc DBG: ts=%RX32 %s\n",
     266                                         DbgDir.TimeDateStamp, (const char *)&uBuf.Misc.Data[0]);
     267                    else
     268                        DBGCCmdHlpPrintf(pCmdHlp, "    Misc DBG: ts=%RX32 %ls\n",
     269                                         DbgDir.TimeDateStamp, (PCRTUTF16)&uBuf.Misc.Data[0]);
     270                }
     271            }
     272        }
     273    }
     274    return VINF_SUCCESS;
     275}
     276
     277
     278static int dbgcDumpImagePeDataDirs(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, unsigned cDataDirs, PCIMAGE_DATA_DIRECTORY paDataDirs)
     279{
     280    int rcRet = VINF_SUCCESS;
     281    for (unsigned i = 0; i < cDataDirs; i++)
     282    {
     283        if (paDataDirs[i].Size || paDataDirs[i].VirtualAddress)
     284        {
     285            DBGCVAR DataAddr = *pThis->pImageBase;
     286            DBGCCmdHlpEval(pCmdHlp, &DataAddr, "%DV + %#RX32", pThis->pImageBase, paDataDirs[i].VirtualAddress);
     287            DBGCCmdHlpPrintf(pCmdHlp, "DataDir[%02u]: %Dv/%08RX32 LB %08RX32 %s\n",
     288                             i, &DataAddr, paDataDirs[i].VirtualAddress, paDataDirs[i].Size, dbgcPeDataDirName(i));
     289            int rc = VINF_SUCCESS;
     290            if (   i == IMAGE_DIRECTORY_ENTRY_DEBUG
     291                && paDataDirs[i].Size >= sizeof(IMAGE_DEBUG_DIRECTORY))
     292                rc = dbgcDumpImagePeDebugDir(pThis, pCmdHlp, &DataAddr, paDataDirs[i].Size);
     293            if (RT_FAILURE(rc) && RT_SUCCESS(rcRet))
     294                rcRet = rc;
     295        }
     296    }
     297    return rcRet;
     298}
     299
     300
     301static int dbgcDumpImagePeSectionHdrs(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, unsigned cShdrs, PCIMAGE_SECTION_HEADER paShdrs)
    103302{
    104303    for (unsigned i = 0; i < cShdrs; i++)
    105304    {
    106         DBGCVAR SectAddr = *pImageBase;
    107         DBGCCmdHlpEval(pCmdHlp, &SectAddr, "%DV + %#RX32", pImageBase, paShdrs[i].VirtualAddress);
    108         DBGCCmdHlpPrintf(pCmdHlp, "Section #%u: %Dv/%08RX32 LB %08RX32 %.8s\n",
     305        DBGCVAR SectAddr = *pThis->pImageBase;
     306        DBGCCmdHlpEval(pCmdHlp, &SectAddr, "%DV + %#RX32", pThis->pImageBase, paShdrs[i].VirtualAddress);
     307        DBGCCmdHlpPrintf(pCmdHlp, "Section[%02u]: %Dv/%08RX32 LB %08RX32 %.8s\n",
    109308                         i, &SectAddr, paShdrs[i].VirtualAddress, paShdrs[i].Misc.VirtualSize,  paShdrs[i].Name);
    110309    }
    111 
    112     RT_NOREF(pCmd);
    113310    return VINF_SUCCESS;
    114311}
    115312
    116313
    117 static int dbgcDumpImagePeOptHdr32(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, IMAGE_NT_HEADERS32 const *pNtHdrs)
    118 {
    119     RT_NOREF(pCmd, pCmdHlp, pNtHdrs);
     314static int dbgcDumpImagePeOptHdr32(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, PCIMAGE_NT_HEADERS32 pNtHdrs)
     315{
     316    RT_NOREF(pThis, pCmdHlp, pNtHdrs);
    120317    return VINF_SUCCESS;
    121318}
    122319
    123 static int dbgcDumpImagePeOptHdr64(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, IMAGE_NT_HEADERS64 const *pNtHdrs)
    124 {
    125     RT_NOREF(pCmd, pCmdHlp, pNtHdrs);
     320static int dbgcDumpImagePeOptHdr64(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, PCIMAGE_NT_HEADERS64 pNtHdrs)
     321{
     322    RT_NOREF(pThis, pCmdHlp, pNtHdrs);
    126323    return VINF_SUCCESS;
    127324}
    128325
    129326
    130 static int dbgcDumpImagePe(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, PCDBGCVAR pPeHdrAddr,
    131                            IMAGE_FILE_HEADER const *pFileHdr)
     327static int dbgcDumpImagePe(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase,
     328                           PCDBGCVAR pPeHdrAddr, PCIMAGE_FILE_HEADER pFileHdr)
    132329{
    133330    /*
     
    169366    if (RT_SUCCESS(rc))
    170367    {
     368        DUMPIMAGEPE This;
     369        RT_ZERO(This);
     370        This.pImageBase = pImageBase;
     371        This.pFileHdr   = pFileHdr;
     372        This.u.pv       = pvBuf;
     373        This.cShdrs     = pFileHdr->NumberOfSections;
     374        This.paShdrs    = (PCIMAGE_SECTION_HEADER)((uintptr_t)pvBuf + offSHdrs);
     375        This.pCmd       = pCmd;
     376
    171377        if (pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32))
    172             rc = dbgcDumpImagePeOptHdr32(pCmd, pCmdHlp, (IMAGE_NT_HEADERS32 const *)pvBuf);
     378        {
     379            This.paDataDir = This.u.pNt32->OptionalHeader.DataDirectory;
     380            This.cDataDir  = This.u.pNt32->OptionalHeader.NumberOfRvaAndSizes;
     381            rc = dbgcDumpImagePeOptHdr32(&This, pCmdHlp, This.u.pNt32);
     382        }
    173383        else if (pFileHdr->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER64))
    174             rc = dbgcDumpImagePeOptHdr64(pCmd, pCmdHlp, (IMAGE_NT_HEADERS64 const *)pvBuf);
     384        {
     385            This.paDataDir = This.u.pNt64->OptionalHeader.DataDirectory;
     386            This.cDataDir  = This.u.pNt64->OptionalHeader.NumberOfRvaAndSizes;
     387            rc = dbgcDumpImagePeOptHdr64(&This, pCmdHlp, This.u.pNt64);
     388        }
    175389        else
    176390            rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "%Dv: Unsupported optional header size: %#x\n",
    177391                                pImageBase, pFileHdr->SizeOfOptionalHeader);
    178         int rc2 = dbgcDumpImagePeSectionHdrs(pCmd, pCmdHlp, pImageBase, pFileHdr->NumberOfSections,
    179                                              (IMAGE_SECTION_HEADER const *)((uintptr_t)pvBuf + offSHdrs));
     392
     393        int rc2 = dbgcDumpImagePeSectionHdrs(&This, pCmdHlp, This.cShdrs, This.paShdrs);
     394        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
     395            rc = rc2;
     396
     397        rc2 = dbgcDumpImagePeDataDirs(&This, pCmdHlp, This.cDataDir, This.paDataDir);
    180398        if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
    181399            rc = rc2;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette