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

📄 pe_map.c

📁 全面揭示PE文件的核心机密!彻底揭开PE结构的面纱!
💻 C
📖 第 1 页 / 共 3 页
字号:
                              nextforwarder = (int)mapped_entry->u1.ForwarderString;
                          }
                    else
                        puts("");
                }
          }
      }
    if (IsBadReadPtr(imp, sizeof(*imp)))
        puts(indent "!! data inaccessible!!");

      #undef adr
      #undef indent
}


static void dump_bound_import_directory(const void *const section_base, const DWORD section_base_virtual, const void *const import_base)
    /* for forward-table of new-style bound import directories
     * often found in the header, not in a section!
     */
{
      #define indent "   "

    const IMAGE_BOUND_IMPORT_DESCRIPTOR *bd = import_base;

    while (bd->TimeDateStamp)
      {
          unsigned i;
          const IMAGE_BOUND_FORWARDER_REF *forw;
          printf(indent "%u forwarder-DLLs from %s of %s", bd->NumberOfModuleForwarderRefs, (char *)import_base + bd->OffsetModuleName, asctime(gmtime((const time_t *)&bd->TimeDateStamp)));
          forw = (void *)(bd + 1);
          for (i = bd->NumberOfModuleForwarderRefs; i; i--, forw++)
              printf(indent indent "%s of %s", (char *)import_base + forw->OffsetModuleName, asctime(gmtime((const time_t *)&forw->TimeDateStamp)));
          bd = (void *)forw;
      }

      #undef indent
}


/* resources are recursive stuff! * directories contain enries which
 * may point to other directories. */

static void dump_resource_directory(const int indent, const IMAGE_RESOURCE_DIRECTORY * const res_start, const IMAGE_RESOURCE_DIRECTORY * const dir, const BOOL output_types);

static void dump_resource_directory_entry(const int indent, const IMAGE_RESOURCE_DIRECTORY * const res_start, const IMAGE_RESOURCE_DIRECTORY_ENTRY * const entry, const BOOL output_types)
    /* a directory entry is either a type (menu etc.) or an ID (name or number) or
     * a language identifier
     */
{
    if (entry->NameIsString)
      {
          /* it's a UNICODE string without a 0-termination - cautious! */
          IMAGE_RESOURCE_DIR_STRING_U *uni_name = (void *)((char *)res_start + entry->NameOffset);
          printf("%*sname: \"%.*ls\"", indent, "", (int)uni_name->Length, uni_name->NameString);
      }
    else if (output_types)
        switch (entry->Id)
          {
              case 1:
                  printf("%*scursor", indent, "");
                  break;
              case 2:
                  printf("%*sbitmap", indent, "");
                  break;
              case 3:
                  printf("%*sicon", indent, "");
                  break;
              case 4:
                  printf("%*smenu", indent, "");
                  break;
              case 5:
                  printf("%*sdialog", indent, "");
                  break;
              case 6:
                  printf("%*sstring", indent, "");
                  break;
              case 7:
                  printf("%*sfontdir", indent, "");
                  break;
              case 8:
                  printf("%*sfont", indent, "");
                  break;
              case 9:
                  printf("%*saccelerators", indent, "");
                  break;
              case 10:
                  printf("%*sRCdata", indent, "");
                  break;
              case 11:
                  printf("%*smessage table", indent, "");
                  break;
              case 12:
                  printf("%*sgroup cursor", indent, "");
                  break;
              case 14:
                  printf("%*sgroup icon", indent, "");
                  break;
              case 16:
                  printf("%*sversion info", indent, "");
                  break;
              default:
                  printf("%*sunknown resource type %#4x", indent, "", entry->Id);
                  break;
          }
    else
        printf("%*sid: %#x", indent, "", entry->Id);
    fputs(", ", stdout);
    if (entry->DataIsDirectory)
        dump_resource_directory(indent + 4, res_start, (void *)((char *)res_start + entry->OffsetToDirectory), FALSE);
    else
      {
          IMAGE_RESOURCE_DATA_ENTRY *data = (void *)((char *)res_start + entry->OffsetToData);
          char lang_buffer[50]; /* buffer for language name */
          char country_buffer[50];  /* buffer for country name */
          if (PRIMARYLANGID(entry->Id) == LANG_NEUTRAL)
            {
                strcpy(lang_buffer, "neutral");
                switch (SUBLANGID(entry->Id))
                  {
                      case SUBLANG_NEUTRAL:
                          strcpy(country_buffer, "neutral");
                          break;
                      case SUBLANG_SYS_DEFAULT:
                          strcpy(country_buffer, "system default");
                          break;
                      case SUBLANG_DEFAULT:
                          strcpy(country_buffer, "user default");
                          break;
                      default:
                          strcpy(country_buffer, "unknown default");
                          break;
                  }
            }
          else
            {
                DWORD lcid = MAKELCID(entry->Id, SORT_DEFAULT);  /* build locale for language (indicated by id) */
                if (!GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, lang_buffer, sizeof lang_buffer))  /* get abbreviated language identifier */
                    strcpy(lang_buffer, "???");
                if (!GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, country_buffer, sizeof country_buffer))  /* get abbreviated language identifier */
                    strcpy(lang_buffer, "???");
            }
          printf("%s (%s), %ld bytes from %#lx, codepage 0x%04lx\n", lang_buffer, country_buffer, data->Size, data->OffsetToData, data->CodePage);
      }
}


