腊味满,24岁,即将死于“UpdateResource",求救!!!!!! lpType参数必须设置正确:RT_ANIICON、RT_GROUP_ICON或者RT_ICON。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 azuo_lee,请你编写一个修改图标的程序试一试,总是会多出22个字节!! 当我使用RT_ICON更新ICON时加入的22个字节是每次都不同的,当我使用RT_BITMAP更新Bitmap时,加入的是一个Bitmap头的一部分,因为是以"BM"开头的,大家不要小看了UpdateResource,你可以编一个程序试一试,来修改一个EXE的图标,我的程序可以修改,但改了以后在新的ICON前面多了22个字节,只要删除这22个字节就OK了! 这个问题希望大家一定 试一试,我参加革命几年了,这么头痛的问题还是第二次碰到,第一次的问题经过1个月的 苦苦寻找,最后在 Microsoft的Bug list找到了答案,但这个问题Bug List中没有,我想,这应该不是Bug!!! 向你表示同情……如果这是必须逾越的障碍的话,我建议你直接更新exe文件的资源树结构,不用UpdateResource,这个我做过,并不是很难 to rocks_lee:我有PE结构的E文,但没看懂,不知道你能否给我一份代码,感谢! 我的代码是java的,因为不能用windows的结构,因此过于复杂。我记得有一个很好的pedump的例程,也不大,想要的话可以给你贴在这里。不过它只是读取的代码,你要做好精神准备,回写要更复杂一些,因为你要保证exe仍然能够运行:) 不是链表,是树。下面是pe_dump的源代码,不过如果你只是读资源的话,可以简化很多,当然回写则要添加不少代码了。/* pe_map.c, dumps a PE file * made with Watcom C32 version 11.0 on NT 4.0 * (f) by B. Luevelsmeyer 1997, 1998 */#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.22 1998/07/20 12:02:54 LUEVELSMEYER Exp $ * * checked in by $Author: LUEVELSMEYER $ * checked in at $Date: 1998/07/20 12:02:54 $ * * History: * $Log: pe_map.c,v $ * 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 re 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.22 1998/07/20 12:02:54 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) /* output of an export directory */{ #define indent " " #define adr(rva) ((const void*)((char*)section_base+((DWORD)(rva))-section_base_virtual)) int i; if (IsBadReadPtr(exp, sizeof(*exp))) puts(indent "!! data inaccessible!!"); 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\n", exp->NumberOfFunctions); printf(indent "%lu exported names (entries relative to image base in RAM):\n", exp->NumberOfNames); printf(indent "%4s %8s %s\n", "ord.", "entry", "name"); printf(indent "%4s %8s %s\n", "----", "-----", "----"); { const WORD *ordinal_table = adr(exp->AddressOfNameOrdinals); const DWORD *function_table = adr(exp->AddressOfFunctions); const DWORD *name_table = adr(exp->AddressOfNames); for (i = min(exp->NumberOfFunctions, exp->NumberOfNames); i--; ordinal_table++, function_table++, name_table++) printf(indent "%4lu %8lx %s\n", *ordinal_table + exp->Base, *function_table, (char *)adr(*name_table)); } #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", "ord.", "name"); printf(indent "%6s %s\n", "----", "----"); { int count, nextforwarder = imp->ForwarderChain; 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 <only number supplied>", IMAGE_ORDINAL(import_entry->u1.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"); 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 forwarders 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 "to %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); 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; 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;} 如何修改CMainFrame的标题字体大小,以及标题居中 怎样用SetTimer封装一个计时器? 画图一般是在文档视图中吗? 关于控件摆放位置问题 ==出差在外散分== 如何在程序里实现模拟网页中的表单提交功能. pdf的问题 请问哪位有图片变换特效的源代码? 如何画一个圆圈,圆的中间没有被填充 串口编程,串口打开时跟换串口时怎么判断电脑是否有这个串口 请问rtx(Nokia铃声文件)文件格式是什麽,它是如何定义的,我的mail:[email protected],谢谢 用VC操纵Word文档,是否可行?
如果这是必须逾越的障碍的话,我建议你直接更新exe文件的资源树结构,
不用UpdateResource,这个我做过,并不是很难
我有PE结构的E文,但没看懂,不知道你能否给我一份代码,感谢!
我记得有一个很好的pedump的例程,也不大,想要的话可以给你贴在这里。
不过它只是读取的代码,你要做好精神准备,回写要更复杂一些,
因为你要保证exe仍然能够运行:)
下面是pe_dump的源代码,不过如果你只是读资源的话,可以简化很多,当然回写则要添加不少代码了。/* pe_map.c, dumps a PE file
* made with Watcom C32 version 11.0 on NT 4.0
* (f) by B. Luevelsmeyer 1997, 1998
*/#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.22 1998/07/20 12:02:54 LUEVELSMEYER Exp $
*
* checked in by $Author: LUEVELSMEYER $
* checked in at $Date: 1998/07/20 12:02:54 $
*
* History:
* $Log: pe_map.c,v $
* 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 re 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.22 1998/07/20 12:02:54 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)
/* output of an export directory */
{
#define indent " "
#define adr(rva) ((const void*)((char*)section_base+((DWORD)(rva))-section_base_virtual)) int i;
if (IsBadReadPtr(exp, sizeof(*exp)))
puts(indent "!! data inaccessible!!"); 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\n", exp->NumberOfFunctions);
printf(indent "%lu exported names (entries relative to image base in RAM):\n", exp->NumberOfNames); printf(indent "%4s %8s %s\n", "ord.", "entry", "name");
printf(indent "%4s %8s %s\n", "----", "-----", "----"); {
const WORD *ordinal_table = adr(exp->AddressOfNameOrdinals);
const DWORD *function_table = adr(exp->AddressOfFunctions);
const DWORD *name_table = adr(exp->AddressOfNames);
for (i = min(exp->NumberOfFunctions, exp->NumberOfNames); i--; ordinal_table++, function_table++, name_table++)
printf(indent "%4lu %8lx %s\n", *ordinal_table + exp->Base, *function_table, (char *)adr(*name_table));
} #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", "ord.", "name");
printf(indent "%6s %s\n", "----", "----"); {
int count, nextforwarder = imp->ForwarderChain;
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 <only number supplied>", IMAGE_ORDINAL(import_entry->u1.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");
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 forwarders 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 "to %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);
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;
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;
}