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

📄 pe_map.c

📁 全面揭示PE文件的核心机密!彻底揭开PE结构的面纱!
💻 C
📖 第 1 页 / 共 3 页
字号:
                    default:
                        puts("unknown directory");
                        break;
                }
          }
}


static void map_exe(const void *base)
    /* dump headers, then walk through sections */
{
    const IMAGE_DOS_HEADER *dos_head = base;

      #include <pshpack1.h>     /* sorry, but I really do need this struct without padding */
    const struct
      {
          DWORD signature;
          IMAGE_FILE_HEADER _head;
          IMAGE_OPTIONAL_HEADER opt_head;
          IMAGE_SECTION_HEADER section_header[];  /* actual number in NumberOfSections */
      }
          *header;
      #include <poppack.h>

    if (dos_head->e_magic != IMAGE_DOS_SIGNATURE)
      {
          puts("unknown type of file");
          return;
      }                         /* verify DOS-EXE-Header */
    header = (const void *)((char *)dos_head + dos_head->e_lfanew);  /* after end of DOS-EXE-Header: offset to PE-Header */

    if (IsBadReadPtr(header, sizeof(*header)))  /* start of PE-Header */
      {
          puts("(no PE header, probably DOS executable)");
          return;
      }
    printf("DOS-stub: %ld bytes\n", (long)((char *)header - (char *)dos_head));
    {
        if (header->signature != IMAGE_NT_SIGNATURE)  /* verify PE format */
          {
              switch ((unsigned short)header->signature)
                {
                    case IMAGE_DOS_SIGNATURE:
                        puts("(MS-DOS signature)");
                        return;
                    case IMAGE_OS2_SIGNATURE:
                        puts("(Win16 or OS/2 signature)");
                        return;
                    case IMAGE_OS2_SIGNATURE_LE:
                        puts("(Win16, OS/2 or VxD signature)");
                        return;
                    default:
                        puts("(unknown signature, probably MS-DOS)");
                        return;
                }
          }
    }

    /* finally, we have the PE image header */

    fputs("built for machine: ", stdout);
    switch (header->_head.Machine)
      {
          case IMAGE_FILE_MACHINE_I386:
              puts("Intel 80386 processor");
              break;
          case 0x014d:
              puts("Intel 80486 processor");
              break;
          case 0x014e:
              puts("Intel Pentium processor");
              break;
          case 0x0160:
              puts("R3000 (MIPS) processor, big endian");
              break;
          case IMAGE_FILE_MACHINE_R3000:
              puts("R3000 (MIPS) processor, little endian");
              break;
          case IMAGE_FILE_MACHINE_R4000:
              puts("R4000 (MIPS) processor, little endian");
              break;
          case IMAGE_FILE_MACHINE_R10000:
              puts("R10000 (MIPS) processor, little endian");
              break;
          case IMAGE_FILE_MACHINE_ALPHA:
              puts("DEC Alpha_AXP processor");
              break;
          case IMAGE_FILE_MACHINE_POWERPC:
              puts("Power PC, little endian");
              break;
          default:
              printf("unknown processor: %04x\n", header->_head.Machine);
              break;
      }

    printf("  (%s32-bit-word machine)\n", header->_head.Characteristics & IMAGE_FILE_32BIT_MACHINE ? "" : "non-");
    printf("Bytes of machine word are %s\n", header->_head.Characteristics & IMAGE_FILE_BYTES_REVERSED_LO ? "reversed" : "not reversed");

    printf("Relocation info %s\n", header->_head.Characteristics & IMAGE_FILE_RELOCS_STRIPPED ? "stripped" : "not stripped");
    printf("Line nunbers %s\n", header->_head.Characteristics & IMAGE_FILE_LINE_NUMS_STRIPPED ? "stripped" : "not stripped");
    printf("Local symbols %s\n", header->_head.Characteristics & IMAGE_FILE_LOCAL_SYMS_STRIPPED ? "stripped" : "not stripped");
    printf("Debugging info %s\n", header->_head.Characteristics & IMAGE_FILE_DEBUG_STRIPPED ? "stripped" : "not stripped");

    printf("%s copy to swapfile if run from removable media\n", header->_head.Characteristics & IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP ? "must" : "need not");
    printf("%s copy to swapfile if run from network\n", header->_head.Characteristics & IMAGE_FILE_NET_RUN_FROM_SWAP ? "must" : "need not");
    printf("runs on %s\n", header->_head.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY ? "UP machine only" : "MP or UP machine");
    printf("working set trimmed %s\n", header->_head.Characteristics & IMAGE_FILE_AGGRESIVE_WS_TRIM ? "aggressively" : "normaly");

    puts(header->_head.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE ? "executable file" : "object/library file");
    puts(header->_head.Characteristics & IMAGE_FILE_SYSTEM ? "system file" : "not a system file");
    if (header->_head.Characteristics & IMAGE_FILE_DLL)
      {
          puts("File is a DLL");
          printf("  %snotify on ProcAttach\n", header->opt_head.DllCharacteristics & 0x1 ? "" : "do not ");
          printf("  %snotify on ThreadAttach\n", header->opt_head.DllCharacteristics & 0x4 ? "" : "do not ");
          printf("  %snotify on ProcDetach\n", header->opt_head.DllCharacteristics & 0x8 ? "" : "do not ");
          printf("  %snotify on ThreadDetach\n", header->opt_head.DllCharacteristics & 0x2 ? "" : "do not ");
      }
    else
        puts("not a DLL");

    printf("%ld entries in symbol table\n", header->_head.NumberOfSymbols);
    printf("%d sections\n", header->_head.NumberOfSections);
    printf("created (GMT): %s", asctime(gmtime((const time_t *)&header->_head.TimeDateStamp)));

    printf("Linker version: %d.%d\n", header->opt_head.MajorLinkerVersion, header->opt_head.MinorLinkerVersion);
    printf(".text start: %#8lx, length: %6lu bytes\n", header->opt_head.BaseOfCode, header->opt_head.SizeOfCode);
    printf(".data start: %#8lx, length: %6lu bytes\n", header->opt_head.BaseOfData, header->opt_head.SizeOfInitializedData);
    printf(".bss  start:      -/-, length: %6lu bytes\n", header->opt_head.SizeOfUninitializedData);
    printf("execution starts at    %#8lx\n", header->opt_head.AddressOfEntryPoint);
    printf("Preferred load base is %#8lx\n", header->opt_head.ImageBase);
    printf("Image size in RAM: %lu KB\n", header->opt_head.SizeOfImage / 1024);
    printf("Sections aligned to %lu bytes in RAM, %lu bytes in file\n", header->opt_head.SectionAlignment, header->opt_head.FileAlignment);
    printf("Versions: NT %d.%d, Win32 %d.%d, App %d.%d\n", header->opt_head.MajorOperatingSystemVersion, header->opt_head.MinorOperatingSystemVersion, header->opt_head.MajorSubsystemVersion, header->opt_head.MinorSubsystemVersion, header->opt_head.MajorImageVersion, header->opt_head.MinorImageVersion);
    printf("Checksum: 0x%08lx\n", header->opt_head.CheckSum);
    switch (header->opt_head.Subsystem)
      {
          case IMAGE_SUBSYSTEM_NATIVE:
              puts("uses no subsystem");
              break;
          case IMAGE_SUBSYSTEM_WINDOWS_GUI:
              puts("uses Win32 graphical subsystem");
              break;
          case IMAGE_SUBSYSTEM_WINDOWS_CUI:
              puts("uses Win32 console subsystem");
              break;
          case IMAGE_SUBSYSTEM_OS2_CUI:
              puts("uses OS/2 console subsystem");
              break;
          case IMAGE_SUBSYSTEM_POSIX_CUI:
              puts("uses Posix console subsystem");
              break;
          default:
              puts("uses unknown subsystem");
              break;
      }
    printf("Stack: %3lu KB reserved, %3lu KB committed\n", header->opt_head.SizeOfStackReserve / 1024, header->opt_head.SizeOfStackCommit / 1024);
    printf("Heap:  %3lu KB reserved, %3lu KB committed\n", header->opt_head.SizeOfHeapReserve / 1024, header->opt_head.SizeOfHeapCommit / 1024);
    printf("Size of headers / offset to sections in file: %#lx\n", header->opt_head.SizeOfHeaders);

    /* look for directories in the headers
     * yes, this happens...
     */
    look_for_directories(base, 0, header->opt_head.SizeOfHeaders, header->opt_head.DataDirectory, 0);

    /* walk through sections */
    {
        int sect;
        const IMAGE_SECTION_HEADER *section_header;
        for (sect = 0, section_header = header->section_header; sect < header->_head.NumberOfSections; sect++, section_header++)
          {                     /* first, dump header */
                          #define indent "    "
              printf("\n\"%.*s\" (virt. Size/Address: %#lx)\n", IMAGE_SIZEOF_SHORT_NAME, section_header->Name, section_header->Misc.VirtualSize);
              printf("  %6lu bytes at offset %#8lx in RAM, %#8lx in file\n", section_header->SizeOfRawData, section_header->VirtualAddress, section_header->PointerToRawData);

              if (section_header->Characteristics & IMAGE_SCN_CNT_CODE)
                  puts(indent "contains code");
              if (section_header->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
                  puts(indent "contains initialized data");
              if (section_header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
                  puts(indent "contains uninitialized data");

              if (section_header->Characteristics & IMAGE_SCN_LNK_INFO)
                  puts(indent "contains comments / information");
              if (section_header->Characteristics & IMAGE_SCN_LNK_REMOVE)
                  puts(indent "contents will not become part of image");
              if (section_header->Characteristics & IMAGE_SCN_LNK_COMDAT)
                  puts(indent "contents is COMDAT (common block data, packaged functions)");
              if (section_header->Characteristics & IMAGE_SCN_MEM_FARDATA)
                  puts(indent "? far data ?");
              if (section_header->Characteristics & IMAGE_SCN_MEM_PURGEABLE)
                  puts(indent "purgeable");
              if (section_header->Characteristics & IMAGE_SCN_MEM_16BIT)
                  puts(indent "? 16-bit-section ?");
              if (section_header->Characteristics & IMAGE_SCN_MEM_LOCKED)
                  puts(indent "locked in memory");
              if (section_header->Characteristics & IMAGE_SCN_MEM_PRELOAD)
                  puts(indent "preload");

              if (!(section_header->Characteristics & IMAGE_SCN_ALIGN_64BYTES))
                  puts(indent "default alignment (16 bytes)");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_1BYTES)
                  puts(indent "1-byte-alignment");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_2BYTES)
                  puts(indent "2-byte-alignment");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_4BYTES)
                  puts(indent "4-byte-alignment");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_8BYTES)
                  puts(indent "8-byte-alignment");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_16BYTES)
                  puts(indent "16-byte-alignment");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_32BYTES)
                  puts(indent "32-byte-alignment");
              else if (section_header->Characteristics & IMAGE_SCN_ALIGN_64BYTES)
                  puts(indent "64-byte-alignment");
              else
                  puts(indent "unknown alignment");

              if (section_header->Characteristics & IMAGE_SCN_LNK_NRELOC_OVFL)
                  puts(indent "contains extended relocations");
              if (section_header->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
                  puts(indent "can be discarded");
              if (section_header->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
                  puts(indent "is not cachable");
              if (section_header->Characteristics & IMAGE_SCN_MEM_NOT_PAGED)
                  puts(indent "is not pageable");
              if (section_header->Characteristics & IMAGE_SCN_MEM_SHARED)
                  puts(indent "is shareable");
              if (section_header->Characteristics & IMAGE_SCN_MEM_EXECUTE)
                  puts(indent "is executable");
              if (section_header->Characteristics & IMAGE_SCN_MEM_READ)
                  puts(indent "is readable");
              if (section_header->Characteristics & IMAGE_SCN_MEM_WRITE)
                  puts(indent "is writeable");

              if (isin(header->opt_head.AddressOfEntryPoint, section_header->VirtualAddress, section_header->SizeOfRawData))
                  printf(indent "at offset %#lx: execution start\n", header->opt_head.AddressOfEntryPoint - section_header->VirtualAddress);

              look_for_directories((char *)base + section_header->PointerToRawData,
                                   section_header->VirtualAddress,
                                   section_header->SizeOfRawData,
                                   header->opt_head.DataDirectory,
                                   sizeof(indent) - 1);
                          #undef indent
          }
    }
}


int main(int argc, char **argv)
{
    while (*++argv)
        if (!strcmp(*argv, "-r"))
            do_the_relocs = 1;
        else if (!strcmp(*argv, "-?"))
          {
              fputs("usage: pe_map [-r] file ...\n", stderr);
              return EXIT_FAILURE;
          }
        else
          {
              HANDLE hFile, hMapping;
              void *basepointer;
              printf("filename: %s\n", *argv);
              if ((hFile = CreateFile(*argv, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0)) == INVALID_HANDLE_VALUE)
                {
                    puts("(could not open)");
                    return EXIT_FAILURE;
                }
              if (!(hMapping = CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0)))
                {
                    puts("(mapping failed)");
                    CloseHandle(hFile);
                    return EXIT_FAILURE;
                }
              if (!(basepointer = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0)))
                {
                    puts("(view failed)");
                    CloseHandle(hMapping);
                    CloseHandle(hFile);
                    return EXIT_FAILURE;
                }
              map_exe(basepointer);
              UnmapViewOfFile(basepointer);
              CloseHandle(hMapping);
              CloseHandle(hFile);
              puts("\nVersion Info:");
              print_version_info(*argv);
          }
    return EXIT_SUCCESS;
}

⌨️ 快捷键说明

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