static void dump_resource_directory(const int indent, const IMAGE_RESOURCE_DIRECTORY * const res_start, const IMAGE_RESOURCE_DIRECTORY * const dir, const BOOL output_types)
    /* a directory contains many resource types or many resources or many languages */
{
    if (IsBadReadPtr(dir, sizeof(*dir)))
      {
          puts("!! data inaccessible!!");
          return;
      }
    printf("version: %d.%d, created (GMT): %s", dir->MajorVersion, dir->MinorVersion, asctime(gmtime((const time_t *)&dir->TimeDateStamp)));
    {
        IMAGE_RESOURCE_DIRECTORY_ENTRY *single_resource = (void *)(dir + 1);
        int i;
        for (i = 0; i < dir->NumberOfNamedEntries + dir->NumberOfIdEntries; i++, single_resource++)
            dump_resource_directory_entry(indent, res_start, single_resource, output_types);
    }
}


static void dump_reloc_directory(const void *const section_base, const DWORD section_base_virtual, const IMAGE_BASE_RELOCATION * rel)
    /* relocations - boring to read, but they are there :-)
     */
{
      #define indent "    "

    if (!do_the_relocs)
      {
          puts(indent "(relocations skipped)");
          return;
      }

    while (rel->VirtualAddress)
      {
          const unsigned long reloc_num = (rel->SizeOfBlock - sizeof(*rel)) / sizeof(WORD);
          printf("\n" indent indent "%lu relocations starting at 0x%04lx\n", reloc_num, rel->VirtualAddress);
          {
              unsigned i;
              const WORD *ad = (void *)(rel + 1);
              for (i = 0; i < reloc_num; i++, ad++)
                {
                    const char *type;
                    switch (*ad >> 12)
                      {
                          case IMAGE_REL_BASED_ABSOLUTE:
                              type = "nop";
                              break;
                          case IMAGE_REL_BASED_HIGH:
                              type = "fix high";
                              break;
                          case IMAGE_REL_BASED_LOW:
                              type = "fix low";
                              break;
                          case IMAGE_REL_BASED_HIGHLOW:
                              type = "fix hilo";
                              break;
                          case IMAGE_REL_BASED_HIGHADJ:
                              type = "fix highadj";
                              break;
                          case IMAGE_REL_BASED_MIPS_JMPADDR:
                              type = "jmpaddr";
                              break;
                          case IMAGE_REL_BASED_SECTION:
                              type = "section";
                              break;
                          case IMAGE_REL_BASED_REL32:
                              type = "fix rel32";
                              break;
                          default:
                              type = "???";
                              break;
                      }
                    printf(indent indent indent "offset 0x%03x (%s)\n", *ad & 0xfffU, type);
                }
              rel = (void *)ad;
          }
      }


      #undef indent
}


static void look_for_directories(const void *const section_data,
                                 const DWORD section_start_virtual,
                                 const size_t section_length,
                                 const IMAGE_DATA_DIRECTORY * const directories,
                                 const int indentation)
    /* find directories in the given range
     * section_data: current address of section start (raw data)
     * section_start_virtual: RVA of section (raw data)
     * section_length: number of bytes in section
     * look for directory in section or in section-like part of the header (bound import!)
     * if found, dump interesting stuff
     */
{
    int directory;
    for (directory = 0; directory < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; directory++)
        if (directories[directory].VirtualAddress && isin(directories[directory].VirtualAddress, section_start_virtual, section_length))
          {
              const void *const stuff_start = (char *)section_data + (directories[directory].VirtualAddress - section_start_virtual);
              /* (virtual address of stuff - virtual address of section) = offset of stuff in section */
              const unsigned stuff_length = directories[directory].Size;
              printf("\n%*sat offset %#x (%u bytes): ", indentation, "", (char *)stuff_start - (char *)section_data, stuff_length);
              switch (directory)
                {
                    case IMAGE_DIRECTORY_ENTRY_EXPORT:
                        puts("Export Directory");
                        dump_export_directory(section_data, section_start_virtual, stuff_start, section_length);
                        break;
                    case IMAGE_DIRECTORY_ENTRY_IMPORT:
                        puts("Import Directory");
                        dump_import_directory(section_data, section_start_virtual, stuff_start);
                        break;
                    case IMAGE_DIRECTORY_ENTRY_RESOURCE:
                        printf("Resource Directory\n%*s", 2 * indentation, "");
                        dump_resource_directory(2 * indentation, stuff_start, stuff_start, TRUE);
                        break;
                    case IMAGE_DIRECTORY_ENTRY_EXCEPTION:
                        puts("Exception Directory");
                        break;
                    case IMAGE_DIRECTORY_ENTRY_SECURITY:
                        puts("Security Directory");
                        break;
                    case IMAGE_DIRECTORY_ENTRY_BASERELOC:
                        puts("Base Relocation Table");
                        dump_reloc_directory(section_data, section_start_virtual, stuff_start);
                        break;
                    case IMAGE_DIRECTORY_ENTRY_DEBUG:
                        puts("Debug Directory");
                        break;
                    case IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
                        printf("Description String \"%.*s\"\n", stuff_length, (char *)stuff_start);
                        break;
                    case IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
                        puts("Machine Value (MIPS GP)");
                        break;
                    case IMAGE_DIRECTORY_ENTRY_TLS:
                        puts("TLS Directory");
                        break;
                    case IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
                        puts("Load Configuration Directory");
                        break;
                    case IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
                        puts("Bound Import Directory");
                        dump_bound_import_directory(section_data, section_start_virtual, stuff_start);
                        break;
                    case IMAGE_DIRECTORY_ENTRY_IAT:
                        puts("Import Address Table");
                        break;

⌨️ 快捷键说明

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