Changeset 73148 in vbox for trunk/src/VBox/Debugger
- Timestamp:
- Jul 16, 2018 9:57:37 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123738
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Debugger/DBGCDumpImage.cpp
r73131 r73148 39 39 #include <iprt/formats/elf32.h> 40 40 #include <iprt/formats/elf64.h> 41 #include <iprt/formats/codeview.h> 41 42 42 43 #include "DBGCInternal.h" 44 45 46 /********************************************************************************************************************************* 47 * Structures and Typedefs * 48 *********************************************************************************************************************************/ 49 /** 50 * PE dumper instance. 51 */ 52 typedef 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. */ 78 typedef DUMPIMAGEPE *PDUMPIMAGEPE; 43 79 44 80 … … 96 132 case IMAGE_FILE_MACHINE_ARM64 : return "ARM64"; 97 133 } 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 138 static 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 162 static 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 188 static 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 278 static 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 301 static int dbgcDumpImagePeSectionHdrs(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, unsigned cShdrs, PCIMAGE_SECTION_HEADER paShdrs) 103 302 { 104 303 for (unsigned i = 0; i < cShdrs; i++) 105 304 { 106 DBGCVAR SectAddr = *p ImageBase;107 DBGCCmdHlpEval(pCmdHlp, &SectAddr, "%DV + %#RX32", p ImageBase, 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", 109 308 i, &SectAddr, paShdrs[i].VirtualAddress, paShdrs[i].Misc.VirtualSize, paShdrs[i].Name); 110 309 } 111 112 RT_NOREF(pCmd);113 310 return VINF_SUCCESS; 114 311 } 115 312 116 313 117 static int dbgcDumpImagePeOptHdr32(P CDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, IMAGE_NT_HEADERS32 const *pNtHdrs)118 { 119 RT_NOREF(p Cmd, pCmdHlp, pNtHdrs);314 static int dbgcDumpImagePeOptHdr32(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, PCIMAGE_NT_HEADERS32 pNtHdrs) 315 { 316 RT_NOREF(pThis, pCmdHlp, pNtHdrs); 120 317 return VINF_SUCCESS; 121 318 } 122 319 123 static int dbgcDumpImagePeOptHdr64(P CDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, IMAGE_NT_HEADERS64 const *pNtHdrs)124 { 125 RT_NOREF(p Cmd, pCmdHlp, pNtHdrs);320 static int dbgcDumpImagePeOptHdr64(PDUMPIMAGEPE pThis, PDBGCCMDHLP pCmdHlp, PCIMAGE_NT_HEADERS64 pNtHdrs) 321 { 322 RT_NOREF(pThis, pCmdHlp, pNtHdrs); 126 323 return VINF_SUCCESS; 127 324 } 128 325 129 326 130 static int dbgcDumpImagePe(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, PCDBGCVAR pPeHdrAddr,131 IMAGE_FILE_HEADER const *pFileHdr)327 static int dbgcDumpImagePe(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PCDBGCVAR pImageBase, 328 PCDBGCVAR pPeHdrAddr, PCIMAGE_FILE_HEADER pFileHdr) 132 329 { 133 330 /* … … 169 366 if (RT_SUCCESS(rc)) 170 367 { 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 171 377 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 } 173 383 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 } 175 389 else 176 390 rc = DBGCCmdHlpFail(pCmdHlp, pCmd, "%Dv: Unsupported optional header size: %#x\n", 177 391 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); 180 398 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 181 399 rc = rc2;
Note:
See TracChangeset
for help on using the changeset viewer.