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

📄 pe_map.c

📁 全面揭示PE文件的核心机密!彻底揭开PE结构的面纱!
💻 C
📖 第 1 页 / 共 3 页
字号:

/* 
 * pe_map.c, dumps a PE file
 * made with Watcom C32 version 11.0b on NT 4.0
 * (f) by B. Luevelsmeyer 1997, 1998, 1999
 */

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <io.h>
#include <fcntl.h>


/* 
 *      $Header: D:/c_kram/nt_info/RCS/pe_map.c,v 1.26 1999/03/20 23:59:47 LUEVELSMEYER Exp $
 *
 *      checked in by $Author: LUEVELSMEYER $
 *      checked in at $Date: 1999/03/20 23:59:47 $
 *
 *      History:
 *      $Log: pe_map.c,v $
 *      Revision 1.26  1999/03/20 23:59:47  LUEVELSMEYER
 *      fixed messed-up comment
 *
 *      Revision 1.25  1999/03/18 20:29:56  LUEVELSMEYER
 *      changed ordinal<->hint
 *
 *      Revision 1.24  1999/03/14 04:47:19  LUEVELSMEYER
 *      cosmetical stuff (indentation, comments)
 *
 *      Revision 1.23  1999/03/14 02:48:41  LUEVELSMEYER
 *      corrected major fuckup in export directory dump
 *
 *      Revision 1.22  1998/07/20 12:02:54  LUEVELSMEYER
 *      merged with DEC alpha port
 *
 *      Revision 1.21  1998/07/03 18:03:02  LUEVELSMEYER
 *      added share to file opening
 *
 *      Revision 1.20  1998/04/26 00:03:07  LUEVELSMEYER
 *      corrected typo in comment
 *
 *      Revision 1.19  1998/04/16 13:22:12  LUEVELSMEYER
 *      added output of import table addresses
 *
 *      Revision 1.18  1998/04/14 15:41:46  LUEVELSMEYER
 *      added comments
 *
 *      Revision 1.17  1998/04/04 16:07:08  LUEVELSMEYER
 *      added command line options & base relocation output
 *
 *      Revision 1.16  1998/04/02 21:37:24  LUEVELSMEYER
 *      supported output of resource-language
 *
 *      Revision 1.15  1998/04/02 16:34:03  LUEVELSMEYER
 *      changed output strings of bound imports
 *
 *      Revision 1.14  1998/04/02 15:56:53  LUEVELSMEYER
 *      added support for new-style-binding of imports
 *
 *      Revision 1.13  1998/04/02 01:18:02  LUEVELSMEYER
 *      beautified indentation
 *
 *      Revision 1.12  1998/04/02 01:07:13  LUEVELSMEYER
 *      linted
 *      (mostly bad printf-conversions)
 *
 *      Revision 1.11  1998/02/18 00:53:50  LUEVELSMEYER
 *      corrected typo
 *
 *      Revision 1.10  1998/01/16 02:51:35  LUEVELSMEYER
 *      changed wording of header output
 *
 *      Revision 1.9  1998/01/16 02:36:25  LUEVELSMEYER
 *      added meaningful exit-codes
 *
 *      Revision 1.8  1997/12/24 22:14:07  LUEVELSMEYER
 *      changed filename output
 *
 *      Revision 1.8  1997/12/24 22:10:53  LUEVELSMEYER
 *      dropped filename on output
 *
 *      Revision 1.7  1997/11/23 00:14:07  LUEVELSMEYER
 *      corrected spelling in output
 *
 *      Revision 1.6  1997/08/10 03:39:09  LUEVELSMEYER
 *      (minor correction in output)
 *
 *      Revision 1.5  1997/08/10 03:33:19  LUEVELSMEYER
 *      added following forwarders
 *
 *      Revision 1.4  1997/08/07 16:54:49  LUEVELSMEYER
 *      added remark on "ForwarderChain"
 *
 *      Revision 1.3  1997/08/06 20:51:13  LUEVELSMEYER
 *      changed one output string
 *
 *      Revision 1.2  1997/06/06 22:26:31  LUEVELSMEYER
 *      added support for bound import; changed to bind for old style
 *
 *      Revision 1.1  1997/06/05 11:23:42  LUEVELSMEYER
 *      Initial revision
 *
 *
 */

#pragma off(unreferenced)
static const char RCSHeader[] = "$Id: pe_map.c,v 1.26 1999/03/20 23:59:47 LUEVELSMEYER Exp $";
#pragma on(unreferenced)



#include "versinfo.h"


/* is an address in the range start up to start+length? */
#define isin(address,start,length) ((char*)(address)>=(char*)(start) && (char*)(address)<(char*)(start)+(length))


static do_the_relocs;           /* controls whether base relocation table is desired */


