📄 common.c
字号:
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 = IMAGE_FIRST_SECTION(pNTHeader);
unsigned i;
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 = IMAGE_FIRST_SECTION(pNTHeader);
unsigned i;
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
if ( strnicmp(section->Name, name, IMAGE_SIZEOF_SHORT_NAME) == 0 )
return section;
}
return 0;
}
//
// Given an RVA, look up the section header that encloses it and return a
// pointer to its IMAGE_SECTION_HEADER
//
PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva,
PIMAGE_NT_HEADERS pNTHeader)
{
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader);
unsigned i;
for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ )
{
// Is the RVA within this section?
if ( (rva >= section->VirtualAddress) &&
(rva < (section->VirtualAddress + section->Misc.VirtualSize)))
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=1; 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++;
}
}
PIMAGE_COFF_SYMBOLS_HEADER PCOFFDebugInfo = 0;
char *SzDebugFormats[] = {
"UNKNOWN/BORLAND","COFF","CODEVIEW","FPO","MISC","EXCEPTION","FIXUP" };
//
// Dump the debug directory array
//
void DumpDebugDirectory(PIMAGE_DEBUG_DIRECTORY debugDir, DWORD size, DWORD base)
{
DWORD cDebugFormats = size / sizeof(IMAGE_DEBUG_DIRECTORY);
PSTR szDebugFormat;
unsigned i;
if ( cDebugFormats == 0 )
return;
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 )
{
PCOFFDebugInfo =
(PIMAGE_COFF_SYMBOLS_HEADER)(base+ debugDir->PointerToRawData);
}
debugDir++;
}
}
//
// Dump the COFF debug information header
//
void DumpCOFFHeader(PIMAGE_COFF_SYMBOLS_HEADER 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);
}
// 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, buffPtr2;
unsigned cOutput, i;
DWORD bytesToGo=length;
while ( bytesToGo )
{
cOutput = bytesToGo >= HEX_DUMP_WIDTH ? HEX_DUMP_WIDTH : bytesToGo;
buffPtr = buffer;
buffPtr += sprintf(buffPtr, "%08X: ", length-bytesToGo );
buffPtr2 = buffPtr + (HEX_DUMP_WIDTH * 3) + 1;
for ( i=0; i < HEX_DUMP_WIDTH; i++ )
{
BYTE value = *(ptr+i);
if ( i >= cOutput )
{
// On last line. Pad with spaces
*buffPtr++ = ' ';
*buffPtr++ = ' ';
*buffPtr++ = ' ';
}
else
{
if ( value < 0x10 )
{
*buffPtr++ = '0';
itoa( value, buffPtr++, 16);
}
else
{
itoa( value, buffPtr, 16);
buffPtr+=2;
}
*buffPtr++ = ' ';
*buffPtr2++ = isprint(value) ? value : '.';
}
// Put an extra space between the 1st and 2nd half of the bytes
// on each line.
if ( i == (HEX_DUMP_WIDTH/2)-1 )
*buffPtr++ = ' ';
}
*buffPtr2 = 0; // Null terminate it.
puts(buffer); // Can't use printf(), since there may be a '%'
// in the string.
bytesToGo -= cOutput;
ptr += HEX_DUMP_WIDTH;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -