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