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