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

📄 common.c

📁 《Windows 95 System Programming Secrets》配套代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==================================
// PEDUMP - Matt Pietrek 1995
// FILE: COMMON.C
//==================================

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.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" }, // Removed in NT 3.5
// { IMAGE_FILE_UPDATE_OBJECT, "UPDATE_OBJECT" },   // Removed in NT 3.5
// { IMAGE_FILE_16BIT_MACHINE, "16BIT_MACHINE" },   // Removed in NT 3.5
{ IMAGE_FILE_BYTES_REVERSED_LO, "BYTES_REVERSED_LO" },
{ IMAGE_FILE_32BIT_MACHINE, "32BIT_MACHINE" },
{ IMAGE_FILE_DEBUG_STRIPPED, "DEBUG_STRIPPED" },
// { 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 );
    }
}

#if 0
// Marked as obsolete in MSDN CD 9
// 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))
#endif

#if 0
// Marked as obsolete in MSDN CD 9
// 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))
#endif

// Names of the data directory elements that are defined
char *ImageDirectoryNames[] = {
    "EXPORT", "IMPORT", "RESOURCE", "EXCEPTION", "SECURITY", "BASERELOC",
    "DEBUG", "COPYRIGHT", "GLOBALPTR", "TLS", "LOAD_CONFIG",
    "BOUND_IMPORT", "IAT" };    // These last two entries added for NT 3.51

#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);

#if 0
// Marked as obsolete in MSDN CD 9
    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");
#endif

    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);

#if 0
// Marked as obsolete in MSDN CD 9
    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");
#endif

    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: sprintf(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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -