mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1089 lines
23 KiB
1089 lines
23 KiB
/***********************************************************************
|
|
* Microsoft (R) 32-Bit Incremental Linker
|
|
*
|
|
* Copyright (C) Microsoft Corp 1992-95. All rights reserved.
|
|
*
|
|
* File: dbinsp.cpp
|
|
*
|
|
* File Comments:
|
|
*
|
|
* Inspects & dumps incremental database files.
|
|
*
|
|
***********************************************************************/
|
|
|
|
#include "link.h"
|
|
|
|
#if DBG
|
|
|
|
// macros
|
|
#define FileWarning(file, str) printf("%s : %s\n", file, str)
|
|
|
|
// statics
|
|
static PIMAGE pimage;
|
|
static void *pvIncr;
|
|
static INT FileHandle;
|
|
static DWORD FileLen;
|
|
static char *SzDbFile;
|
|
|
|
static BOOL fSymbols;
|
|
static BOOL fHashTable;
|
|
static BOOL fSectionMap;
|
|
static BOOL fLibMap;
|
|
static BOOL fHeaders;
|
|
|
|
// function prototypes
|
|
extern void IncrInitImage(PPIMAGE);
|
|
|
|
void ProcessDbInspSwitches(void);
|
|
void DbInsp(PARGUMENT_LIST);
|
|
BOOL FVerifyAndDumpHeader(const char *);
|
|
BOOL FReadInFile(void);
|
|
void DumpIncrDb(const char *);
|
|
|
|
BOOL DumpIncrImageHeaders(PIMAGE, const char *);
|
|
void DumpIncrImgFileHdr(PIMAGE_FILE_HEADER);
|
|
void DumpIncrImgOptHdr(PIMAGE_OPTIONAL_HEADER);
|
|
|
|
void DumpIncrPGRP(PGRP);
|
|
void DumpIncrPSEC(PSEC);
|
|
void DumpIncrPLIB(PLIB);
|
|
void DumpIncrPMOD(PMOD);
|
|
void DumpIncrPCON(PCON);
|
|
|
|
void DumpIncrSectionMap(PSECS, const char *);
|
|
void DumpIncrLibMap(PLIB, const char *);
|
|
|
|
void DumpIncrHashTable(PHT, void *);
|
|
void DumpIncrSymbolTable(PST);
|
|
|
|
// functions
|
|
|
|
void
|
|
DbInspUsage(void)
|
|
{
|
|
if (fNeedBanner) {
|
|
PrintBanner();
|
|
}
|
|
|
|
puts("usage: DBINSP [options] [files]\n\n"
|
|
|
|
" options:\n\n"
|
|
|
|
" /ALL\n"
|
|
" /HASH\n"
|
|
" /HEADERS\n"
|
|
" /LIBMAP\n"
|
|
" /NOLOGO\n"
|
|
" /OUT:filename\n"
|
|
" /SECMAP\n"
|
|
" /SYMBOLS");
|
|
|
|
fflush(stdout);
|
|
|
|
exit(USAGE);
|
|
}
|
|
|
|
|
|
MainFunc DbInspMain(int Argc, char *Argv[])
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps an incremental database in human readable form.
|
|
|
|
Arguments:
|
|
|
|
Argc - Standard C argument count.
|
|
|
|
Argv - Standard C argument strings.
|
|
|
|
Return Value:
|
|
|
|
0 Dump was successful.
|
|
!0 Dumper error index.
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD i;
|
|
PARGUMENT_LIST parg;
|
|
|
|
if (Argc < 2) {
|
|
DbInspUsage();
|
|
}
|
|
|
|
ParseCommandLine(Argc, Argv, NULL);
|
|
ProcessDbInspSwitches();
|
|
|
|
if (fNeedBanner) {
|
|
PrintBanner();
|
|
}
|
|
|
|
for(i = 0, parg = ObjectFilenameArguments.First;
|
|
i < ObjectFilenameArguments.Count;
|
|
i++, parg = parg->Next) {
|
|
DbInsp(parg);
|
|
}
|
|
|
|
FileCloseAll();
|
|
fclose(InfoStream);
|
|
return (0);
|
|
}
|
|
|
|
void
|
|
ProcessDbInspSwitches (
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Process incr db inspector switches.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PARGUMENT_LIST parg;
|
|
WORD i;
|
|
|
|
for (i=0,parg=SwitchArguments.First;
|
|
i<SwitchArguments.Count;
|
|
parg=parg->Next, i++) {
|
|
|
|
if (!strcmp(parg->OriginalName, "?")) {
|
|
DbInspUsage();
|
|
assert(FALSE); // doesn't return
|
|
}
|
|
|
|
if (!_strnicmp(parg->OriginalName, "out:", 4)) {
|
|
if (*(parg->OriginalName+4)) {
|
|
szInfoFilename = parg->OriginalName+4;
|
|
if (!(InfoStream = fopen(szInfoFilename, "wt"))) {
|
|
Fatal(NULL, CANTOPENFILE, szInfoFilename);
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "nologo")) {
|
|
fNeedBanner = FALSE;
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "symbols")) {
|
|
fSymbols = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "all")) {
|
|
fSymbols = TRUE;
|
|
fHashTable = TRUE;
|
|
fSectionMap = TRUE;
|
|
fLibMap = TRUE;
|
|
fHeaders = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "hash")) {
|
|
fHashTable = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "secmap")) {
|
|
fSectionMap = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "libmap")) {
|
|
fLibMap = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (!_stricmp(parg->OriginalName, "headers")) {
|
|
fHeaders = TRUE;
|
|
continue;
|
|
}
|
|
|
|
Warning(NULL, WARN_UNKNOWN_SWITCH, parg->OriginalName);
|
|
|
|
} // end for
|
|
}
|
|
|
|
void
|
|
DbInsp (
|
|
PARGUMENT_LIST parg
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Verifies and dumps contents of incremental database.
|
|
|
|
Arguments:
|
|
|
|
parg - ptr to argument.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
fprintf(InfoStream, "\nInspecting file %s\n", parg->OriginalName);
|
|
|
|
// Set the incr db filename
|
|
|
|
szIncrDbFilename = parg->OriginalName;
|
|
|
|
// Peek at the header
|
|
|
|
if (!FVerifyAndDumpHeader(parg->OriginalName)) {
|
|
return;
|
|
}
|
|
|
|
// Read in the entire file
|
|
|
|
if (!FReadInFile()) {
|
|
return;
|
|
}
|
|
|
|
// verify symbol table (ptrs are valid only after reading it in the entire image)
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD) FileLen, (DWORD) pimage->pst->blkStringTable.pb, pimage->pst->blkStringTable.cb)) {
|
|
FileWarning(parg->OriginalName, "invalid pointer to string table");
|
|
return;
|
|
}
|
|
|
|
if (Align(sizeof(DWORD), ((DWORD) pimage->pst->blkStringTable.pb + pimage->pst->blkStringTable.cb - (DWORD) pvIncr))
|
|
!= FileLen) {
|
|
FileWarning(parg->OriginalName, "garbage beyond string table");
|
|
return;
|
|
}
|
|
|
|
// Dump the rest of the stuff
|
|
|
|
DumpIncrDb(parg->OriginalName);
|
|
|
|
// Close the incr db file
|
|
|
|
FileClose(FileIncrDbHandle, TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
FVerifyAndDumpHeader (
|
|
const char *szFile
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads in just the header and verifies it & dumps interesting info.
|
|
|
|
Arguments:
|
|
|
|
szFile - name of the incr db file.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
struct _stat statfile;
|
|
IMAGE image;
|
|
|
|
// stat the file
|
|
if (_stat(szFile, &statfile) == -1) {
|
|
Fatal(NULL, CANTOPENFILE, szFile);
|
|
}
|
|
|
|
FileLen = statfile.st_size;
|
|
|
|
if (FileLen < sizeof(IMAGE)) {
|
|
FileWarning(szFile, "file too small to be incr db");
|
|
return(FALSE);
|
|
}
|
|
|
|
FileHandle = FileOpen(szFile, O_RDONLY | O_BINARY, 0);
|
|
FileRead(FileHandle, &image, sizeof(IMAGE));
|
|
FileClose(FileHandle, TRUE);
|
|
|
|
// verify the incr db signature
|
|
if (strcmp(image.Sig, INCDB_SIGNATURE)) {
|
|
FileWarning(szFile, "invalid incr db signature found");
|
|
return(FALSE);
|
|
}
|
|
|
|
// verify the version numbers
|
|
if (image.MajVersNum != INCDB_MAJVERSNUM) {
|
|
FileWarning(szFile, "invalid version number found");
|
|
return(FALSE);
|
|
}
|
|
|
|
pvIncr = image.pvBase;
|
|
|
|
if (!DumpIncrImageHeaders(&image, szFile)) {
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL FReadInFile(void)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reads in file onto private heap.
|
|
|
|
Arguments:
|
|
|
|
szFile - name of file.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD dwErr = 0;
|
|
|
|
// create a private heap to load the image
|
|
if (CreateHeap(pvIncr, FileLen, FALSE, &dwErr) != pvIncr) {
|
|
puts("failed to map ILK file");
|
|
return(FALSE);
|
|
}
|
|
|
|
pimage = (PIMAGE) pvIncr;
|
|
|
|
IncrInitImage(&pimage);
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL
|
|
DumpIncrImageHeaders (
|
|
PIMAGE pimg,
|
|
const char *szFile
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps out the various headers.
|
|
|
|
Arguments:
|
|
|
|
pimg - pointer to IMAGE struct
|
|
|
|
szFile - name of file for error reporting
|
|
|
|
Return Value:
|
|
|
|
TRUE if everything is valid.
|
|
|
|
--*/
|
|
|
|
{
|
|
BYTE Sig[32];
|
|
BOOL fValid = TRUE;
|
|
|
|
fprintf(InfoStream, "\nIMAGE HEADER VALUES\n");
|
|
strcpy((char *) Sig, pimg->Sig);
|
|
Sig[26]='\0';
|
|
fprintf(InfoStream, " Signature: %s", Sig);
|
|
fprintf(InfoStream, " MajVersNum: 0x%.4x\n", pimg->MajVersNum);
|
|
fprintf(InfoStream, " MinVersNum: 0x%.4x\n", pimg->MinVersNum);
|
|
fprintf(InfoStream, " Heap Base: 0x%.8lx\n",pvIncr);
|
|
fprintf(InfoStream, " secs.psecHead: 0x%.8lx\n", pimg->secs.psecHead);
|
|
fprintf(InfoStream, " libs.plibHead: 0x%.8lx\n", pimg->libs.plibHead);
|
|
fprintf(InfoStream, " libs.fNoDefaultLibs: %c\n", pimg->libs.fNoDefaultLibs ? '1':'0');
|
|
fprintf(InfoStream, " plibCmdLineObjs: 0x%.8lx\n",pimg->plibCmdLineObjs);
|
|
fprintf(InfoStream, " pst: 0x%.8lx\n",pimg->pst);
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->secs.psecHead, 0)) {
|
|
FileWarning(szFile, "invalid pointer to section list");
|
|
fValid = FALSE;
|
|
}
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->libs.plibHead, 0)) {
|
|
FileWarning(szFile, "invalid pointer to lib list");
|
|
fValid = FALSE;
|
|
}
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->plibCmdLineObjs, 0)) {
|
|
FileWarning(szFile, "invalid pointer to cmdline objs lib");
|
|
fValid = FALSE;
|
|
}
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)pimg->pst, 0)) {
|
|
FileWarning(szFile, "invalid pointer to symbol table");
|
|
fValid = FALSE;
|
|
}
|
|
|
|
DumpIncrImgFileHdr(&pimg->ImgFileHdr);
|
|
DumpIncrImgOptHdr(&pimg->ImgOptHdr);
|
|
|
|
return(fValid);
|
|
}
|
|
|
|
void
|
|
DumpIncrImgFileHdr (
|
|
PIMAGE_FILE_HEADER pImgFileHdr
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps out the IMAGE_FILE_HEADER.
|
|
|
|
Arguments:
|
|
|
|
pImgFileHdr - pointer to IMAGE_FILE_HEADER struct
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (!fHeaders) {
|
|
return;
|
|
}
|
|
|
|
fprintf(InfoStream, "\nIMAGE FILE HEADER VALUES\n");
|
|
fprintf(InfoStream, " Machine: 0x%.4x\n", pImgFileHdr->Machine);
|
|
fprintf(InfoStream, " NumOfSec: 0x%.4x\n", pImgFileHdr->NumberOfSections);
|
|
fprintf(InfoStream, " TimeStamp: %s", ctime((time_t *)&pImgFileHdr->TimeDateStamp));
|
|
fprintf(InfoStream, " PtrToSymTbl: 0x%.8lx\n", pImgFileHdr->PointerToSymbolTable);
|
|
fprintf(InfoStream, " NumOfSyms: 0x%.8lx\n", pImgFileHdr->NumberOfSymbols);
|
|
fprintf(InfoStream, " SizeOfOptHdr: 0x%.4x\n", pImgFileHdr->SizeOfOptionalHeader);
|
|
fprintf(InfoStream, " Character.: 0x%.4x\n", pImgFileHdr->Characteristics);
|
|
}
|
|
|
|
static const char * const SubsystemName[] = {
|
|
"Unknown",
|
|
"Native",
|
|
"Windows GUI",
|
|
"Windows CUI",
|
|
"Posix CUI",
|
|
"MMOSA",
|
|
};
|
|
|
|
static const char * const DirectoryEntryName[] = {
|
|
"Export",
|
|
"Import",
|
|
"Resource",
|
|
"Exception",
|
|
"Security",
|
|
"Base Relocation",
|
|
"Debug",
|
|
"Description",
|
|
"Special",
|
|
"Thread Storage",
|
|
NULL
|
|
};
|
|
|
|
void
|
|
DumpIncrImgOptHdr (
|
|
PIMAGE_OPTIONAL_HEADER pImgOptHdr
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps out the IMAGE_OPTIONAL_HEADER. Code taken from dump.c yikes!
|
|
|
|
Arguments:
|
|
|
|
pImgFileHdr - pointer to IMAGE_OPTIONAL_HEADER struct
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
WORD i, j;
|
|
char version[30];
|
|
|
|
if (!fHeaders) {
|
|
return;
|
|
}
|
|
|
|
fprintf(InfoStream, "\nIMAGE OPTIONAL FILE HEADER VALUES\n");
|
|
fprintf(InfoStream, "% 8hX magic #\n", pImgOptHdr->Magic);
|
|
|
|
j = (WORD) sprintf(version, "%d.%d", pImgOptHdr->MajorLinkerVersion, pImgOptHdr->MinorLinkerVersion);
|
|
if (j > 8) {
|
|
j = 8;
|
|
}
|
|
for (j = (WORD) (8-j); j; j--) {
|
|
fputc(' ', InfoStream);
|
|
}
|
|
|
|
fprintf(InfoStream, "%s linker version\n% 8lX size of code\n% 8lX size of initialized data\n% 8lX size of uninitialized data\n% 8lX address of entry point\n% 8lX base of code\n% 8lX base of data\n",
|
|
version,
|
|
pImgOptHdr->SizeOfCode,
|
|
pImgOptHdr->SizeOfInitializedData,
|
|
pImgOptHdr->SizeOfUninitializedData,
|
|
pImgOptHdr->AddressOfEntryPoint,
|
|
pImgOptHdr->BaseOfCode,
|
|
pImgOptHdr->BaseOfData);
|
|
|
|
switch (pImgOptHdr->Subsystem) {
|
|
case IMAGE_SUBSYSTEM_MMOSA : i = 5; break;
|
|
case IMAGE_SUBSYSTEM_POSIX_CUI : i = 4; break;
|
|
case IMAGE_SUBSYSTEM_WINDOWS_CUI : i = 3; break;
|
|
case IMAGE_SUBSYSTEM_WINDOWS_GUI : i = 2; break;
|
|
case IMAGE_SUBSYSTEM_NATIVE : i = 1; break;
|
|
default : i = 0;
|
|
}
|
|
|
|
fprintf(InfoStream, " ----- new -----\n% 8lX image base\n% 8lX section alignment\n% 8lX file alignment\n% 8hX subsystem (%s)\n",
|
|
pImgOptHdr->ImageBase,
|
|
pImgOptHdr->SectionAlignment,
|
|
pImgOptHdr->FileAlignment,
|
|
pImgOptHdr->Subsystem,
|
|
SubsystemName[i]);
|
|
|
|
j = (WORD) sprintf(version, "%hX.%hX", pImgOptHdr->MajorOperatingSystemVersion, pImgOptHdr->MinorOperatingSystemVersion);
|
|
if (j > 8) {
|
|
j = 8;
|
|
}
|
|
for (j = (WORD) (8-j); j; j--) {
|
|
fputc(' ', InfoStream);
|
|
}
|
|
|
|
fprintf(InfoStream, "%s operating system version\n", version);
|
|
j = (WORD) sprintf(version, "%hX.%hX", pImgOptHdr->MajorImageVersion, pImgOptHdr->MinorImageVersion);
|
|
if (j > 8) {
|
|
j = 8;
|
|
}
|
|
for (j = (WORD) (8-j); j; j--) {
|
|
fputc(' ', InfoStream);
|
|
}
|
|
|
|
fprintf(InfoStream, "%s image version\n", version);
|
|
|
|
j = (WORD) sprintf(version, "%hX.%hX", pImgOptHdr->MajorSubsystemVersion, pImgOptHdr->MinorSubsystemVersion);
|
|
if (j > 8) {
|
|
j = 8;
|
|
}
|
|
for (j = (WORD) (8-j); j; j--) {
|
|
fputc(' ', InfoStream);
|
|
}
|
|
|
|
fprintf(InfoStream, "%s subsystem version\n% 8lX size of image\n% 8lX size of headers\n% 8lX checksum\n",
|
|
version,
|
|
pImgOptHdr->SizeOfImage,
|
|
pImgOptHdr->SizeOfHeaders,
|
|
pImgOptHdr->CheckSum);
|
|
|
|
fprintf(InfoStream, "% 8lX size of stack reserve\n% 8lX size of stack commit\n% 8lX size of heap reserve\n% 8lX size of heap commit\n%",
|
|
pImgOptHdr->SizeOfStackReserve,
|
|
pImgOptHdr->SizeOfStackCommit,
|
|
pImgOptHdr->SizeOfHeapReserve,
|
|
pImgOptHdr->SizeOfHeapCommit);
|
|
|
|
for (i=0; i<IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
|
|
if (!DirectoryEntryName[i]) {
|
|
break;
|
|
}
|
|
|
|
fprintf(InfoStream, "% 8lX [% 8lx] address [size] of %s Directory\n%",
|
|
pImgOptHdr->DataDirectory[i].VirtualAddress,
|
|
pImgOptHdr->DataDirectory[i].Size,
|
|
DirectoryEntryName[i]
|
|
);
|
|
}
|
|
fputc('\n', InfoStream);
|
|
}
|
|
|
|
void
|
|
DumpIncrDb (
|
|
const char *szFile
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps the contents of the incr db file.
|
|
|
|
Arguments:
|
|
|
|
szFile - name of the file to dump.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DumpIncrSymbolTable(pimage->pst);
|
|
DumpIncrHashTable(pimage->pst->pht, &pimage->pst->blkStringTable);
|
|
DumpIncrSectionMap(&pimage->secs, szFile);
|
|
DumpIncrLibMap(pimage->libs.plibHead, szFile);
|
|
}
|
|
|
|
void
|
|
DumpIncrSectionMap(
|
|
PSECS psecs,
|
|
const char *szFile
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump the image map.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ENM_SEC enm_sec;
|
|
ENM_GRP enm_grp;
|
|
ENM_DST enm_dst;
|
|
CHAR buf[128];
|
|
|
|
if (!fSectionMap) {
|
|
return;
|
|
}
|
|
|
|
fprintf(InfoStream, "\nSECTION MAP DUMP\n");
|
|
|
|
InitEnmSec(&enm_sec, psecs);
|
|
while (FNextEnmSec(&enm_sec)) {
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_sec.psec, sizeof(SEC))) {
|
|
sprintf(buf, "invalid ptr to SEC 0x%lx found\n",enm_sec.psec);
|
|
FileWarning(szFile, buf);
|
|
goto InvalidSectionMap;
|
|
}
|
|
|
|
DumpIncrPSEC(enm_sec.psec);
|
|
|
|
InitEnmGrp(&enm_grp, enm_sec.psec);
|
|
while (FNextEnmGrp(&enm_grp)) {
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_grp.pgrp, sizeof(GRP))) {
|
|
sprintf(buf, "invalid ptr to GRP 0x%lx found\n",enm_grp.pgrp);
|
|
FileWarning(szFile, buf);
|
|
goto InvalidSectionMap;
|
|
}
|
|
|
|
DumpIncrPGRP(enm_grp.pgrp);
|
|
|
|
InitEnmDst(&enm_dst, enm_grp.pgrp);
|
|
while (FNextEnmDst(&enm_dst)) {
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_dst.pcon, sizeof(CON))) {
|
|
sprintf(buf, "invalid ptr to CON 0x%lx found\n",enm_dst.pcon);
|
|
FileWarning(szFile, buf);
|
|
goto InvalidSectionMap;
|
|
}
|
|
|
|
DumpIncrPCON(enm_dst.pcon);
|
|
}
|
|
}
|
|
}
|
|
|
|
InvalidSectionMap:
|
|
|
|
fprintf(InfoStream, "\n");
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrLibMap(
|
|
PLIB plibHead,
|
|
const char *szFile
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump the driver map.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ENM_LIB enm_lib;
|
|
ENM_MOD enm_mod;
|
|
ENM_SRC enm_src;
|
|
CHAR buf[128];
|
|
|
|
if (!fLibMap) {
|
|
return;
|
|
}
|
|
|
|
fprintf(InfoStream, "\nLIBRARY MAP OF IMAGE\n");
|
|
|
|
InitEnmLib(&enm_lib, plibHead);
|
|
while (FNextEnmLib(&enm_lib)) {
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_lib.plib, sizeof(LIB))) {
|
|
sprintf(buf, "invalid ptr to LIB 0x%lx found\n",enm_lib.plib);
|
|
FileWarning(szFile, buf);
|
|
goto InvalidLibMap;
|
|
}
|
|
|
|
DumpIncrPLIB(enm_lib.plib);
|
|
|
|
InitEnmMod(&enm_mod, enm_lib.plib);
|
|
while (FNextEnmMod(&enm_mod)) {
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_mod.pmod, sizeof(MOD))) {
|
|
sprintf(buf, "invalid ptr to MOD 0x%lx found\n",enm_mod.pmod);
|
|
FileWarning(szFile, buf);
|
|
goto InvalidLibMap;
|
|
}
|
|
|
|
DumpIncrPMOD(enm_mod.pmod);
|
|
|
|
InitEnmSrc(&enm_src, enm_mod.pmod);
|
|
while (FNextEnmSrc(&enm_src)) {
|
|
if (!FValidPtrInfo((DWORD) pvIncr, (DWORD)FileLen, (DWORD)enm_src.pcon, sizeof(CON))) {
|
|
sprintf(buf, "invalid ptr to CON 0x%lx found\n",enm_src.pcon);
|
|
FileWarning(szFile, buf);
|
|
goto InvalidLibMap;
|
|
}
|
|
|
|
DumpIncrPCON(enm_src.pcon);
|
|
}
|
|
}
|
|
}
|
|
|
|
InvalidLibMap:
|
|
fprintf(InfoStream, "\n");
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrPSEC(
|
|
PSEC psec)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump an image section.
|
|
|
|
Arguments:
|
|
|
|
psec - section to dump.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
assert(psec);
|
|
|
|
fprintf(InfoStream, "\n==========\n");
|
|
fprintf(InfoStream, "section=%.8s, isec=%.4x\n", psec->szName, psec->isec);
|
|
fprintf(InfoStream, "rva= %.8lX ", psec->rva);
|
|
fprintf(InfoStream, "foPad= %.8lx ", psec->foPad);
|
|
fprintf(InfoStream, "cbRawData= %.8lx ", psec->cbRawData);
|
|
fprintf(InfoStream, "foRawData= %.8lx\n", psec->foRawData);
|
|
fprintf(InfoStream, "foLinenum= %.8lx ", psec->foLinenum);
|
|
fprintf(InfoStream, "flags= %.8lx ", psec->flags);
|
|
fprintf(InfoStream, "cLinenum= %.4x\n", psec->cLinenum);
|
|
fflush(InfoStream);
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrPGRP(
|
|
PGRP pgrp)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump an image group.
|
|
|
|
Arguments:
|
|
|
|
pgrp - group to dump.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
fprintf(InfoStream, "\n----------\n");
|
|
fprintf(InfoStream, "\n group=%s\n", pgrp->szName);
|
|
fflush(InfoStream);
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrPLIB(
|
|
PLIB plib)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump a library.
|
|
|
|
Arguments:
|
|
|
|
plib - library to dump.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
fprintf(InfoStream, "\n==========\n");
|
|
fprintf(InfoStream, "library=%s\n", plib->szName);
|
|
fprintf(InfoStream, "foIntMemST=%.8lx ", plib->foIntMemSymTab);
|
|
fprintf(InfoStream, "csymIntMem=%.8lx ", plib->csymIntMem);
|
|
fprintf(InfoStream, "flags= %.8lx\n", plib->flags);
|
|
fprintf(InfoStream, "TimeStamp= %s", ctime((time_t *)&plib->TimeStamp));
|
|
fflush(InfoStream);
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrPMOD(
|
|
PMOD pmod)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump a module.
|
|
|
|
Arguments:
|
|
|
|
pmod - module to dump.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
fprintf(InfoStream, "\n----------\n");
|
|
fprintf(InfoStream, " module=%s, ", SzOrigFilePMOD(pmod));
|
|
|
|
if (FIsLibPMOD(pmod)) {
|
|
fprintf(InfoStream, "foMember=%.8lx\n", pmod->foMember);
|
|
} else {
|
|
fprintf(InfoStream, "szNameMod=%s\n", pmod->szNameMod);
|
|
}
|
|
|
|
fprintf(InfoStream, "foSymTable=%.8lx ", pmod->foSymbolTable);
|
|
fprintf(InfoStream, "csymbols= %.8lx ", pmod->csymbols);
|
|
fprintf(InfoStream, "cbOptHdr= %.8lx\n", pmod->cbOptHdr);
|
|
fprintf(InfoStream, "flags= %.8lx ", pmod->flags);
|
|
fprintf(InfoStream, "ccon= %.8lx ", pmod->ccon);
|
|
fprintf(InfoStream, "icon= %.8lx ", pmod->icon);
|
|
fprintf(InfoStream, "TimeStamp= (%.8lx) %s", pmod->TimeStamp, ctime((time_t *)&pmod->TimeStamp));
|
|
fprintf(InfoStream, "cbFile= %.8lx ", pmod->cbFile);
|
|
fprintf(InfoStream, "HdrTime= %.8lx\n", pmod->HdrTimeStamp);
|
|
|
|
fflush(InfoStream);
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrPCON(
|
|
PCON pcon)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump a contribution.
|
|
|
|
Arguments:
|
|
|
|
pcon - contribution to dump.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
fprintf(InfoStream, "\n contributor: flags=%.8lx, rva=%.8lx, module=%s\n",
|
|
pcon->flags, pcon->rva, SzObjNamePCON(pcon));
|
|
fprintf(InfoStream, "cbRawData= %.8lx ", pcon->cbRawData);
|
|
fprintf(InfoStream, "foRawDataD=%.8lx ", pcon->foRawDataDest);
|
|
fprintf(InfoStream, "chksum =%.8lx ", pcon->chksumComdat);
|
|
fprintf(InfoStream, "selComdat= %.4x\n", pcon->selComdat);
|
|
fprintf(InfoStream, "cbPad = %.4x\n", pcon->cbPad);
|
|
fflush(InfoStream);
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrHashTable(
|
|
PHT pht,
|
|
void *pvBlk)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump a hash table.
|
|
|
|
Arguments:
|
|
|
|
pht - hast table
|
|
|
|
pvBlk - ptr to string table
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PELEMENT pelement;
|
|
DWORD ibucket;
|
|
|
|
assert(pht);
|
|
|
|
if (!fHashTable) {
|
|
return;
|
|
}
|
|
|
|
fprintf(InfoStream, "\nHASH TABLE DUMP\n");
|
|
for (ibucket = 0; ibucket < pht->cbuckets; ibucket++) {
|
|
assert(ibucket / pht->celementInChunk < pht->cchunkInDir);
|
|
pelement = pht->rgpchunk[ibucket / pht->celementInChunk]->
|
|
rgpelement[ibucket % pht->celementInChunk];
|
|
fprintf(InfoStream, "bucket = %u\n", ibucket);
|
|
while (pelement) {
|
|
fprintf(InfoStream, " %s\n", pht->SzFromPv(pelement->pv, pvBlk));
|
|
pelement = pelement->pelementNext;
|
|
}
|
|
}
|
|
fprintf(InfoStream, "\n");
|
|
}
|
|
|
|
|
|
void
|
|
DumpIncrSymbolTable (
|
|
PST pst
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump the symbol table.
|
|
|
|
Arguments:
|
|
|
|
pst - symbol table
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PPEXTERNAL rgpexternal;
|
|
DWORD cexternal;
|
|
DWORD i;
|
|
|
|
if (!fSymbols) {
|
|
return;
|
|
}
|
|
|
|
fprintf(InfoStream, "\nSYMBOL TABLE DUMP\n");
|
|
// put them out sorted by name
|
|
rgpexternal = RgpexternalByName(pst);
|
|
cexternal = Cexternal(pst);
|
|
|
|
for (i = 0; i < cexternal; i++) {
|
|
PEXTERNAL pext;
|
|
char *szSym;
|
|
const char *szType;
|
|
|
|
pext = rgpexternal[i];
|
|
|
|
szSym = SzOutputSymbolName(SzNamePext(pext, pst), TRUE);
|
|
|
|
if (!pext->pcon || (pext->Flags & EXTERN_IGNORE)) {
|
|
fprintf(InfoStream, "%s off=%.8lx flags=%.8lx %s name=%s\n",
|
|
pext->Offset ? "THUNK" : " ",
|
|
pext->Offset,
|
|
pext->Flags,
|
|
"IGNR",
|
|
szSym);
|
|
continue;
|
|
}
|
|
|
|
if (pext->pcon && !FIsLibPCON(pext->pcon)) {
|
|
if (ISFCN(pext->ImageSymbol.Type)) {
|
|
szType = "FUNC";
|
|
} else {
|
|
szType = "DATA";
|
|
}
|
|
} else {
|
|
szType = " ";
|
|
}
|
|
|
|
fprintf(InfoStream, "%s off=%.8lx flags=%.8lx %s name=%s\n",
|
|
pext->Offset ? "THUNK" : " ",
|
|
pext->Offset,
|
|
pext->Flags,
|
|
szType,
|
|
szSym);
|
|
|
|
if (szSym != SzNamePext(pext, pst)) {
|
|
free(szSym);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // DBG
|