static void dump_export_directory(const void *const section_base, const DWORD section_base_virtual, const IMAGE_EXPORT_DIRECTORY * const exp, const size_t section_length)
    /* output of an export directory */
{
      #define indent "      "
      #define adr(rva) ((const void*)((char*)section_base+((DWORD)(rva))-section_base_virtual))

    /* prepare for bad linkers */
    if (IsBadReadPtr(exp, sizeof(*exp)))
      {
          puts(indent "!! data inaccessible!!");
          return;
      }

    printf(indent "module name: \"%s\"\n", (char *)adr(exp->Name));
    printf(indent "created (GMT): %s", asctime(gmtime((const time_t *)&exp->TimeDateStamp)));
    printf(indent "version: %d.%d\n", exp->MajorVersion, exp->MinorVersion);
    printf(indent "%lu exported functions, list at %lx\n", exp->NumberOfFunctions, exp->AddressOfFunctions);
    if (exp->NumberOfNames && exp->AddressOfNames)
        printf(indent "%lu exported names, list at %lx\n", exp->NumberOfNames, exp->AddressOfNames);
    else
        puts(indent "(no name table provided)");
    printf(indent "Ordinal base: %lu\n", exp->Base);

    {
        const WORD *ordinal_table = adr(exp->AddressOfNameOrdinals);
        const DWORD *function_table = adr(exp->AddressOfFunctions);
        const DWORD *name_table = exp->AddressOfNames ? adr(exp->AddressOfNames) : 0;
        size_t i;
        unsigned unused_slots = 0;  /* functions with an RVA of 0 seem to be unused */

        printf(indent "%4s %4s %-30s %6s\n", "Ord.", "Hint", "Name", "RVA");
        printf(indent "%4s %4s %-30s %6s\n", "----", "----", "----", "---");

        for (i = 0; i < exp->NumberOfFunctions; i++)
          {
              const DWORD addr = function_table[i];
              if (!addr)        /* skip unused slots */
                {
                    ++unused_slots;
                    continue;
                }

              /* ordinal */
              printf(indent "%4u ", i + exp->Base);

              /* if names provided, list all names of this
               * export ordinal
               */
              if (name_table)
                {
                    size_t n;
                    int found = 0;
                    for (n = 0; n < exp->NumberOfNames; n++)
                      {
                          /* according to the spec, you should
                           * compare to the ordinal 'i+exp->Base'
                           * rather than to 'i', but I've found
                           * this to work and the ordinal not to
                           * work.
                           */
                          if (ordinal_table[n] == i)
                            {
                                /* begin new line for
                                 * additional names
                                 */
                                if (found)
                                    fputs("\n" indent "     ", stdout);

                                printf("%4lu %-30s", (unsigned long)n,adr(name_table[n]));
                                ++found;
                            }
                      }
                    if (!found)
                        /* no names */
                        printf("%4s %-30s", "","(nameless)");
                    else if (found > 1)
                        /* several names, put address in new line */
                        fputs("\n" indent indent, stdout);

                    putchar(' ');
                }

              /* entry point */
              if (addr >= section_base_virtual && addr < section_base_virtual + section_length)
                  /* forwarder */
                  puts(adr(addr));
              else
                  /* normal export */
                  printf("%6lx\n", addr);
          }

        if (unused_slots)
            printf(indent "-- there are %u unused slots --\n", unused_slots);
    }

      #undef adr
      #undef indent
}


static void dump_import_directory(const void *const section_base, const DWORD section_base_virtual, const IMAGE_IMPORT_DESCRIPTOR * imp)
    /* dump of import directory.
     * quite a challenge because of broken linkers, unbound/old-bound and new-bound directories
     */
{
      #define indent "      "
      #define adr(rva) ((const void*)((char*)section_base+((DWORD)(rva))-section_base_virtual))

    for (; !IsBadReadPtr(imp, sizeof(*imp)) && imp->Name; imp++)
      {
          const IMAGE_THUNK_DATA *import_entry, *mapped_entry;
          enum
            {
                bound_none, bound_old, bound_new
            }
          bound;

          printf("\n" indent "from \"%s\":\n", (char *)adr(imp->Name));

          if (imp->TimeDateStamp == ~0UL)
            {
                puts(indent "bound, new style");
                bound = bound_new;
            }
          else if (imp->TimeDateStamp)
            {
                printf(indent "bound (old style) to %s", asctime(gmtime((const time_t *)&imp->TimeDateStamp)));
                bound = bound_old;
            }
          else
            {
                puts(indent "not bound");
                bound = bound_none;
            }

          printf(indent "name table at %#lx, address table at %#lx\n", imp->OriginalFirstThunk, imp->FirstThunk);

          if (imp->OriginalFirstThunk)
            {
                import_entry = adr(imp->OriginalFirstThunk);
                mapped_entry = adr(imp->FirstThunk);
            }
          else
            {
                puts(indent "(hint table missing, probably Borland bug)");
                import_entry = adr(imp->FirstThunk);
                mapped_entry = 0;
                bound = bound_none;
            }

          printf(indent "%6s %s\n", "hint", "name");
          printf(indent "%6s %s\n", "----", "----");

          {
              int count, nextforwarder = bound==bound_old ? imp->ForwarderChain : -1;
              for (count = 0; import_entry->u1.Ordinal; count++, import_entry++, bound ? mapped_entry++ : 0)
                {
                    if (IMAGE_SNAP_BY_ORDINAL(import_entry->u1.Ordinal))
                        printf(indent "%6lu %-20s", IMAGE_ORDINAL(import_entry->u1.Ordinal),"<ordinal>");
                    else
                      {
                          const IMAGE_IMPORT_BY_NAME *name_import = adr(import_entry->u1.AddressOfData);
                          printf(indent "%6u %-20.50s", name_import->Hint, name_import->Name);
                      }
                    if (bound)
                        if (count != nextforwarder)
                            printf("%#12lx\n", (unsigned long)mapped_entry->u1.Function);
                        else
                          {
                              printf("%12s\n", "    --> forward");

⌨️ 快捷键说明

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