⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 《Windows 95 System Programming Secrets》配套代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    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 + -