This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions
+583
View File
@@ -0,0 +1,583 @@
//--------------------
// PROGRAM: PEDUMP
// FILE: COMMON.C
// AUTHOR: Matt Pietrek - 1993
//--------------------
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "common.h"
PIMAGE_SYMBOL PCOFFSymbolTable = 0; // RVA to COFF symbol table (if present)
DWORD COFFSymbolCount = 0; // Number of symbols in COFF symbol table
typedef struct
{
WORD flag;
PSTR name;
} WORD_FLAG_DESCRIPTIONS;
typedef struct
{
DWORD flag;
PSTR name;
} DWORD_FLAG_DESCRIPTIONS;
// Bitfield values and names for the IMAGE_FILE_HEADER flags
WORD_FLAG_DESCRIPTIONS ImageFileHeaderCharacteristics[] =
{
{ IMAGE_FILE_RELOCS_STRIPPED, "RELOCS_STRIPPED" },
{ IMAGE_FILE_EXECUTABLE_IMAGE, "EXECUTABLE_IMAGE" },
{ IMAGE_FILE_LINE_NUMS_STRIPPED, "LINE_NUMS_STRIPPED" },
{ IMAGE_FILE_LOCAL_SYMS_STRIPPED, "LOCAL_SYMS_STRIPPED" },
{ IMAGE_FILE_MINIMAL_OBJECT, "MINIMAL_OBJECT" },
{ IMAGE_FILE_UPDATE_OBJECT, "UPDATE_OBJECT" },
{ IMAGE_FILE_16BIT_MACHINE, "16BIT_MACHINE" },
{ IMAGE_FILE_BYTES_REVERSED_LO, "BYTES_REVERSED_LO" },
{ IMAGE_FILE_32BIT_MACHINE, "32BIT_MACHINE" },
{ IMAGE_FILE_PATCH, "PATCH" },
{ IMAGE_FILE_SYSTEM, "SYSTEM" },
{ IMAGE_FILE_DLL, "DLL" },
{ IMAGE_FILE_BYTES_REVERSED_HI, "BYTES_REVERSED_HI" }
};
#define NUMBER_IMAGE_HEADER_FLAGS \
(sizeof(ImageFileHeaderCharacteristics) / sizeof(WORD_FLAG_DESCRIPTIONS))
//
// Dump the IMAGE_FILE_HEADER for a PE file or an OBJ
//
void DumpHeader(PIMAGE_FILE_HEADER pImageFileHeader)
{
UINT headerFieldWidth = 30;
UINT i;
char *szMachine;
printf("File Header\n");
switch( pImageFileHeader->Machine )
{
case IMAGE_FILE_MACHINE_I386: szMachine = "i386"; break;
case IMAGE_FILE_MACHINE_I860: szMachine = "i860"; break;
case IMAGE_FILE_MACHINE_R3000: szMachine = "R3000"; break;
case IMAGE_FILE_MACHINE_R4000: szMachine = "R4000"; break;
case IMAGE_FILE_MACHINE_ALPHA: szMachine = "alpha"; break;
default: szMachine = "unknown"; break;
}
printf(" %-*s%04X (%s)\n", headerFieldWidth, "Machine:",
pImageFileHeader->Machine, szMachine);
printf(" %-*s%04X\n", headerFieldWidth, "Number of Sections:",
pImageFileHeader->NumberOfSections);
printf(" %-*s%08X\n", headerFieldWidth, "TimeDateStamp:",
pImageFileHeader->TimeDateStamp);
printf(" %-*s%08X\n", headerFieldWidth, "PointerToSymbolTable:",
pImageFileHeader->PointerToSymbolTable);
printf(" %-*s%08X\n", headerFieldWidth, "NumberOfSymbols:",
pImageFileHeader->NumberOfSymbols);
printf(" %-*s%04X\n", headerFieldWidth, "SizeOfOptionalHeader:",
pImageFileHeader->SizeOfOptionalHeader);
printf(" %-*s%04X\n", headerFieldWidth, "Characteristics:",
pImageFileHeader->Characteristics);
for ( i=0; i < NUMBER_IMAGE_HEADER_FLAGS; i++ )
{
if ( pImageFileHeader->Characteristics &
ImageFileHeaderCharacteristics[i].flag )
printf( " %s\n", ImageFileHeaderCharacteristics[i].name );
}
}
// Bitfield values and names for the DllCharacteritics flags
WORD_FLAG_DESCRIPTIONS DllCharacteristics[] =
{
{ IMAGE_LIBRARY_PROCESS_INIT, "PROCESS_INIT" },
{ IMAGE_LIBRARY_PROCESS_TERM, "PROCESS_TERM" },
{ IMAGE_LIBRARY_THREAD_INIT, "THREAD_INIT" },
{ IMAGE_LIBRARY_THREAD_TERM, "THREAD_TERM" },
};
#define NUMBER_DLL_CHARACTERISTICS \
(sizeof(DllCharacteristics) / sizeof(WORD_FLAG_DESCRIPTIONS))
// Bitfield values and names for the LoaderFlags flags
DWORD_FLAG_DESCRIPTIONS LoaderFlags[] =
{
{ IMAGE_LOADER_FLAGS_BREAK_ON_LOAD, "BREAK_ON_LOAD" },
{ IMAGE_LOADER_FLAGS_DEBUG_ON_LOAD, "DEBUG_ON_LOAD" }
};
#define NUMBER_LOADER_FLAGS \
(sizeof(LoaderFlags) / sizeof(DWORD_FLAG_DESCRIPTIONS))
// Names of the data directory elements that are defined
char *ImageDirectoryNames[] = {
"EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC",
"DEBUG", "COPYRIGHT", "GLOBALPTR", "TLS", "LOAD_CONFIG" };
#define NUMBER_IMAGE_DIRECTORY_ENTRYS \
(sizeof(ImageDirectoryNames)/sizeof(char *))
//
// Dump the IMAGE_OPTIONAL_HEADER from a PE file
//
void DumpOptionalHeader(PIMAGE_OPTIONAL_HEADER optionalHeader)
{
UINT width = 30;
char *s;
UINT i;
printf("Optional Header\n");
printf(" %-*s%04X\n", width, "Magic", optionalHeader->Magic);
printf(" %-*s%u.%02u\n", width, "linker version",
optionalHeader->MajorLinkerVersion,
optionalHeader->MinorLinkerVersion);
printf(" %-*s%X\n", width, "size of code", optionalHeader->SizeOfCode);
printf(" %-*s%X\n", width, "size of initialized data",
optionalHeader->SizeOfInitializedData);
printf(" %-*s%X\n", width, "size of uninitialized data",
optionalHeader->SizeOfUninitializedData);
printf(" %-*s%X\n", width, "entrypoint RVA",
optionalHeader->AddressOfEntryPoint);
printf(" %-*s%X\n", width, "base of code", optionalHeader->BaseOfCode);
printf(" %-*s%X\n", width, "base of data", optionalHeader->BaseOfData);
printf(" %-*s%X\n", width, "image base", optionalHeader->ImageBase);
printf(" %-*s%X\n", width, "section align",
optionalHeader->SectionAlignment);
printf(" %-*s%X\n", width, "file align", optionalHeader->FileAlignment);
printf(" %-*s%u.%02u\n", width, "required OS version",
optionalHeader->MajorOperatingSystemVersion,
optionalHeader->MinorOperatingSystemVersion);
printf(" %-*s%u.%02u\n", width, "image version",
optionalHeader->MajorImageVersion,
optionalHeader->MinorImageVersion);
printf(" %-*s%u.%02u\n", width, "subsystem version",
optionalHeader->MajorSubsystemVersion,
optionalHeader->MinorSubsystemVersion);
printf(" %-*s%X\n", width, "Reserved1", optionalHeader->Reserved1);
printf(" %-*s%X\n", width, "size of image", optionalHeader->SizeOfImage);
printf(" %-*s%X\n", width, "size of headers",
optionalHeader->SizeOfHeaders);
printf(" %-*s%X\n", width, "checksum", optionalHeader->CheckSum);
switch( optionalHeader->Subsystem )
{
case IMAGE_SUBSYSTEM_NATIVE: s = "Native"; break;
case IMAGE_SUBSYSTEM_WINDOWS_GUI: s = "Windows GUI"; break;
case IMAGE_SUBSYSTEM_WINDOWS_CUI: s = "Windows character"; break;
case IMAGE_SUBSYSTEM_OS2_CUI: s = "OS/2 character"; break;
case IMAGE_SUBSYSTEM_POSIX_CUI: s = "Posix character"; break;
default: s = "unknown";
}
printf(" %-*s%04X (%s)\n", width, "Subsystem",
optionalHeader->Subsystem, s);
printf(" %-*s%04X\n", width, "DLL flags",
optionalHeader->DllCharacteristics);
for ( i=0; i < NUMBER_DLL_CHARACTERISTICS; i++ )
{
if ( optionalHeader->DllCharacteristics &
DllCharacteristics[i].flag )
printf( " %s", DllCharacteristics[i].name );
}
if ( optionalHeader->DllCharacteristics )
printf("\n");
printf(" %-*s%X\n", width, "stack reserve size",
optionalHeader->SizeOfStackReserve);
printf(" %-*s%X\n", width, "stack commit size",
optionalHeader->SizeOfStackCommit);
printf(" %-*s%X\n", width, "heap reserve size",
optionalHeader->SizeOfHeapReserve);
printf(" %-*s%X\n", width, "heap commit size",
optionalHeader->SizeOfHeapCommit);
printf(" %-*s%08X\n", width, "loader flags",
optionalHeader->LoaderFlags);
for ( i=0; i < NUMBER_LOADER_FLAGS; i++ )
{
if ( optionalHeader->LoaderFlags &
LoaderFlags[i].flag )
printf( " %s", LoaderFlags[i].name );
}
if ( optionalHeader->LoaderFlags )
printf("\n");
printf(" %-*s%X\n", width, "RVAs & sizes",
optionalHeader->NumberOfRvaAndSizes);
printf("\nData Directory\n");
for ( i=0; i < optionalHeader->NumberOfRvaAndSizes; i++)
{
printf( " %-12s rva: %08X size: %08X\n",
(i >= NUMBER_IMAGE_DIRECTORY_ENTRYS)
? "unused" : ImageDirectoryNames[i],
optionalHeader->DataDirectory[i].VirtualAddress,
optionalHeader->DataDirectory[i].Size);
}
}
// Bitfield values and names for the IMAGE_SECTION_HEADER flags
DWORD_FLAG_DESCRIPTIONS SectionCharacteristics[] =
{
{ IMAGE_SCN_CNT_CODE, "CODE" },
{ IMAGE_SCN_CNT_INITIALIZED_DATA, "INITIALIZED_DATA" },
{ IMAGE_SCN_CNT_UNINITIALIZED_DATA, "UNINITIALIZED_DATA" },
{ IMAGE_SCN_LNK_INFO, "LNK_INFO" },
{ IMAGE_SCN_LNK_OVERLAY, "LNK_OVERLAY" },
{ IMAGE_SCN_LNK_REMOVE, "LNK_REMOVE" },
{ IMAGE_SCN_LNK_COMDAT, "LNK_COMDAT" },
{ IMAGE_SCN_MEM_DISCARDABLE, "MEM_DISCARDABLE" },
{ IMAGE_SCN_MEM_NOT_CACHED, "MEM_NOT_CACHED" },
{ IMAGE_SCN_MEM_NOT_PAGED, "MEM_NOT_PAGED" },
{ IMAGE_SCN_MEM_SHARED, "MEM_SHARED" },
{ IMAGE_SCN_MEM_EXECUTE, "MEM_EXECUTE" },
{ IMAGE_SCN_MEM_READ, "MEM_READ" },
{ IMAGE_SCN_MEM_WRITE, "MEM_WRITE" },
};
#define NUMBER_SECTION_CHARACTERISTICS \
(sizeof(SectionCharacteristics) / sizeof(DWORD_FLAG_DESCRIPTIONS))
//
// Dump the section table from a PE file or an OBJ
//
void DumpSectionTable(PIMAGE_SECTION_HEADER section,
unsigned cSections,
BOOL IsEXE)
{
unsigned i, j;
printf("Section Table\n");
for ( i=1; i <= cSections; i++, section++ )
{
printf( " %02X %-8.8s %s: %08X VirtAddr: %08X\n",
i, section->Name,
IsEXE ? "VirtSize" : "PhysAddr",
section->Misc.VirtualSize, section->VirtualAddress);
printf( " raw data offs: %08X raw data size: %08X\n",
section->PointerToRawData, section->SizeOfRawData );
printf( " relocation offs: %08X relocations: %08X\n",
section->PointerToRelocations, section->NumberOfRelocations );
printf( " line # offs: %08X line #'s: %08X\n",
section->PointerToLinenumbers, section->NumberOfLinenumbers );
printf( " characteristics: %08X\n", section->Characteristics);
printf(" ");
for ( j=0; j < NUMBER_SECTION_CHARACTERISTICS; j++ )
{
if ( section->Characteristics &
SectionCharacteristics[j].flag )
printf( " %s", SectionCharacteristics[j].name );
}
printf("\n\n");
}
}
//
// Used by the DumpSymbolTable() routine. It purpose is to filter out
// the non-normal section numbers and give them meaningful names.
//
void GetSectionName(WORD section, PSTR buffer, unsigned cbBuffer)
{
char tempbuffer[10];
switch ( (SHORT)section )
{
case IMAGE_SYM_UNDEFINED: strcpy(tempbuffer, "UNDEF"); break;
case IMAGE_SYM_ABSOLUTE: strcpy(tempbuffer, "ABS "); break;
case IMAGE_SYM_DEBUG: strcpy(tempbuffer, "DEBUG"); break;
default: wsprintf(tempbuffer, "%-5X", section);
}
strncpy(buffer, tempbuffer, cbBuffer-1);
}
// The names of the first group of possible symbol table storage classes
char * SzStorageClass1[] = {
"NULL","AUTOMATIC","EXTERNAL","STATIC","REGISTER","EXTERNAL_DEF","LABEL",
"UNDEFINED_LABEL","MEMBER_OF_STRUCT","ARGUMENT","STRUCT_TAG",
"MEMBER_OF_UNION","UNION_TAG","TYPE_DEFINITION","UNDEFINED_STATIC",
"ENUM_TAG","MEMBER_OF_ENUM","REGISTER_PARAM","BIT_FIELD"
};
// The names of the second group of possible symbol table storage classes
char * SzStorageClass2[] = {
"BLOCK","FUNCTION","END_OF_STRUCT","FILE","SECTION","WEAK_EXTERNAL"
};
//
// Given a symbol storage class value, return a descriptive ASCII string
//
PSTR GetSZStorageClass(BYTE storageClass)
{
if ( storageClass <= IMAGE_SYM_CLASS_BIT_FIELD )
return SzStorageClass1[storageClass];
else if ( (storageClass >= IMAGE_SYM_CLASS_BLOCK)
&& (storageClass <= IMAGE_SYM_CLASS_WEAK_EXTERNAL) )
return SzStorageClass2[storageClass-IMAGE_SYM_CLASS_BLOCK];
else
return "???";
}
//
// Dumps the auxillary symbol for a regular symbol. It takes a pointer
// to the regular symbol, since the routine needs the information in
// that record.
//
void DumpAuxSymbols(PIMAGE_SYMBOL pSymbolTable)
{
PIMAGE_AUX_SYMBOL auxSym;
auxSym = (PIMAGE_AUX_SYMBOL)(pSymbolTable+1);
if ( pSymbolTable->StorageClass == IMAGE_SYM_CLASS_FILE )
printf(" * %s\n", auxSym);
else if ( (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_EXTERNAL) )
{
if ( (pSymbolTable->Type & 0xF0) == (IMAGE_SYM_DTYPE_FUNCTION << 4))
{
printf(" * tag: %04X size: %04X Line #'s: %08X next fn: %04X\n",
auxSym->Sym.TagIndex, auxSym->Sym.Misc.TotalSize,
auxSym->Sym.FcnAry.Function.PointerToLinenumber,
auxSym->Sym.FcnAry.Function.PointerToNextFunction);
}
}
else if ( (pSymbolTable->StorageClass == IMAGE_SYM_CLASS_STATIC) )
{
printf(
" * Section: %04X Len: %05X Relocs: %04X LineNums: %04X\n",
auxSym->Section.Number, auxSym->Section.Length,
auxSym->Section.NumberOfRelocations,
auxSym->Section.NumberOfLinenumbers);
}
}
//
// Given a COFF symbol table index, look up its name. This function assumes
// that the COFFSymbolCount and PCOFFSymbolTable variables have been already
// set up.
//
BOOL LookupSymbolName(DWORD index, PSTR buffer, UINT length)
{
PSTR stringTable;
if ( index >= COFFSymbolCount )
return FALSE;
if ( PCOFFSymbolTable == 0 )
return FALSE;
if ( PCOFFSymbolTable[index].N.Name.Short != 0 )
{
strncpy(buffer, PCOFFSymbolTable[index].N.ShortName, min(8,length));
buffer[8] = 0;
}
else
{
stringTable = (PSTR)&PCOFFSymbolTable[COFFSymbolCount];
strncpy(buffer,
stringTable + PCOFFSymbolTable[index].N.Name.Long, length);
buffer[length-1] = 0;
}
return TRUE;
}
//
// Dumps a COFF symbol table from an EXE or OBJ
//
void DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, unsigned cSymbols)
{
unsigned i;
PSTR stringTable;
char sectionName[10];
printf("Symbol Table - %X entries (* = auxillary symbol)\n", cSymbols);
printf(
"Indx Name Value Section cAux Type Storage\n"
"---- -------------------- -------- ---------- ----- ------- --------\n");
// The string table apparently starts right after the symbol table
stringTable = (PSTR)&pSymbolTable[cSymbols];
for ( i=0; i < cSymbols; i++ )
{
printf("%04X ", i);
if ( pSymbolTable->N.Name.Short != 0 )
printf("%-20.8s", pSymbolTable->N.ShortName);
else
printf("%-20s", stringTable + pSymbolTable->N.Name.Long);
printf(" %08X", pSymbolTable->Value);
GetSectionName(pSymbolTable->SectionNumber, sectionName,
sizeof(sectionName));
printf(" sect:%s aux:%X type:%02X st:%s\n",
sectionName,
pSymbolTable->NumberOfAuxSymbols,
pSymbolTable->Type,
GetSZStorageClass(pSymbolTable->StorageClass) );
if ( pSymbolTable->NumberOfAuxSymbols )
DumpAuxSymbols(pSymbolTable);
// Take into account any aux symbols
i += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable += pSymbolTable->NumberOfAuxSymbols;
pSymbolTable++;
}
}
//
// Given a section name, look it up in the section table and return a
// pointer to the start of its raw data area.
//
LPVOID GetSectionPtr(PSTR name, PIMAGE_NT_HEADERS pNTHeader, DWORD imageBase)
{
PIMAGE_SECTION_HEADER section;
unsigned i;
section = (PIMAGE_SECTION_HEADER)(pNTHeader+1);
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( strnicmp(section->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0 )
return (LPVOID)(section->PointerToRawData + imageBase);
}
return 0;
}
//
// Given a section name, look it up in the section table and return a
// pointer to its IMAGE_SECTION_HEADER
//
PIMAGE_SECTION_HEADER GetSectionHeader(PSTR name, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_SECTION_HEADER section;
unsigned i;
section = (PIMAGE_SECTION_HEADER)(pNTHeader+1);
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( strnicmp(section->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0 )
return section;
}
return 0;
}
//
// Do a hexadecimal dump of the raw data for all the sections. You
// could just dump one section by adjusting the PIMAGE_SECTION_HEADER
// and cSections parameters
//
void DumpRawSectionData(PIMAGE_SECTION_HEADER section,
PVOID base,
unsigned cSections)
{
unsigned i;
char name[IMAGE_SIZEOF_SHORT_NAME + 1];
printf("Section Hex Dumps\n");
for ( i=0; i < cSections; i++, section++ )
{
// Make a copy of the section name so that we can ensure that
// it's null-terminated
memcpy(name, section->Name, IMAGE_SIZEOF_SHORT_NAME);
name[IMAGE_SIZEOF_SHORT_NAME] = 0;
// Don't dump sections that don't exist in the file!
if ( section->PointerToRawData == 0 )
continue;
printf( "section %02X (%s) size: %08X file offs: %08X\n",
i, name, section->SizeOfRawData, section->PointerToRawData);
HexDump( MakePtr(PBYTE, base, section->PointerToRawData),
section->SizeOfRawData );
printf("\n");
}
}
//
// Dump a range of line numbers from the COFF debug information
//
void DumpLineNumbers(PIMAGE_LINENUMBER pln, DWORD count)
{
char buffer[64];
DWORD i;
printf("Line Numbers\n");
for (i=0; i < count; i++)
{
if ( pln->Linenumber == 0 ) // A symbol table index
{
buffer[0] = 0;
LookupSymbolName(pln->Type.SymbolTableIndex, buffer,
sizeof(buffer));
printf("SymIndex: %X (%s)\n", pln->Type.SymbolTableIndex,
buffer);
}
else // A regular line number
printf(" Addr: %05X Line: %04X\n",
pln->Type.VirtualAddress, pln->Linenumber);
pln++;
}
}
// Number of hex values displayed per line
#define HEX_DUMP_WIDTH 16
//
// Dump a region of memory in a hexadecimal format
//
void HexDump(PBYTE ptr, DWORD length)
{
char buffer[256];
PSTR buffPtr;
unsigned cOutput, i;
DWORD bytesToGo=length;
while ( bytesToGo )
{
cOutput = bytesToGo >= HEX_DUMP_WIDTH ? HEX_DUMP_WIDTH : bytesToGo;
buffPtr = buffer;
buffPtr += wsprintf(buffPtr, "%08X: ", length-bytesToGo );
for ( i=0; i < HEX_DUMP_WIDTH; i++ )
{
buffPtr += wsprintf(buffPtr,
i < cOutput ? "%02X " : " ",
*(ptr+i) );
// Put an extra space between the 1st and 2nd half of the bytes
// on each line.
if ( i == (HEX_DUMP_WIDTH/2)-1 )
buffPtr += wsprintf(buffPtr, " ");
}
for ( i=0; i < cOutput; i++ )
{
char c;
c = '.';
if ( isascii(*(ptr + i)) )
c = isprint(*(ptr + i)) ? *(ptr + i) : '.';
buffPtr += wsprintf(buffPtr, "%c", c);
}
puts(buffer); // Can't use printf(), since there may be a '%'
// in the string.
bytesToGo -= cOutput;
ptr += HEX_DUMP_WIDTH;
}
}
+27
View File
@@ -0,0 +1,27 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// MakePtr is a macro that allows you to easily add to values (including
// pointers) together without dealing with C's pointer arithmetic. It
// essentially treats the last two parameters as DWORDs. The first
// parameter is used to typecast the result to the appropriate pointer type.
#define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (addValue) )
void DumpHeader(PIMAGE_FILE_HEADER pImageFileHeader);
void DumpOptionalHeader(PIMAGE_OPTIONAL_HEADER pImageOptionalHeader);
void DumpSectionTable(PIMAGE_SECTION_HEADER section,
unsigned cSections,
BOOL IsEXE);
BOOL LookupSymbolName(DWORD index, PSTR buffer, UINT length);
void DumpSymbolTable(PIMAGE_SYMBOL pSymbolTable, unsigned cSymbols);
LPVOID GetSectionPtr(PSTR name, PIMAGE_NT_HEADERS pNTHeader, DWORD imageBase);
PIMAGE_SECTION_HEADER GetSectionHeader(PSTR name, PIMAGE_NT_HEADERS pNTHeader);
void DumpRawSectionData(PIMAGE_SECTION_HEADER section,
PVOID base,
unsigned cSections);
void DumpLineNumbers(PIMAGE_LINENUMBER pln, DWORD count);
void HexDump(PBYTE ptr, DWORD length);
+532
View File
@@ -0,0 +1,532 @@
//--------------------
// PROGRAM: PEDUMP
// FILE: EXEDUMP.C
// AUTHOR: Matt Pietrek - 1993
//--------------------
#include <windows.h>
#include <stdio.h>
#include "common.h"
#include "extrnvar.h"
typedef PIMAGE_COFF_SYMBOLS_HEADER PIMAGE_DEBUG_INFO;
PIMAGE_DEBUG_INFO PCOFFDebugInfo = 0;
char *SzDebugFormats[] = {
"UNKNOWN/BORLAND","COFF","CODEVIEW","FPO","MISC","EXCEPTION","FIXUP" };
//
// Dump the debug directory in a PE file.
//
void DumpDebugDirectory(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_DEBUG_DIRECTORY debugDir;
PIMAGE_SECTION_HEADER header;
unsigned cDebugFormats, i;
DWORD offsetInto_rdata;
DWORD va_debug_dir;
PSTR szDebugFormat;
// This line was so long that we had to break it up
va_debug_dir = pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].
VirtualAddress;
if ( va_debug_dir == 0 )
return;
// If we found a .debug section, and the debug directory is at the
// beginning of this section, it looks like a Borland file
header = GetSectionHeader(".debug", pNTHeader);
if ( header && (header->VirtualAddress == va_debug_dir) )
{
debugDir = (PIMAGE_DEBUG_DIRECTORY)(header->PointerToRawData+base);
cDebugFormats = pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size;
}
else // Look for microsoft debug directory in the .rdata section
{
header = GetSectionHeader(".rdata", pNTHeader);
if ( !header )
return;
// See if there's even any debug directories to speak of...
cDebugFormats = pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size
/ sizeof(IMAGE_DEBUG_DIRECTORY);
if ( cDebugFormats == 0 )
return;
offsetInto_rdata = va_debug_dir - header->VirtualAddress;
debugDir = MakePtr(PIMAGE_DEBUG_DIRECTORY, base,
header->PointerToRawData + offsetInto_rdata);
}
printf(
"Debug Formats in File\n"
" Type Size Address FilePtr Charactr TimeData Version\n"
" --------------- -------- -------- -------- -------- -------- --------\n"
);
for ( i=0; i < cDebugFormats; i++ )
{
szDebugFormat = (debugDir->Type <= 6)
? SzDebugFormats[debugDir->Type] : "???";
printf(" %-15s %08X %08X %08X %08X %08X %u.%02u\n",
szDebugFormat, debugDir->SizeOfData, debugDir->AddressOfRawData,
debugDir->PointerToRawData, debugDir->Characteristics,
debugDir->TimeDateStamp, debugDir->MajorVersion,
debugDir->MinorVersion);
// If COFF debug info, save its address away for later. We
// do the check for "PointerToSymbolTable" because some files
// have bogus values for the COFF header offset.
if ( (debugDir->Type == IMAGE_DEBUG_TYPE_COFF) &&
pNTHeader->FileHeader.PointerToSymbolTable )
{
PCOFFDebugInfo =
(PIMAGE_DEBUG_INFO)(base+ debugDir->PointerToRawData);
}
debugDir++;
}
}
// Function prototype (necessary because two functions recurse)
void DumpResourceDirectory
(
PIMAGE_RESOURCE_DIRECTORY resDir, DWORD resourceBase,
DWORD level, DWORD resourceType
);
// The predefined resource types
char *SzResourceTypes[] = {
"???_0", "CURSOR", "BITMAP", "ICON", "MENU", "DIALOG", "STRING", "FONTDIR",
"FONT", "ACCELERATORS", "RCDATA", "MESSAGETABLE", "GROUP_CURSOR",
"???_13", "GROUP_ICON", "???_15", "VERSION"
};
// Get an ASCII string representing a resource type
void GetResourceTypeName(DWORD type, PSTR buffer, UINT cBytes)
{
if ( type <= 16 )
strncpy(buffer, SzResourceTypes[type], cBytes);
else
wsprintf(buffer, "%X", type);
}
//
// If a resource entry has a string name (rather than an ID), go find
// the string and convert it from unicode to ascii.
//
void GetResourceNameFromId
(
DWORD id, DWORD resourceBase, PSTR buffer, UINT cBytes
)
{
PIMAGE_RESOURCE_DIR_STRING_U prdsu;
// If it's a regular ID, just format it.
if ( !(id & IMAGE_RESOURCE_NAME_IS_STRING) )
{
wsprintf(buffer, "%X", id);
return;
}
id &= 0x7FFFFFFF;
prdsu = (PIMAGE_RESOURCE_DIR_STRING_U)(resourceBase + id);
// prdsu->Length is the number of unicode characters
WideCharToMultiByte(CP_ACP, 0, prdsu->NameString, prdsu->Length,
buffer, cBytes, 0, 0);
buffer[ min(cBytes-1,prdsu->Length) ] = 0; // Null terminate it!!!
}
//
// Dump the information about one resource directory entry. If the
// entry is for a subdirectory, call the directory dumping routine
// instead of printing information in this routine.
//
void DumpResourceEntry
(
PIMAGE_RESOURCE_DIRECTORY_ENTRY resDirEntry,
DWORD resourceBase,
DWORD level
)
{
UINT i;
char nameBuffer[128];
if ( resDirEntry->OffsetToData & IMAGE_RESOURCE_DATA_IS_DIRECTORY )
{
DumpResourceDirectory( (PIMAGE_RESOURCE_DIRECTORY)
((resDirEntry->OffsetToData & 0x7FFFFFFF) + resourceBase),
resourceBase, level, resDirEntry->Name);
return;
}
// Spit out the spacing for the level indentation
for ( i=0; i < level; i++ )
printf(" ");
if ( resDirEntry->Name & IMAGE_RESOURCE_NAME_IS_STRING )
{
GetResourceNameFromId(resDirEntry->Name, resourceBase, nameBuffer,
sizeof(nameBuffer));
printf("Name: %s Offset: %08X\n",
nameBuffer, resDirEntry->OffsetToData);
}
else
{
printf("ID: %08X Offset: %08X\n",
resDirEntry->Name, resDirEntry->OffsetToData);
}
}
//
// Dump the information about one resource directory.
//
void DumpResourceDirectory
(
PIMAGE_RESOURCE_DIRECTORY resDir,
DWORD resourceBase,
DWORD level,
DWORD resourceType
)
{
PIMAGE_RESOURCE_DIRECTORY_ENTRY resDirEntry;
char szType[64];
UINT i;
// Spit out the spacing for the level indentation
for ( i=0; i < level; i++ )
printf(" ");
// Level 1 resources are the resource types
if ( level == 1 && !(resourceType & IMAGE_RESOURCE_NAME_IS_STRING) )
{
GetResourceTypeName( resourceType, szType, sizeof(szType) );
}
else // Just print out the regular id or name
{
GetResourceNameFromId( resourceType, resourceBase, szType,
sizeof(szType) );
}
printf(
"ResDir (%s) Named:%02X ID:%02X TimeDate:%08X Vers:%u.%02u Char:%X\n",
szType, resDir->NumberOfNamedEntries, resDir->NumberOfIdEntries,
resDir->TimeDateStamp, resDir->MajorVersion,
resDir->MinorVersion,resDir->Characteristics);
resDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir+1);
for ( i=0; i < resDir->NumberOfNamedEntries; i++, resDirEntry++ )
DumpResourceEntry(resDirEntry, resourceBase, level+1);
for ( i=0; i < resDir->NumberOfIdEntries; i++, resDirEntry++ )
DumpResourceEntry(resDirEntry, resourceBase, level+1);
}
//
// Top level routine called to dump out the entire resource hierarchy
//
void DumpResourceSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_RESOURCE_DIRECTORY resDir;
resDir = GetSectionPtr(".rsrc", pNTHeader, (DWORD)base);
if ( !resDir )
return;
printf("Resources\n");
DumpResourceDirectory(resDir, (DWORD)resDir, 0, 0);
}
//
// Dump the imports table (the .idata section) of a PE file
//
void DumpImportsSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_IMPORT_DESCRIPTOR importDesc;
PIMAGE_SECTION_HEADER header;
PIMAGE_THUNK_DATA thunk;
PIMAGE_IMPORT_BY_NAME pOrdinalName;
DWORD exportsStartRVA, exportsEndRVA;
INT delta;
header = GetSectionHeader(".idata", pNTHeader);
if ( !header )
return;
importDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, base,
header->PointerToRawData);
delta = (INT)(header->VirtualAddress - header->PointerToRawData);
printf("Imports Table:\n");
while ( 1 )
{
// See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR
if ( (importDesc->TimeDateStamp==0 ) && (importDesc->Name==0) )
break;
printf(" %s\n", (PBYTE)(importDesc->Name) - delta + base);
printf(" Hint/Name Table: %08X\n", importDesc->Characteristics);
printf(" TimeDateStamp: %08X\n", importDesc->TimeDateStamp);
printf(" ForwarderChain: %08X\n", importDesc->ForwarderChain);
printf(" First thunk RVA: %08X\n", importDesc->FirstThunk);
thunk = (PIMAGE_THUNK_DATA)importDesc->FirstThunk;
thunk = (PIMAGE_THUNK_DATA)( (PBYTE)thunk - delta + base);
// If the pointer that thunk points to is outside of the .idata
// section, it looks like this file is "pre-fixed up" with regards
// to the thunk table. In this situation, we'll need to fall back
// to the hint-name (aka, the "Characteristics") table.
exportsStartRVA = header->VirtualAddress;
exportsEndRVA= exportsStartRVA + header->SizeOfRawData;
if ( (*(PDWORD)thunk <= exportsStartRVA) ||
(*(PDWORD)thunk >= exportsEndRVA) )
{
if ( importDesc->Characteristics == 0 ) // Borland doesn't have
return; // this table!!!
thunk = (PIMAGE_THUNK_DATA)importDesc->Characteristics;
if ( ((DWORD)thunk <= exportsStartRVA) ||
((DWORD)thunk >= exportsEndRVA) )
return;
thunk = (PIMAGE_THUNK_DATA)( (PBYTE)thunk - delta + base);
}
printf(" Ordn Name\n");
while ( 1 ) // Loop forever (or until we break out)
{
if ( thunk->u1.AddressOfData == 0 )
break;
if ( thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG )
{
printf(" %4u\n", thunk->u1.Ordinal & 0xFFFF);
break;
}
else
{
pOrdinalName = thunk->u1.AddressOfData;
pOrdinalName = (PIMAGE_IMPORT_BY_NAME)
((PBYTE)pOrdinalName - delta + base);
printf(" %4u %s\n", pOrdinalName->Hint, pOrdinalName->Name);
}
thunk++; // Advance to next thunk
}
importDesc++; // advance to next IMAGE_IMPORT_DESCRIPTOR
printf("\n");
}
}
//
// Dump the exports table (the .edata section) of a PE file
//
void DumpExportsSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_EXPORT_DIRECTORY exportDir;
PIMAGE_SECTION_HEADER header;
INT delta;
PSTR filename;
DWORD i;
PDWORD functions;
PWORD ordinals;
PSTR *name;
header = GetSectionHeader(".edata", pNTHeader);
if ( !header )
return;
exportDir = MakePtr(PIMAGE_EXPORT_DIRECTORY, base,
header->PointerToRawData);
delta = (INT)(header->VirtualAddress - header->PointerToRawData);
filename = (PSTR)(exportDir->Name - delta + base);
printf("exports table:\n\n");
printf(" Name: %s\n", filename);
printf(" Characteristics: %08X\n", exportDir->Characteristics);
printf(" TimeDateStamp: %08X\n", exportDir->TimeDateStamp);
printf(" Version: %u.%02u\n", exportDir->MajorVersion,
exportDir->MinorVersion);
printf(" Ordinal base: %08X\n", exportDir->Base);
printf(" # of functions: %08X\n", exportDir->NumberOfFunctions);
printf(" # of Names: %08X\n", exportDir->NumberOfNames);
functions = (PDWORD)((DWORD)exportDir->AddressOfFunctions - delta + base);
ordinals = (PWORD)((DWORD)exportDir->AddressOfNameOrdinals - delta + base);
name = (PSTR *)((DWORD)exportDir->AddressOfNames - delta + base);
printf("\n Entry Pt Ordn Name\n");
for ( i=0; i < exportDir->NumberOfNames; i++ )
{
printf(" %08X %4u %s\n", *functions,
*ordinals + exportDir->Base,
(*name - delta + base));
name++; // Bump each pointer to the next array element
ordinals++;
functions++;
}
}
// The names of the available base relocations
char *SzRelocTypes[] = {
"ABSOLUTE","HIGH","LOW","HIGHLOW","HIGHADJ","MIPS_JMPADDR",
"I860_BRADDR","I860_SPLIT" };
//
// Dump the base relocation table of a PE file
//
void DumpBaseRelocationsSection(DWORD base, PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_BASE_RELOCATION baseReloc;
baseReloc = GetSectionPtr(".reloc", pNTHeader, base);
if ( !baseReloc )
return;
printf("base relocations:\n\n");
while ( baseReloc->SizeOfBlock != 0 )
{
unsigned i,cEntries;
PWORD pEntry;
char *szRelocType;
WORD relocType;
cEntries = (baseReloc->SizeOfBlock-sizeof(*baseReloc))/sizeof(WORD);
pEntry = MakePtr( PWORD, baseReloc, sizeof(*baseReloc) );
printf("Virtual Address: %08X size: %08X\n",
baseReloc->VirtualAddress, baseReloc->SizeOfBlock);
for ( i=0; i < cEntries; i++ )
{
// Extract the top 4 bits of the relocation entry. Turn those 4
// bits into an appropriate descriptive string (szRelocType)
relocType = (*pEntry & 0xF000) >> 12;
szRelocType = relocType < 8 ? SzRelocTypes[relocType] : "unknown";
printf(" %08X %s\n",
(*pEntry & 0x0FFF) + baseReloc->VirtualAddress,
szRelocType);
pEntry++; // Advance to next relocation entry
}
baseReloc = MakePtr( PIMAGE_BASE_RELOCATION, baseReloc,
baseReloc->SizeOfBlock);
}
}
//
// Dump the COFF debug information header
//
void DumpCOFFHeader(PIMAGE_DEBUG_INFO pDbgInfo)
{
printf("COFF Debug Info Header\n");
printf(" NumberOfSymbols: %08X\n", pDbgInfo->NumberOfSymbols);
printf(" LvaToFirstSymbol: %08X\n", pDbgInfo->LvaToFirstSymbol);
printf(" NumberOfLinenumbers: %08X\n", pDbgInfo->NumberOfLinenumbers);
printf(" LvaToFirstLinenumber: %08X\n", pDbgInfo->LvaToFirstLinenumber);
printf(" RvaToFirstByteOfCode: %08X\n", pDbgInfo->RvaToFirstByteOfCode);
printf(" RvaToLastByteOfCode: %08X\n", pDbgInfo->RvaToLastByteOfCode);
printf(" RvaToFirstByteOfData: %08X\n", pDbgInfo->RvaToFirstByteOfData);
printf(" RvaToLastByteOfData: %08X\n", pDbgInfo->RvaToLastByteOfData);
}
//
// top level routine called from PEDUMP.C to dump the components of a PE file
//
void DumpExeFile( PIMAGE_DOS_HEADER dosHeader )
{
PIMAGE_NT_HEADERS pNTHeader;
DWORD base = (DWORD)dosHeader;
pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader,
dosHeader->e_lfanew );
// First, verify that the e_lfanew field gave us a reasonable
// pointer, then verify the PE signature.
if ( IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) ||
pNTHeader->Signature != IMAGE_NT_SIGNATURE )
{
printf("Unhandled EXE type, or invalid .EXE\n");
return;
}
DumpHeader((PIMAGE_FILE_HEADER)&pNTHeader->FileHeader);
printf("\n");
DumpOptionalHeader((PIMAGE_OPTIONAL_HEADER)&pNTHeader->OptionalHeader);
printf("\n");
DumpSectionTable( (PIMAGE_SECTION_HEADER)(pNTHeader+1),
pNTHeader->FileHeader.NumberOfSections, TRUE);
printf("\n");
DumpDebugDirectory(base, pNTHeader);
printf("\n");
DumpResourceSection(base, pNTHeader);
printf("\n");
DumpImportsSection(base, pNTHeader);
printf("\n");
DumpExportsSection(base, pNTHeader);
printf("\n");
if ( fShowRelocations )
{
DumpBaseRelocationsSection(base, pNTHeader);
printf("\n");
}
//
// Initialize these vars here since we'll need them in DumpLineNumbers
//
PCOFFSymbolTable = MakePtr(PIMAGE_SYMBOL, base,
pNTHeader->FileHeader.PointerToSymbolTable);
COFFSymbolCount = pNTHeader->FileHeader.NumberOfSymbols;
if ( fShowSymbolTable && PCOFFDebugInfo )
{
DumpCOFFHeader( PCOFFDebugInfo );
printf("\n");
}
if ( fShowLineNumbers && PCOFFDebugInfo )
{
DumpLineNumbers( MakePtr(PIMAGE_LINENUMBER, PCOFFDebugInfo,
PCOFFDebugInfo->LvaToFirstLinenumber),
PCOFFDebugInfo->NumberOfLinenumbers);
printf("\n");
}
if ( fShowSymbolTable )
{
if ( pNTHeader->FileHeader.NumberOfSymbols
&& pNTHeader->FileHeader.PointerToSymbolTable)
{
DumpSymbolTable(PCOFFSymbolTable, COFFSymbolCount);
printf("\n");
}
}
if ( fShowRawSectionData )
{
DumpRawSectionData( (PIMAGE_SECTION_HEADER)(pNTHeader+1),
dosHeader,
pNTHeader->FileHeader.NumberOfSections);
}
}
+8
View File
@@ -0,0 +1,8 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
void DumpExeFile( PIMAGE_DOS_HEADER dosHeader );
+16
View File
@@ -0,0 +1,16 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// EXTRNVAR.H holds the "extern" definitions for global variables used
// through the program.
extern BOOL fShowRelocations;
extern BOOL fShowRawSectionData;
extern BOOL fShowSymbolTable;
extern BOOL fShowLineNumbers;
extern PIMAGE_SYMBOL PCOFFSymbolTable;
extern DWORD COFFSymbolCount;
+132
View File
@@ -0,0 +1,132 @@
//--------------------
// PROGRAM: PEDUMP
// FILE: OBJDUMP.C
// AUTHOR: Matt Pietrek - 1993
//--------------------
#include <windows.h>
#include <stdio.h>
#include "common.h"
#include "extrnvar.h"
typedef struct _i386RelocTypes
{
WORD type;
PSTR name;
} i386RelocTypes;
// ASCII names for the various relocations used in i386 COFF OBJs
i386RelocTypes i386Relocations[] =
{
{ IMAGE_REL_I386_ABSOLUTE, "ABSOLUTE" },
{ IMAGE_REL_I386_DIR16, "DIR16" },
{ IMAGE_REL_I386_REL16, "REL16" },
{ IMAGE_REL_I386_DIR32, "DIR32" },
{ IMAGE_REL_I386_DIR32NB, "DIR32NB" },
{ IMAGE_REL_I386_SEG12, "SEG12" },
{ IMAGE_REL_I386_SECTION, "SECTION" },
{ IMAGE_REL_I386_SECREL, "SECREL" },
{ IMAGE_REL_I386_REL32, "REL32" }
};
#define I386RELOCTYPECOUNT (sizeof(i386Relocations) / sizeof(i386RelocTypes))
//
// Given an i386 OBJ relocation type, return its ASCII name in a buffer
//
void GetObjRelocationName(WORD type, PSTR buffer, DWORD cBytes)
{
DWORD i;
for ( i=0; i < I386RELOCTYPECOUNT; i++ )
if ( type == i386Relocations[i].type )
{
strncpy(buffer, i386Relocations[i].name, cBytes);
return;
}
wsprintf( buffer, "???_%X", type);
}
//
// Dump the relocation table for one COFF section
//
void DumpObjRelocations(PIMAGE_RELOCATION pRelocs, DWORD count)
{
DWORD i;
char szTypeName[32];
for ( i=0; i < count; i++ )
{
GetObjRelocationName(pRelocs->Type, szTypeName, sizeof(szTypeName));
printf(" Address: %08X SymIndex: %08X Type: %s\n",
pRelocs->VirtualAddress, pRelocs->SymbolTableIndex,
szTypeName);
pRelocs++;
}
}
//
// top level routine called from PEDUMP.C to dump the components of a
// COFF OBJ file.
//
void DumpObjFile( PIMAGE_FILE_HEADER pImageFileHeader )
{
unsigned i;
PIMAGE_SECTION_HEADER pSections;
DumpHeader(pImageFileHeader);
printf("\n");
pSections = (PIMAGE_SECTION_HEADER)(pImageFileHeader+1);
DumpSectionTable(pSections, pImageFileHeader->NumberOfSections, FALSE);
printf("\n");
if ( fShowRelocations )
{
for ( i=0; i < pImageFileHeader->NumberOfSections; i++ )
{
if ( pSections[i].PointerToRelocations == 0 )
continue;
printf("Section %02X (%.8s) relocations\n", i, pSections[i].Name);
DumpObjRelocations( MakePtr(PIMAGE_RELOCATION, pImageFileHeader,
pSections[i].PointerToRelocations),
pSections[i].NumberOfRelocations );
printf("\n");
}
}
PCOFFSymbolTable = MakePtr(PIMAGE_SYMBOL, pImageFileHeader,
pImageFileHeader->PointerToSymbolTable);
COFFSymbolCount = pImageFileHeader->NumberOfSymbols;
if ( fShowLineNumbers )
{
// Walk through the section table...
for (i=0; i < pImageFileHeader->NumberOfSections; i++)
{
// if there's any line numbers for this section, dump'em
if ( pSections->NumberOfLinenumbers )
{
DumpLineNumbers( MakePtr(PIMAGE_LINENUMBER, pImageFileHeader,
pSections->PointerToLinenumbers),
pSections->NumberOfLinenumbers );
printf("\n");
}
pSections++;
}
}
if ( fShowSymbolTable )
{
DumpSymbolTable(PCOFFSymbolTable, COFFSymbolCount);
printf("\n");
}
if ( fShowRawSectionData )
{
DumpRawSectionData( (PIMAGE_SECTION_HEADER)(pImageFileHeader+1),
pImageFileHeader,
pImageFileHeader->NumberOfSections);
}
}
+8
View File
@@ -0,0 +1,8 @@
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
void DumpObjFile( PIMAGE_FILE_HEADER pImageFileHeader );
+139
View File
@@ -0,0 +1,139 @@
//--------------------
// PROGRAM: PEDUMP
// FILE: PEDUMP.C
// AUTHOR: Matt Pietrek - 1993
//--------------------
#include <windows.h>
#include <stdio.h>
#include "objdump.h"
#include "exedump.h"
#include "extrnvar.h"
// Global variables set here, and used in EXEDUMP.C and OBJDUMP.C
BOOL fShowRelocations = FALSE;
BOOL fShowRawSectionData = FALSE;
BOOL fShowSymbolTable = FALSE;
BOOL fShowLineNumbers = FALSE;
char HelpText[] =
"PEDUMP - Win32/COFF .EXE/.OBJ file dumper - 1993 Matt Pietrek\n\n"
"Syntax: PEDUMP [switches] filename\n\n"
" /A include everything in dump\n"
" /H include hex dump of sections\n"
" /L include line number information\n"
" /R show base relocations\n"
" /S show symbol table\n";
//
// Open up a file, memory map it, and call the appropriate dumping routine
//
void DumpFile(LPSTR filename)
{
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("Couldn't open file with CreateFile()\n");
return;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( hFileMapping == 0 )
{
CloseHandle(hFile);
printf("Couldn't open file mapping with CreateFileMapping()\n");
return;
}
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if ( lpFileBase == 0 )
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
printf("Couldn't map view of file with MapViewOfFile()\n");
return;
}
printf("Dump of file %s\n\n", filename);
dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
if ( dosHeader->e_magic == IMAGE_DOS_SIGNATURE )
{
DumpExeFile( dosHeader );
}
else if ( (dosHeader->e_magic == 0x014C) // Does it look like a i386
&& (dosHeader->e_sp == 0) ) // COFF OBJ file???
{
// The two tests above aren't what they look like. They're
// really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
// and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
DumpObjFile( (PIMAGE_FILE_HEADER)lpFileBase );
}
else
printf("unrecognized file format\n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
}
//
// process all the command line arguments and return a pointer to
// the filename argument.
//
PSTR ProcessCommandLine(int argc, char *argv[])
{
int i;
for ( i=1; i < argc; i++ )
{
strupr(argv[i]);
// Is it a switch character?
if ( (argv[i][0] == '-') || (argv[i][0] == '/') )
{
if ( argv[i][1] == 'A' )
{
fShowRelocations = TRUE;
fShowRawSectionData = TRUE;
fShowSymbolTable = TRUE;
fShowLineNumbers = TRUE;
}
else if ( argv[i][1] == 'H' )
fShowRawSectionData = TRUE;
else if ( argv[i][1] == 'L' )
fShowLineNumbers = TRUE;
else if ( argv[i][1] == 'R' )
fShowRelocations = TRUE;
else if ( argv[i][1] == 'S' )
fShowSymbolTable = TRUE;
}
else // Not a switch character. Must be the filename
{
return argv[i];
}
}
}
int main(int argc, char *argv[])
{
PSTR filename;
if ( argc == 1 )
{
printf( HelpText );
return 1;
}
filename = ProcessCommandLine(argc, argv);
if ( filename )
DumpFile( filename );
return 0;
}
+149
View File
@@ -0,0 +1,149 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// test_binaries.cpp : test for debug section
//
// Adapted from PEDUMP, AUTHOR: Matt Pietrek - 1993
//--------------------
#include <windows.h>
#include <stdio.h>
#include "common.h"
#include "strtools.h"
bool HasSection( PIMAGE_SECTION_HEADER section, int numSections, const char *pSectionName )
{
for ( int i = 0; i < numSections; i++ )
{
if ( !strnicmp( (char *)section[i].Name, pSectionName, 8 ) )
return true;
}
return false;
}
void TestExeFile( const char *pFilename, PIMAGE_DOS_HEADER dosHeader )
{
PIMAGE_NT_HEADERS pNTHeader;
pNTHeader = MakePtr( PIMAGE_NT_HEADERS, dosHeader,
dosHeader->e_lfanew );
// First, verify that the e_lfanew field gave us a reasonable
// pointer, then verify the PE signature.
if ( IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS)) ||
pNTHeader->Signature != IMAGE_NT_SIGNATURE )
{
printf("Unhandled EXE type, or invalid .EXE (%s)\n", pFilename);
return;
}
if ( HasSection( (PIMAGE_SECTION_HEADER)(pNTHeader+1), pNTHeader->FileHeader.NumberOfSections, "ValveDBG" ) )
{
printf("%s is a debug build\n", pFilename);
}
}
//
// Open up a file, memory map it, and call the appropriate dumping routine
//
void TestFile(const char *pFilename)
{
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
PIMAGE_DOS_HEADER dosHeader;
hFile = CreateFile(pFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if ( hFile == INVALID_HANDLE_VALUE )
{
printf("Couldn't open file %s with CreateFile()\n", pFilename );
return;
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if ( hFileMapping == 0 )
{
CloseHandle(hFile);
printf("Couldn't open file mapping with CreateFileMapping()\n");
return;
}
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if ( lpFileBase == 0 )
{
CloseHandle(hFileMapping);
CloseHandle(hFile);
printf("Couldn't map view of file with MapViewOfFile()\n");
return;
}
dosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
if ( dosHeader->e_magic == IMAGE_DOS_SIGNATURE )
{
TestExeFile( pFilename, dosHeader );
}
#if 0
else if ( (dosHeader->e_magic == 0x014C) // Does it look like a i386
&& (dosHeader->e_sp == 0) ) // COFF OBJ file???
{
// The two tests above aren't what they look like. They're
// really checking for IMAGE_FILE_HEADER.Machine == i386 (0x14C)
// and IMAGE_FILE_HEADER.SizeOfOptionalHeader == 0;
DumpObjFile( (PIMAGE_FILE_HEADER)lpFileBase );
}
#endif
else
printf("unrecognized file format\n");
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
}
int main(int argc, char* argv[])
{
if ( argc < 2 )
{
printf("Usage: test_binaries <FILENAME>\n" );
}
else
{
char fileName[2048], dir[2048];
if ( !Q_ExtractFilePath( argv[1], dir, sizeof( dir ) ) )
{
strcpy( dir, "" );
}
else
{
Q_FixSlashes( dir, '/' );
int len = strlen(dir);
if ( len && dir[len-1] !='/' )
{
strcat( dir, "/" );
}
}
WIN32_FIND_DATA findData;
HANDLE hFind = FindFirstFile( argv[1], &findData );
if ( hFind == INVALID_HANDLE_VALUE )
{
printf("Can't find %s\n", argv[1] );
}
else
{
do
{
sprintf( fileName, "%s%s", dir, findData.cFileName );
TestFile( fileName );
} while ( FindNextFile( hFind, &findData ) );
FindClose( hFind );
}
}
return 0;
}
+18
View File
@@ -0,0 +1,18 @@
//-----------------------------------------------------------------------------
// TEST_BINARIES.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\.."
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc"
$Project "Test_binaries"
{
$Folder "Source Files"
{
$File "test_binaries.cpp"
}
}