📄 pe_map.c
字号:
/*
* 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 + -