pedump.c
来源:互联网 发布:oracle sql nvl函数 编辑:程序博客网 时间:2024/06/09 17:46
// $Id: pedump.c 17587 2005-08-28 15:29:36Z hpoussin $//// This program was written by Sang Cho, assistant professor at// the department of// computer science and engineering// chongju university// this program is based on the program pefile.c// which is written by Randy Kath(Microsoft Developmer Network Technology Group)// in june 12, 1993.// I have investigated P.E. file format as thoroughly as possible,// but I cannot claim that I am an expert yet, so some of its information// may give you wrong results.//////// language used: djgpp// date of creation: September 28, 1997//// date of first release: October 15, 1997////// you can contact me: e-mail address: sangcho@alpha94.chongju.ac.kr// hitel id: chokhas// phone number: (0431) 229-8491 +82-431-229-8491//////// Copyright (C) 1997. by Sang Cho.//// Permission is granted to make and distribute verbatim copies of this// program provided the copyright notice and this permission notice are// preserved on all copies.////// File: pedump.c ( I included header file into source file. )//// LICENSE// Sources released under GNU General Public License version 2// or later by Mr. Sang Cho permission.//// REVISIONS// 2000-04-23 (ea) Initial adaptation to GCC/MinGW/ROS.// 2000-08-05 (ea) Initial raw adaptation done.// 2006-11-13 http://www.quietearth.us///#include <stdio.h>#include <stdarg.h>#include <string.h>#include <setjmp.h>#include <malloc.h>#include <ctype.h>#ifndef bcopy#define bcopy(s,d,z) memcpy((d),(s),(z))#endiftypedef char CHAR;typedef short WCHAR;typedef short SHORT;typedef long LONG;typedef unsigned short USHORT;typedef unsigned long DWORD;typedef int BOOL;typedef unsigned char BYTE;typedef unsigned short WORD;typedef BYTE *PBYTE;typedef WORD *PWORD;typedef DWORD *PDWORD;typedef void *LPVOID;typedef int boolean;#define VOID void#define BOOLEAN boolean#ifndef NULL#define NULL 0#endif#define FALSE 0#define TRUE 1#define CONST const#define LOWORD(l) ((WORD)(l))/*#define __stdcall*///// Image Format//#define IMAGE_DOS_SIGNATURE 0x5A4D// MZ#define IMAGE_OS2_SIGNATURE 0x454E// NE#define IMAGE_OS2_SIGNATURE_LE 0x454C// LE#define IMAGE_VXD_SIGNATURE 0x454C// LE#define IMAGE_NT_SIGNATURE 0x00004550// PE00typedef struct _IMAGE_DOS_HEADER {// DOS .EXE header WORD e_magic;// Magic number WORD e_cblp;// Bytes on last page of file WORD e_cp;// Pages in file WORD e_crlc;// Relocations WORD e_cparhdr;// Size of header in paragraphs WORD e_minalloc;// Minimum extra paragraphs needed WORD e_maxalloc;// Maximum extra paragraphs needed WORD e_ss;// Initial (relative) SS value WORD e_sp;// Initial SP value WORD e_csum;// Checksum WORD e_ip;// Initial IP value WORD e_cs;// Initial (relative) CS value WORD e_lfarlc;// File address of relocation table WORD e_ovno;// Overlay number WORD e_res[4];// Reserved words WORD e_oemid;// OEM identifier (for e_oeminfo) WORD e_oeminfo;// OEM information; e_oemid specific WORD e_res2[10];// Reserved words LONG e_lfanew;// File address of new exe header }IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;//// File header format.//typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; }IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;#define IMAGE_SIZEOF_FILE_HEADER 20#define IMAGE_FILE_RELOCS_STRIPPED 0x0001// Relocation info stripped from file.#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002// File is executable (i.e. no unresolved externel references).#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004// Line nunbers stripped from file.#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008// Local symbols stripped from file.#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080// Bytes of machine word are reversed.#define IMAGE_FILE_32BIT_MACHINE 0x0100// 32 bit word machine.#define IMAGE_FILE_DEBUG_STRIPPED 0x0200// Debugging info stripped from file in .DBG file#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400// If Image is on removable media, copy and run from the swap file.#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800// If Image is on Net, copy and run from the swap file.#define IMAGE_FILE_SYSTEM 0x1000// System File.#define IMAGE_FILE_DLL 0x2000// File is a DLL.#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000// File should only be run on a UP machine#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000// Bytes of machine word are reversed.#define IMAGE_FILE_MACHINE_UNKNOWN 0#define IMAGE_FILE_MACHINE_I386 0x14c// Intel 386.#define IMAGE_FILE_MACHINE_R3000 0x162// MIPS little-endian, 0x160 big-endian#define IMAGE_FILE_MACHINE_R4000 0x166// MIPS little-endian#define IMAGE_FILE_MACHINE_R10000 0x168// MIPS little-endian#define IMAGE_FILE_MACHINE_ALPHA 0x184// Alpha_AXP#define IMAGE_FILE_MACHINE_POWERPC 0x1F0// IBM PowerPC Little-Endian//// Directory format.//typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; }IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16//// Optional header format.//typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; // // NT additional fields. // DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; }IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; }IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;// Directory Entries#define IMAGE_DIRECTORY_ENTRY_EXPORT 0// Export Directory#define IMAGE_DIRECTORY_ENTRY_IMPORT 1// Import Directory#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2// Resource Directory#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3// Exception Directory#define IMAGE_DIRECTORY_ENTRY_SECURITY 4// Security Directory#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5// Base Relocation Table#define IMAGE_DIRECTORY_ENTRY_DEBUG 6// Debug Directory#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7// Description String#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8// Machine Value (MIPS GP)#define IMAGE_DIRECTORY_ENTRY_TLS 9// TLS Directory#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10// Load Configuration Directory#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11// Bound Import Directory in headers#define IMAGE_DIRECTORY_ENTRY_IAT 12// Import Address Table//// Section header format.//#define IMAGE_SIZEOF_SHORT_NAME 8typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union {DWORD PhysicalAddress;DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; }IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;#define IMAGE_SIZEOF_SECTION_HEADER 40//// Export Format//typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; PDWORD *AddressOfFunctions; PDWORD *AddressOfNames; PWORD *AddressOfNameOrdinals; }IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;//// Import Format//typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; }IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;#define IMAGE_ORDINAL_FLAG 0x80000000#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)//// Resource Format.////// Resource directory consists of two counts, following by a variable length// array of directory entries. The first count is the number of entries at// beginning of the array that have actual names associated with each entry.// The entries are in ascending order, case insensitive strings. The second// count is the number of entries that immediately follow the named entries.// This second count identifies the number of entries that have 16-bit integer// Ids as their name. These entries are also sorted in ascending order.//// This structure allows fast lookup by either name or number, but for any// given resource entry only one form of lookup is supported, not both.// This is consistant with the syntax of the .RC file and the .RES file.//// Predefined resource types ... there may be some more, but I don't have// the information yet. .....sang cho.....#define RT_NEWRESOURCE 0x2000#define RT_ERROR 0x7fff#define RT_CURSOR 1#define RT_BITMAP 2#define RT_ICON 3#define RT_MENU 4#define RT_DIALOG 5#define RT_STRING 6#define RT_FONTDIR 7#define RT_FONT 8#define RT_ACCELERATORS 9#define RT_RCDATA 10#define RT_MESSAGETABLE 11#define RT_GROUP_CURSOR 12#define RT_GROUP_ICON 14#define RT_VERSION 16#define NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)#define NEWMENU (RT_MENU|RT_NEWRESOURCE)#define NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries;// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1]; }IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000//// Each directory contains the 32-bit Name of the entry and an offset,// relative to the beginning of the resource directory of the data associated// with this directory entry. If the name of the entry is an actual text// string instead of an integer Id, then the high order bit of the name field// is set to one and the low order 31-bits are an offset, relative to the// beginning of the resource directory of the string, which is of type// IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the// low-order 16-bits are the integer Id that identify this resource directory// entry. If the directory entry is yet another resource directory (i.e. a// subdirectory), then the high order bit of the offset field will be// set to indicate this. Otherwise the high bit is clear and the offset// field points to a resource data entry.//typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { DWORD Name; DWORD OffsetToData; }IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;//// For resource directory entries that have actual string names, the Name// field of the directory entry points to an object of the following type.// All of these string objects are stored together after the last resource// directory entry and before the first resource data object. This minimizes// the impact of these variable length objects on the alignment of the fixed// size directory entry objects.//typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { WORD Length; CHAR NameString[1]; }IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;typedef struct _IMAGE_RESOURCE_DIR_STRING_U { WORD Length; WCHAR NameString[1]; }IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;//// Each resource data entry describes a leaf node in the resource directory// tree. It contains an offset, relative to the beginning of the resource// directory of the data for the resource, a size field that gives the number// of bytes of data at that offset, a CodePage that should be used when// decoding code point values within the resource data. Typically for new// applications the code page would be the unicode code page.//typedef struct _IMAGE_RESOURCE_DATA_ENTRY { DWORD OffsetToData; DWORD Size; DWORD CodePage; DWORD Reserved; }IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;// Menu Resources ... added by .....sang cho....// Menu resources are composed of a menu header followed by a sequential list// of menu items. There are two types of menu items: pop-ups and normal menu// itmes. The MENUITEM SEPARATOR is a special case of a normal menu item with// an empty name, zero ID, and zero flags.typedef struct _IMAGE_MENU_HEADER { WORD wVersion;// Currently zero WORD cbHeaderSize;// Also zero }IMAGE_MENU_HEADER, *PIMAGE_MENU_HEADER;typedef struct _IMAGE_POPUP_MENU_ITEM { WORD fItemFlags; WCHAR szItemText[1]; }IMAGE_POPUP_MENU_ITEM, *PIMAGE_POPUP_MENU_ITEM;typedef struct _IMAGE_NORMAL_MENU_ITEM { WORD fItemFlags; WORD wMenuID; WCHAR szItemText[1]; }IMAGE_NORMAL_MENU_ITEM, *PIMAGE_NORMAL_MENU_ITEM;#define GRAYED 0x0001// GRAYED keyword#define INACTIVE 0x0002// INACTIVE keyword#define BITMAP 0x0004// BITMAP keyword#define OWNERDRAW 0x0100// OWNERDRAW keyword#define CHECKED 0x0008// CHECKED keyword#define POPUP 0x0010// used internally#define MENUBARBREAK 0x0020// MENUBARBREAK keyword#define MENUBREAK 0x0040// MENUBREAK keyword#define ENDMENU 0x0080// used internally// Dialog Box Resources .................. added by sang cho.// A dialog box is contained in a single resource and has a header and// a portion repeated for each control in the dialog box.// The item DWORD IStyle is a standard window style composed of flags found// in WINDOWS.H.// The default style for a dialog box is:// WS_POPUP | WS_BORDER | WS_SYSMENU//// The itme marked "Name or Ordinal" are :// If the first word is an 0xffff, the next two bytes contain an ordinal ID.// Otherwise, the first one or more WORDS contain a double-null-terminated string.// An empty string is represented by a single WORD zero in the first location.//// The WORD wPointSize and WCHAR szFontName entries are present if the FONT// statement was included for the dialog box. This can be detected by checking// the entry IStyle. If IStyle & DS_SETFONT ( which is 0x40), then these// entries will be present.typedef struct _IMAGE_DIALOG_BOX_HEADER1 { DWORD IStyle; DWORD IExtendedStyle;// New for Windows NT WORD nControls;// Number of Controls WORD x; WORD y; WORD cx; WORD cy;// N_OR_O MenuName; // Name or Ordinal ID // N_OR_O ClassName; // Name or Ordinal ID // WCHAR szCaption[]; // WORD wPointSize; // Only here if FONT set for dialog // WCHAR szFontName[]; // This too }IMAGE_DIALOG_HEADER, *PIMAGE_DIALOG_HEADER;typedef union _NAME_OR_ORDINAL {// Name or Ordinal ID struct _ORD_ID {WORD flgId;WORD Id; } ORD_ID; WCHAR szName[1]; }NAME_OR_ORDINAL, *PNAME_OR_ORDINAL;// The data for each control starts on a DWORD boundary (which may require// some padding from the previous control), and its format is as follows:typedef struct _IMAGE_CONTROL_DATA { DWORD IStyle; DWORD IExtendedStyle; WORD x; WORD y; WORD cx; WORD cy; WORD wId;// N_OR_O ClassId; // N_OR_O Text; // WORD nExtraStuff; }IMAGE_CONTROL_DATA, *PIMAGE_CONTROL_DATA;#define BUTTON 0x80#define EDIT 0x81#define STATIC 0x82#define LISTBOX 0x83#define SCROLLBAR 0x84#define COMBOBOX 0x85// The various statements used in a dialog script are all mapped to these// classes along with certain modifying styles. The values for these styles// can be found in WINDOWS.H. All dialog controls have the default styles// of WS_CHILD and WS_VISIBLE. A list of the default styles used follows://// Statement Default Class Default Styles// CONTROL None WS_CHILD|WS_VISIBLE// LTEXT STATIC ES_LEFT// RTEXT STATIC ES_RIGHT// CTEXT STATIC ES_CENTER// LISTBOX LISTBOX WS_BORDER|LBS_NOTIFY// CHECKBOX BUTTON BS_CHECKBOX|WS_TABSTOP// PUSHBUTTON BUTTON BS_PUSHBUTTON|WS_TABSTOP// GROUPBOX BUTTON BS_GROUPBOX// DEFPUSHBUTTON BUTTON BS_DFPUSHBUTTON|WS_TABSTOP// RADIOBUTTON BUTTON BS_RADIOBUTTON// AUTOCHECKBOX BUTTON BS_AUTOCHECKBOX// AUTO3STATE BUTTON BS_AUTO3STATE// AUTORADIOBUTTON BUTTON BS_AUTORADIOBUTTON// PUSHBOX BUTTON BS_PUSHBOX// STATE3 BUTTON BS_3STATE// EDITTEXT EDIT ES_LEFT|WS_BORDER|WS_TABSTOP// COMBOBOX COMBOBOX None// ICON STATIC SS_ICON// SCROLLBAR SCROLLBAR None///#define WS_OVERLAPPED 0x00000000L#define WS_POPUP 0x80000000L#define WS_CHILD 0x40000000L#define WS_CLIPSIBLINGS 0x04000000L#define WS_CLIPCHILDREN 0x02000000L#define WS_VISIBLE 0x10000000L#define WS_DISABLED 0x08000000L#define WS_MINIMIZE 0x20000000L#define WS_MAXIMIZE 0x01000000L#define WS_CAPTION 0x00C00000L#define WS_BORDER 0x00800000L#define WS_DLGFRAME 0x00400000L#define WS_VSCROLL 0x00200000L#define WS_HSCROLL 0x00100000L#define WS_SYSMENU 0x00080000L#define WS_THICKFRAME 0x00040000L#define WS_MINIMIZEBOX 0x00020000L#define WS_MAXIMIZEBOX 0x00010000L#define WS_GROUP 0x00020000L#define WS_TABSTOP 0x00010000L// other aliases#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)#define WS_CHILDWINDOW (WS_CHILD)#define WS_TILED WS_OVERLAPPED#define WS_ICONIC WS_MINIMIZE#define WS_SIZEBOX WS_THICKFRAME#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW#define WS_EX_DLGMODALFRAME 0x00000001L#define WS_EX_NOPARENTNOTIFY 0x00000004L#define WS_EX_TOPMOST 0x00000008L#define WS_EX_ACCEPTFILES 0x00000010L#define WS_EX_TRANSPARENT 0x00000020L#define BS_PUSHBUTTON 0x00000000L#define BS_DEFPUSHBUTTON 0x00000001L#define BS_CHECKBOX 0x00000002L#define BS_AUTOCHECKBOX 0x00000003L#define BS_RADIOBUTTON 0x00000004L#define BS_3STATE 0x00000005L#define BS_AUTO3STATE 0x00000006L#define BS_GROUPBOX 0x00000007L#define BS_USERBUTTON 0x00000008L#define BS_AUTORADIOBUTTON 0x00000009L#define BS_OWNERDRAW 0x0000000BL#define BS_LEFTTEXT 0x00000020L#define ES_LEFT 0x00000000L#define ES_CENTER 0x00000001L#define ES_RIGHT 0x00000002L#define ES_MULTILINE 0x00000004L#define ES_UPPERCASE 0x00000008L#define ES_LOWERCASE 0x00000010L#define ES_PASSWORD 0x00000020L#define ES_AUTOVSCROLL 0x00000040L#define ES_AUTOHSCROLL 0x00000080L#define ES_NOHIDESEL 0x00000100L#define ES_OEMCONVERT 0x00000400L#define ES_READONLY 0x00000800L#define ES_WANTRETURN 0x00001000L#define LBS_NOTIFY 0x0001L#define LBS_SORT 0x0002L#define LBS_NOREDRAW 0x0004L#define LBS_MULTIPLESEL 0x0008L#define LBS_OWNERDRAWFIXED 0x0010L#define LBS_OWNERDRAWVARIABLE 0x0020L#define LBS_HASSTRINGS 0x0040L#define LBS_USETABSTOPS 0x0080L#define LBS_NOINTEGRALHEIGHT 0x0100L#define LBS_MULTICOLUMN 0x0200L#define LBS_WANTKEYBOARDINPUT 0x0400L#define LBS_EXTENDEDSEL 0x0800L#define LBS_DISABLENOSCROLL 0x1000L#define SS_LEFT 0x00000000L#define SS_CENTER 0x00000001L#define SS_RIGHT 0x00000002L#define SS_ICON 0x00000003L#define SS_BLACKRECT 0x00000004L#define SS_GRAYRECT 0x00000005L#define SS_WHITERECT 0x00000006L#define SS_BLACKFRAME 0x00000007L#define SS_GRAYFRAME 0x00000008L#define SS_WHITEFRAME 0x00000009L#define SS_SIMPLE 0x0000000BL#define SS_LEFTNOWORDWRAP 0x0000000CL#define SS_BITMAP 0x0000000EL//// Debug Format//typedef struct _IMAGE_DEBUG_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Type; DWORD SizeOfData; DWORD AddressOfRawData; DWORD PointerToRawData; }IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;#define IMAGE_DEBUG_TYPE_UNKNOWN 0#define IMAGE_DEBUG_TYPE_COFF 1#define IMAGE_DEBUG_TYPE_CODEVIEW 2#define IMAGE_DEBUG_TYPE_FPO 3#define IMAGE_DEBUG_TYPE_MISC 4#define IMAGE_DEBUG_TYPE_EXCEPTION 5#define IMAGE_DEBUG_TYPE_FIXUP 6#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8typedef struct _IMAGE_DEBUG_MISC { DWORD DataType;// type of misc data, see defines DWORD Length;// total length of record, rounded to four // byte multiple. BOOLEAN Unicode;// TRUE if data is unicode string BYTE Reserved[3]; BYTE Data[1];// Actual data }IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC;//// Debugging information can be stripped from an image file and placed// in a separate .DBG file, whose file name part is the same as the// image file name part (e.g. symbols for CMD.EXE could be stripped// and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED// flag in the Characteristics field of the file header. The beginning of// the .DBG file contains the following structure which captures certain// information from the image file. This allows a debug to proceed even if// the original image file is not accessable. This header is followed by// zero of more IMAGE_SECTION_HEADER structures, followed by zero or more// IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in// the image file contain file offsets relative to the beginning of the// .DBG file.//// If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure// is left in the image file, but not mapped. This allows a debugger to// compute the name of the .DBG file, from the name of the image in the// IMAGE_DEBUG_MISC structure.//typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { WORD Signature; WORD Flags; WORD Machine; WORD Characteristics; DWORD TimeDateStamp; DWORD CheckSum; DWORD ImageBase; DWORD SizeOfImage; DWORD NumberOfSections; DWORD ExportedNamesSize; DWORD DebugDirectorySize; DWORD SectionAlignment; DWORD Reserved[2]; }IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER;#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944#define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000#define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000// when DBG was updated, the// old checksum didn't match.//// End Image Format//#define SIZE_OF_NT_SIGNATUREsizeof (DWORD)#define MAXRESOURCENAME 13/* global macros to define header offsets into file *//* offset to PE file signature */#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a +/((PIMAGE_DOS_HEADER)a)->e_lfanew))/* DOS header identifies the NT PEFile signature dword the PEFILE header exists just after that dword */#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a +/ ((PIMAGE_DOS_HEADER)a)->e_lfanew +/ SIZE_OF_NT_SIGNATURE))/* PE optional header is immediately after PEFile header */#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a +/ ((PIMAGE_DOS_HEADER)a)->e_lfanew +/ SIZE_OF_NT_SIGNATURE +/ sizeof (IMAGE_FILE_HEADER)))/* section headers are immediately after PE optional header */#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a +/ ((PIMAGE_DOS_HEADER)a)->e_lfanew +/ SIZE_OF_NT_SIGNATURE +/ sizeof (IMAGE_FILE_HEADER) +/ sizeof (IMAGE_OPTIONAL_HEADER)))typedef struct tagImportDirectory { DWORD dwRVAFunctionNameList; DWORD dwUseless1; DWORD dwUseless2; DWORD dwRVAModuleName; DWORD dwRVAFunctionAddressList; }IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;/* global prototypes for functions in pefile.c *//* PE file header info */BOOL GetDosHeader (LPVOID, PIMAGE_DOS_HEADER);DWORD ImageFileType (LPVOID);BOOL GetPEFileHeader (LPVOID, PIMAGE_FILE_HEADER);/* PE optional header info */BOOL GetPEOptionalHeader (LPVOID, PIMAGE_OPTIONAL_HEADER);LPVOID GetModuleEntryPoint (LPVOID);int NumOfSections (LPVOID);LPVOID GetImageBase (LPVOID);LPVOID ImageDirectoryOffset (LPVOID, DWORD);LPVOID ImageDirectorySection (LPVOID, DWORD);/* PE section header info *///int GetSectionNames (LPVOID, HANDLE, char **);int GetSectionNames (LPVOID, char **);BOOL GetSectionHdrByName (LPVOID, PIMAGE_SECTION_HEADER, char *);//// structur to store string tokens//typedef struct _Str_P { char flag;// string_flag '@' or '%' or '#' char *pos;// starting postion of string int length;// length of string BOOL wasString;// if it were stringMode or not }Str_P;/* import section info */int GetImportModuleNames (LPVOID, char **);int GetImportFunctionNamesByModule (LPVOID, char *, char **);// import function name reportingint GetStringLength (char *);void GetPreviousParamString (char *, char *);void TranslateParameters (char **, char **, char **);BOOL StringExpands (char **, char **, char **, Str_P *);char * TranslateFunctionName (char *);/* export section info */int GetExportFunctionNames (LPVOID, char **);/* resource section info */int GetNumberOfResources (LPVOID);int GetListOfResourceTypes (LPVOID, char **);int MenuScan (int *, WORD **);int MenuFill (char **, WORD **);void StrangeMenuFill (char **, WORD **, int);int GetContentsOfMenu (LPVOID, char **);int PrintMenu (int, char **);int PrintStrangeMenu (char **);int dumpMenu (char **psz, int size);/* debug section info */BOOL IsDebugInfoStripped (LPVOID);int RetrieveModuleName (LPVOID, char **);BOOL IsDebugFile (LPVOID);BOOL GetSeparateDebugHeader (LPVOID, PIMAGE_SEPARATE_DEBUG_HEADER);/********************************************************************** * NAME * * DESCRIPTION *Copy DOS header information to structure. * * ARGUMENTS */BOOL GetDosHeader ( LPVOID lpFile, PIMAGE_DOS_HEADER pHeader){ /* * DOS header represents first structure * of bytes in PE image file. */ if ((WORD) IMAGE_DOS_SIGNATURE == *(WORD *) lpFile) { bcopy ( lpFile, (LPVOID) pHeader, sizeof (IMAGE_DOS_HEADER)); return TRUE; } return FALSE;}/* return file signature */DWORD ImageFileType (LPVOID lpFile){ /* dos file signature comes first */ if (*(USHORT *) lpFile == IMAGE_DOS_SIGNATURE) { /* determine location of PE File header from dos header */ if (LOWORD (*(DWORD *) NTSIGNATURE (lpFile)) == IMAGE_OS2_SIGNATURE || LOWORD (*(DWORD *) NTSIGNATURE (lpFile)) == IMAGE_OS2_SIGNATURE_LE)return (DWORD) LOWORD (*(DWORD *) NTSIGNATURE (lpFile)); else if (*(DWORD *) NTSIGNATURE (lpFile) == IMAGE_NT_SIGNATURE)return IMAGE_NT_SIGNATURE; elsereturn IMAGE_DOS_SIGNATURE; } else /* unknown file type */ return 0;}/* copy file header information to structure */BOOL GetPEFileHeader ( LPVOID lpFile, PIMAGE_FILE_HEADER pHeader){ /* file header follows dos header */ if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE) bcopy (PEFHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_FILE_HEADER)); else return FALSE; return TRUE;}/* copy optional header info to structure */BOOL GetPEOptionalHeader ( LPVOID lpFile, PIMAGE_OPTIONAL_HEADER pHeader){ /* optional header follows file header and dos header */ if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE) bcopy (OPTHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_OPTIONAL_HEADER)); else return FALSE; return TRUE;}/* function returns the entry point for an exe module lpFile must be a memory mapped file pointer to the beginning of the image file */LPVOID GetModuleEntryPoint ( LPVOID lpFile){ PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile); if (poh != NULL) return (LPVOID) (poh->AddressOfEntryPoint); else return NULL;}/* return the total number of sections in the module */int NumOfSections (LPVOID lpFile){ /* number os sections is indicated in file header */ return ((int) ((PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile))->NumberOfSections);}/* retrieve entry point */LPVOID GetImageBase ( LPVOID lpFile){ PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile); if (poh != NULL) return (LPVOID) (poh->ImageBase); else return NULL;}//// This function is written by sang cho// .. october 5, 1997///* function returns the actual address of given RVA, lpFile must be a memory mapped file pointer to the beginning of the image file */LPVOID GetActualAddress ( LPVOID lpFile, DWORD dwRVA){// PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile); PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile); int nSections = NumOfSections (lpFile); int i = 0; if (dwRVA == 0) return NULL; if (dwRVA & 0x80000000) { //return (LPVOID)dwRVA; printf ("/n$$ what is going on $$"); exit (0); } /* locate section containing image directory */ while (i++ < nSections) { if (psh->VirtualAddress <= (DWORD) dwRVA && psh->VirtualAddress + psh->SizeOfRawData > (DWORD) dwRVA)break; psh++; } if (i > nSections) return NULL; /* return image import directory offset */ return (LPVOID) (((int) lpFile + (int) dwRVA - psh->VirtualAddress) + (int) psh->PointerToRawData);}//// This function is modified by sang cho/////* return offset to specified IMAGE_DIRECTORY entry */LPVOID ImageDirectoryOffset ( LPVOID lpFile, DWORD dwIMAGE_DIRECTORY){ PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile); PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile); int nSections = NumOfSections (lpFile); int i = 0; LPVOID VAImageDir; /* must be 0 thru (NumberOfRvaAndSizes-1) */ if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes) return NULL; /* locate specific image directory's relative virtual address */ VAImageDir = (LPVOID) poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress; if (VAImageDir == NULL) return NULL; /* locate section containing image directory */ while (i++ < nSections) { if (psh->VirtualAddress <= (DWORD) VAImageDir && psh->VirtualAddress + psh->SizeOfRawData > (DWORD) VAImageDir)break; psh++; } if (i > nSections) return NULL; /* return image import directory offset */ return (LPVOID) (((int) lpFile + (int) VAImageDir - psh->VirtualAddress) + (int) psh->PointerToRawData);}/* function retrieve names of all the sections in the file */int GetSectionNames ( LPVOID lpFile, char **pszSections){ int nSections = NumOfSections (lpFile); int i, nCnt = 0; PIMAGE_SECTION_HEADER psh; char *ps; if (ImageFileType (lpFile) != IMAGE_NT_SIGNATURE || (psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) == NULL) return 0; /* count the number of chars used in the section names */ for (i = 0; i < nSections; i++) nCnt += strlen ((char *)psh[i].Name) + 1; /* allocate space for all section names from heap */ ps = *pszSections = (char *) calloc (nCnt, 1); for (i = 0; i < nSections; i++) { strcpy (ps, (char *)psh[i].Name); ps += strlen ((char *)psh[i].Name) + 1; } return nCnt;}/* function gets the function header for a section identified by name */BOOL GetSectionHdrByName ( LPVOID lpFile, IMAGE_SECTION_HEADER * sh, char *szSection){ PIMAGE_SECTION_HEADER psh; int nSections = NumOfSections (lpFile); int i; if ((psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) != NULL) { /* find the section by name */ for (i = 0; i < nSections; i++){ if (!strcmp ((char *)psh->Name, szSection)) { /* copy data to header */ bcopy ((LPVOID) psh, (LPVOID) sh, sizeof (IMAGE_SECTION_HEADER)); return TRUE; } else psh++;} } return FALSE;}//// This function is modified by sang cho/////* get import modules names separated by null terminators, return module count */int GetImportModuleNames ( LPVOID lpFile, char **pszModules){ PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT); // // sometimes there may be no section for idata or edata // instead rdata or data section may contain these sections .. // or even module names or function names are in different section. // so that's why we need to get actual address of RVAs each time. // ...................sang cho.................. // // PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) // ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT); // BYTE *pData = (BYTE *)pid; // DWORD *pdw = (DWORD *)pid; int nCnt = 0, nSize = 0, i; char *pModule[1024];/* hardcoded maximum number of modules?? */ char *psz; if (pid == NULL) return 0; // pData = (BYTE *)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress); /* extract all import modules */ while (pid->dwRVAModuleName) { /* allocate temporary buffer for absolute string offsets */ //pModule[nCnt] = (char *)(pData + pid->dwRVAModuleName); pModule[nCnt] = (char *) GetActualAddress (lpFile, pid->dwRVAModuleName); nSize += strlen (pModule[nCnt]) + 1; /* increment to the next import directory entry */ pid++; nCnt++; } /* copy all strings to one chunk of memory */ *pszModules = (char *) calloc (nSize, 1); psz = *pszModules; for (i = 0; i < nCnt; i++) { strcpy (psz, pModule[i]); psz += strlen (psz) + 1; } return nCnt;}//// This function is rewritten by sang cho/////* get import module function names separated by null terminators, return function count */int GetImportFunctionNamesByModule ( LPVOID lpFile, char *pszModule, char **pszFunctions){ PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT); // // sometimes there may be no section for idata or edata // instead rdata or data section may contain these sections .. // or even module names or function names are in different section. // so that's why we need to get actual address each time. // ...................sang cho.................. // //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT); //DWORD dwBase; int nCnt = 0, nSize = 0; int nnid = 0; int mnlength, i; DWORD dwFunctionName; DWORD dwFunctionAddress; char name[128]; char buff[256];// enough for any string ?? char *psz; DWORD *pdw; //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress); /* find module's pid */ while (pid->dwRVAModuleName && strcmp (pszModule, (char *) GetActualAddress (lpFile, pid->dwRVAModuleName))) pid++; /* exit if the module is not found */ if (!pid->dwRVAModuleName) return 0; // I am doing this to get rid of .dll from module name strcpy (name, pszModule); mnlength = strlen (pszModule); for (i = 0; i < mnlength; i++) if (name[i] == '.') break; name[i] = 0; mnlength = i; /* count number of function names and length of strings */ dwFunctionName = pid->dwRVAFunctionNameList; // IMAGE_IMPORT_BY_NAME OR IMAGE_THUNK_DATA // modified by Sang Cho while (dwFunctionName && *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName))) { if ((*pdw) & 0x80000000)nSize += mnlength + 10 + 1 + 6; elsenSize += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1 + 6; dwFunctionName += 4; nCnt++; } /* allocate memory for function names */ *pszFunctions = (char *) calloc (nSize, 1); psz = *pszFunctions; // // I modified this part to store function address (4 bytes), // ord number (2 bytes), // and name strings (which was there originally) // so that's why there are 6 more bytes...... +6, or +4 and +2 etc. // these informations are used where they are needed. // ...........sang cho.................. // /* copy function names to mempry pointer */ dwFunctionName = pid->dwRVAFunctionNameList; dwFunctionAddress = pid->dwRVAFunctionAddressList; while (dwFunctionName && *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName))) { if ((*pdw) & 0x80000000){ *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress)); psz += 4; *(short *) psz = *(short *) pdw; psz += 2; sprintf (buff, "%s:NoName%04d", name, nnid++); strcpy (psz, buff); psz += strlen (buff) + 1;} else{ *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress)); psz += 4; *(short *) psz = (*(short *) GetActualAddress (lpFile, *pdw)); psz += 2; strcpy (psz, (char *) GetActualAddress (lpFile, *pdw + 2)); psz += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1;} dwFunctionName += 4; dwFunctionAddress += 4; } return nCnt;}//// This function is written by sang cho// October 6, 1997///* get numerically expressed string length */int GetStringLength ( char *psz){ if (!isdigit (*psz)) return 0; if (isdigit (*(psz + 1))) return (*psz - '0') * 10 + *(psz + 1) - '0'; else return *psz - '0';}//// This function is written by sang cho// October 12, 1997///* translate parameter part of condensed name */void GetPreviousParamString ( char *xpin,// read-only source char *xpout)// translated result { int n = 0; char *pin, *pout; pin = xpin; pout = xpout; pin--; if (*pin == ',') pin--; else { printf ("/n **error PreviousParamString1 char = %c", *pin); exit (0); } while (*pin) { if (*pin == '>')n++; else if (*pin == '<')n--; else if (*pin == ')')n++; if (n > 0){ if (*pin == '(') n--;} else if (strchr (",(", *pin))break; pin--; } //printf("/n ----- %s", pin); if (strchr (",(", *pin)) { pin++; }// printf("/n %s", pin); } else { printf ("/n **error PreviousParamString2"); exit (0); } n = xpin - pin - 1; strncpy (pout, pin, n); *(pout + n) = 0;}//// This function is written by sang cho// October 10, 1997///* translate parameter part of condensed name */void TranslateParameters ( char **ppin,// read-only source char **ppout,// translated result char **pps)// parameter stack { int i, n; char c; char name[128]; char *pin, *pout, *ps; //printf(" %c ", **in); pin = *ppin; pout = *ppout; ps = *pps; c = *pin; switch (c) { // types processing case 'b': strcpy (pout, "byte"); pout += 4; pin++; break; case 'c': strcpy (pout, "char"); pout += 4; pin++; break; case 'd': strcpy (pout, "double"); pout += 6; pin++; break; case 'f': strcpy (pout, "float"); pout += 5; pin++; break; case 'g': strcpy (pout, "long double"); pout += 11; pin++; break; case 'i': strcpy (pout, "int"); pout += 3; pin++; break; case 'l': strcpy (pout, "long"); pout += 4; pin++; break; case 's': strcpy (pout, "short"); pout += 5; pin++; break; case 'v': strcpy (pout, "void"); pout += 4; pin++; break; // postfix processing case 'M': case 'p': if (*(pin + 1) == 'p'){ *ps++ = 'p'; pin += 2;} else{ *ps++ = '*'; pin++;} *ppin = pin; *ppout = pout; *pps = ps; return; case 'q': *pout++ = '('; pin++; *ps++ = 'q'; *ppin = pin; *ppout = pout; *pps = ps; return; case 'r': if (*(pin + 1) == 'p'){ *ps++ = 'r'; pin += 2;} else{ *ps++ = '&'; pin++;} *ppin = pin; *ppout = pout; *pps = ps; return; // repeat processing case 't': if (isdigit (*(pin + 1))){ n = *(pin + 1) - '0'; pin++; pin++; GetPreviousParamString (pout, name); strcpy (pout, name); pout += strlen (name); for (i = 1; i < n; i++) { *pout++ = ','; strcpy (pout, name); pout += strlen (name); }} elsepin++; break; // prefix processing case 'u': strcpy (pout, "u"); pout += 1; pin++; *ppin = pin; *ppout = pout; *pps = ps; return; case 'x': strcpy (pout, "const "); pout += 6; pin++; *ppin = pin; *ppout = pout; *pps = ps; return; case 'z': strcpy (pout, "static "); pout += 7; pin++; *ppin = pin; *ppout = pout; *pps = ps; return; default: strcpy (pout, "!1!"); pout += 3; *pout++ = *pin++; *ppin = pin; *ppout = pout; *pps = ps; return; } // need to process postfix finally c = *(ps - 1); if (strchr ("tqx", c)) { if (*(pin) && !strchr ("@$%", *(pin)))*pout++ = ','; *ppin = pin; *ppout = pout; *pps = ps; return; } switch (c) { case 'r': strcpy (pout, "*&"); pout += 2; ps--; break; case 'p': strcpy (pout, "**"); pout += 2; ps--; break; case '&': strcpy (pout, "&"); pout += 1; ps--; break; case '*': strcpy (pout, "*"); pout += 1; ps--; break; default: strcpy (pout, "!2!"); pout += 3; ps--; break; } if (*(pin) && !strchr ("@$%", *(pin))) *pout++ = ','; *ppin = pin; *ppout = pout; *pps = ps;}//// This function is written by sang cho// October 11, 1997///* translate parameter part of condensed name */BOOL StringExpands (char **ppin,// read-only source char **ppout,// translated result char **pps,// parameter stack Str_P * pcstr)// currently stored string {// int n; // char c; char *pin, *pout, *ps; Str_P c_str; BOOL stringMode = TRUE; pin = *ppin; pout = *ppout; ps = *pps; c_str = *pcstr; if (strncmp (pin, "bctr", 4) == 0) { strncpy (pout, c_str.pos, c_str.length); pout += c_str.length; pin += 4; } else if (strncmp (pin, "bdtr", 4) == 0) { *pout++ = '~'; strncpy (pout, c_str.pos, c_str.length); pout += c_str.length; pin += 4; } else if (*pin == 'o') { strcpy (pout, "const "); pout += 6; pin++; stringMode = FALSE; } else if (*pin == 'q') { *pout++ = '('; pin++; *ps++ = 'q'; stringMode = FALSE; } else if (*pin == 't') { //if (*(ps-1) == 't') { *pout++ = ','; pin++; } // this also got me... //else october 12 .. sang {*pout++ = '<';pin++;*ps++ = 't'; } stringMode = FALSE; } else if (strncmp (pin, "xq", 2) == 0) { *pout++ = '('; pin += 2; *ps++ = 'x'; *ps++ = 'q'; stringMode = FALSE; } else if (strncmp (pin, "bcall", 5) == 0) { strcpy (pout, "operator ()"); pout += 11; pin += 5; } else if (strncmp (pin, "bsubs", 5) == 0) { strcpy (pout, "operator []"); pout += 11; pin += 5; } else if (strncmp (pin, "bnwa", 4) == 0) { strcpy (pout, "operator new[]"); pout += 14; pin += 4; } else if (strncmp (pin, "bdla", 4) == 0) { strcpy (pout, "operator delete[]"); pout += 17; pin += 4; } else if (strncmp (pin, "bnew", 4) == 0) { strcpy (pout, "operator new"); pout += 12; pin += 4; } else if (strncmp (pin, "bdele", 5) == 0) { strcpy (pout, "operator delete"); pout += 15; pin += 5; } else if (strncmp (pin, "blsh", 4) == 0) { strcpy (pout, "operator <<"); pout += 11; pin += 4; } else if (strncmp (pin, "brsh", 4) == 0) { strcpy (pout, "operator >>"); pout += 11; pin += 4; } else if (strncmp (pin, "binc", 4) == 0) { strcpy (pout, "operator ++"); pout += 11; pin += 4; } else if (strncmp (pin, "bdec", 4) == 0) { strcpy (pout, "operator --"); pout += 11; pin += 4; } else if (strncmp (pin, "badd", 4) == 0) { strcpy (pout, "operator +"); pout += 10; pin += 4; } else if (strncmp (pin, "brplu", 5) == 0) { strcpy (pout, "operator +="); pout += 11; pin += 5; } else if (strncmp (pin, "bdiv", 4) == 0) { strcpy (pout, "operator /"); pout += 10; pin += 4; } else if (strncmp (pin, "brdiv", 5) == 0) { strcpy (pout, "operator /="); pout += 11; pin += 5; } else if (strncmp (pin, "bmul", 4) == 0) { strcpy (pout, "operator *"); pout += 10; pin += 4; } else if (strncmp (pin, "brmul", 5) == 0) { strcpy (pout, "operator *="); pout += 11; pin += 5; } else if (strncmp (pin, "basg", 4) == 0) { strcpy (pout, "operator ="); pout += 10; pin += 4; } else if (strncmp (pin, "beql", 4) == 0) { strcpy (pout, "operator =="); pout += 11; pin += 4; } else if (strncmp (pin, "bneq", 4) == 0) { strcpy (pout, "operator !="); pout += 11; pin += 4; } else if (strncmp (pin, "bor", 3) == 0) { strcpy (pout, "operator |"); pout += 10; pin += 3; } else if (strncmp (pin, "bror", 4) == 0) { strcpy (pout, "operator |="); pout += 11; pin += 4; } else if (strncmp (pin, "bcmp", 4) == 0) { strcpy (pout, "operator ~"); pout += 10; pin += 4; } else if (strncmp (pin, "bnot", 4) == 0) { strcpy (pout, "operator !"); pout += 10; pin += 4; } else if (strncmp (pin, "band", 4) == 0) { strcpy (pout, "operator &"); pout += 10; pin += 4; } else if (strncmp (pin, "brand", 5) == 0) { strcpy (pout, "operator &="); pout += 11; pin += 5; } else if (strncmp (pin, "bxor", 4) == 0) { strcpy (pout, "operator ^"); pout += 10; pin += 4; } else if (strncmp (pin, "brxor", 5) == 0) { strcpy (pout, "operator ^="); pout += 11; pin += 5; } else { strcpy (pout, "!$$$!"); pout += 5; } *ppin = pin; *ppout = pout; *pps = ps; return stringMode;}// end of '$' processing//----------------------------------------------------------------------// structure to store string tokens//----------------------------------------------------------------------//typedef struct _Str_P {// char flag; // string_flag '@' or '%' or '#'// char *pos; // starting postion of string// int length; // length of string// BOOL wasString; // if it were stringMode or not//} Str_P;//----------------------------------------------------------------------//// I think I knocked it down finally. But who knows?// october 12, 1997 ... sang//// well I have to rewrite whole part of TranslateFunctionName..// this time I am a little bit more experienced than 5 days ago.// or am i??? anyway i use stacks instead of recurcive calls// and i hope this will take care of every symptoms i have experienced..// october 10, 1997 .... sang// It took a lot of time for me to figure out what is all about....// but still some prefixes like z (static)// -- or some types like b (byte) ,g (long double) ,s (short) --// -- or postfix like M ( * )// -- or $or ( & ) which is pretty wierd. .. added.. october 12// -- also $t business is quite tricky too. (templates)// there may be a lot of things undiscovered yet....// I am not so sure my interpretation is correct or not// If I am wrong please let me know.// october 8, 1997 .... sang////// This function is written by sang cho// October 5, 1997///* translate condesed import function name */char * TranslateFunctionName (char *psz){ int i, /*j,*/ n; char c, cc; static char buff[512];// result of translation int is = 0; char pStack[32];// parameter processing stack Str_P sStack[32];// String processing stack Str_P tok;// String token Str_P c_str;// current string int iend = 0; char *endTab[8];// end of string position check char *ps; char *pin, *pout; BOOL stringMode = TRUE; if (*psz != '@') return psz; pin = psz; pout = buff; ps = pStack; //................................................................ // serious users may need to run the following code. // so I may need to include some flag options... // If you want to know about how translation is done, // you can just revive following line and you can see it. // october 6, 1997 ... sang cho //printf ("/n................................... %s", psz); // for debugging... //pa = pb = pout; pin++; tok.flag = 'A'; tok.pos = pout; tok.length = 0; tok.wasString = stringMode; sStack[is++] = tok;// initialize sStack with dummy marker while (*pin) { while (*pin){ c = *pin; //--------------------------------------------- // check for the end of number specified string //--------------------------------------------- if (iend > 0) { for (i = 0; i < iend; i++)if (pin == endTab[i]) break; if (i < iend){ // move the end of endTab to ith position endTab[i] = endTab[iend - 1]; iend--; // get top of the string stack tok = sStack[is - 1]; // I am expecting '#' token from stack if (tok.flag != '#') { printf ("/n**some serious error1** %c is = %d char = %c", tok.flag, is, *pin); exit (0); } // pop '#' token I am happy now. else {//if (c) //printf("/n pop # token ... current char = %c", c); //else printf("/n pop percent token..next char = NULL"); is--; } stringMode = tok.wasString; if (!stringMode) { // need to process postfix finally cc = *(ps - 1); if (strchr ("qtx", cc)){ if (!strchr ("@$%", c)) *pout++ = ',';} else{ switch (cc) { case 'r': strcpy (pout, "*&"); pout += 2; ps--; break; case 'p': strcpy (pout, "**"); pout += 2; ps--; break; case '&': strcpy (pout, "&"); pout += 1; ps--; break; case '*': strcpy (pout, "*"); pout += 1; ps--; break; default: strcpy (pout, "!3!"); pout += 3; ps--; break; } if (!strchr ("@$%", c)) *pout++ = ',';} } // string mode restored... else;} else;// do nothing.. } //------------------------------------------------ // special control symbol processing: //------------------------------------------------ if (strchr ("@$%", c)) break; //--------------------------------------------------------------- // string part processing : no '$' met yet // or inside of '%' block // or inside of '#' block (numbered string) //--------------------------------------------------------------- else if (stringMode) *pout++ = *pin++; //else if (is > 1) *pout++ = *pin++; //------------------------------------------------ // parameter part processing: '$' met //------------------------------------------------ else// parameter processing { if (!isdigit (c))TranslateParameters (&pin, &pout, &ps); else// number specified string processing{ n = GetStringLength (pin); if (n < 10) pin++; else pin += 2; // push '#' token //if (*pin) //printf("/n push # token .. char = %c", *pin); //else printf("/n push percent token..next char = NULL"); tok.flag = '#'; tok.pos = pout; tok.length = 0; tok.wasString = stringMode; sStack[is++] = tok; // mark end of input string endTab[iend++] = pin + n; stringMode = TRUE;} }}// end of inner while loop // // beginning of new string or end of string ( quotation mark ) // if (c == '%'){ pin++;// anyway we have to proceed... tok = sStack[is - 1];// get top of the sStack if (tok.flag == '%') { // pop '%' token and set c_str //if (*pin) //printf("/n pop percent token..next char = %c", *pin); //else printf("/n pop percent token..next char = NULL"); is--; c_str = tok; c_str.length = pout - c_str.pos; if (*(ps - 1) == 't'){ *pout++ = '>'; ps--; stringMode = tok.wasString;} else{ printf ("/n**some string error3** stack = %c", *(ps - 1)); exit (0);} } else if (tok.flag == 'A' || tok.flag == '#') { // push '%' token //if (*pin) //printf("/n push percent token..next char = %c", *pin); //else printf("/n push percent token..next char = NULL"); tok.flag = '%'; tok.pos = pout; tok.length = 0; tok.wasString = stringMode; sStack[is++] = tok; } else { printf ("/n**some string error5**"); exit (0); }} // // sometimes we need string to use as constructor name or destructor name // else if (c == '@')// get string from previous marker upto here.{ pin++; tok = sStack[is - 1]; c_str.flag = 'S'; c_str.pos = tok.pos; c_str.length = pout - tok.pos; c_str.wasString = stringMode; *pout++ = ':'; *pout++ = ':';} // // we need to take care of parameter control sequence // else if (c == '$')// need to precess template or parameter part{ pin++; if (stringMode) stringMode = StringExpands (&pin, &pout, &ps, &c_str); else {// template parameter mode I guess "$t" if (is > 1){ if (*pin == 't') pin++; else { printf ("/nMYGOODNESS1 %c", *pin); exit (0); } //ps--; //if (*ps == 't') *pout++ = '>'; //else { printf("/nMYGOODNESS2"); exit(0);} *pout++ = ',';//pin++; ..this almost blowed me....} // real parameter mode I guess // unexpected case is found ... humm what can I do... else{ // this is newly found twist.. it really hurts. if (ps <= pStack) { if (*pin == 'q'){ *ps++ = 'q'; *pout++ = '('; pin++;} else{ printf ("/n** I GIVEUP ***"); exit (0);} continue; } ps--; while (*ps != 'q') { if (*ps == '*')*pout++ = '*'; else if (*ps == '&')*pout++ = '&'; else if (*ps == 'p'){ *pout++ = '*'; *pout++ = '*';} else if (*ps == 'r'){ *pout++ = '*'; *pout++ = '&';} else{ printf ("/n*** SOMETHING IS WRONG1*** char= %c", *pin); exit (0);} ps--; } *pout++ = ')'; ps--; while (*ps != 'q') { if (*ps == '*')*pout++ = '*'; else if (*ps == '&')*pout++ = '&'; else if (*ps == 'p'){ *pout++ = '*'; *pout++ = '*';} else if (*ps == 'r'){ *pout++ = '*'; *pout++ = '&';} else{ printf ("/n*** SOMETHING IS WRONG2***"); exit (0);} ps--; } ps++; *pout++ = ',';} }}// end of '$' processing }// end of outer while loop // // need to process remaining parameter stack // while (ps > pStack) { ps--; switch (*ps){case 't': *pout++ = '>'; break;case 'q': *pout++ = ')'; break;case 'x': strcpy (pout, " const"); pout += 6; break;case 'r': strcpy (pout, "*&"); pout += 2; break;case 'p': strcpy (pout, "**"); pout += 2; break;case '&': *pout++ = '&'; break;case '*': *pout++ = '*'; break;default: strcpy (pout, "!4!"); pout += 3; *pout++ = *ps;} } *pout = 0; return buff;}//// This function is written by sang cho/////* get exported function names separated by null terminators, return count of functions */int GetExportFunctionNames ( LPVOID lpFile, char **pszFunctions){ //PIMAGE_SECTION_HEADER psh; PIMAGE_EXPORT_DIRECTORY ped; //DWORD dwBase; DWORD imageBase;//=========================== char *pfns[8192] = {NULL,};// maximum number of functions //============================= char buff[256];// enough for any string ?? char *psz = NULL;//=============================== DWORD *pdwAddress; DWORD *pdw1; DWORD *pdwNames; WORD *pwOrd; int i, nCnt = 0, ntmp = 0; int enid = 0, ordBase = 1;// usally ordBase is 1.... int enames = 0; /* get section header and pointer to data directory for .edata section */ ped = (PIMAGE_EXPORT_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT); if (ped == NULL) return 0; // // sometimes there may be no section for idata or edata // instead rdata or data section may contain these sections .. // or even module names or function names are in different section. // so that's why we need to get actual address each time. // ...................sang cho.................. // //psh = (PIMAGE_SECTION_HEADER) //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT); //if (psh == NULL) return 0; //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress); /* determine the offset of the export function names */ pdwAddress = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfFunctions); imageBase = (DWORD) GetImageBase (lpFile); ordBase = ped->Base; if (ped->NumberOfNames > 0) { pdwNames = (DWORD *)GetActualAddress (lpFile, (DWORD) ped->AddressOfNames); pwOrd = (WORD *)GetActualAddress (lpFile, (DWORD) ped->AddressOfNameOrdinals); pdw1 = pdwAddress; /* figure out how much memory to allocate for all strings */ for (i = 0; i < (int) ped->NumberOfNames; i++){ nCnt += strlen ((char *) GetActualAddress (lpFile, *(DWORD *) pdwNames)) + 1 + 6; pdwNames++;} // get the number of unnamed functions for (i = 0; i < (int) ped->NumberOfFunctions; i++)if (*pdw1++) ntmp++; // add memory required to show unnamed functions. if (ntmp > (int) ped->NumberOfNames)nCnt += 18 * (ntmp - (int) ped->NumberOfNames); /* allocate memory for function names */ *pszFunctions = (char *) calloc (nCnt, 1); pdwNames = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfNames); /* copy string pointer to buffer */ for (i = 0; i < (int) ped->NumberOfNames; i++){ pfns[(int) (*pwOrd) + ordBase] = (char *) GetActualAddress (lpFile, *(DWORD *) pdwNames); pdwNames++; pwOrd++;} psz = *pszFunctions; } for (i = ordBase; i < (int) ped->NumberOfFunctions + ordBase; i++) { if (*pdwAddress > 0){ *(DWORD *) psz = imageBase + *pdwAddress; psz += 4; *(WORD *) psz = (WORD) (i); psz += 2; if (pfns[i]) { strcpy (psz, pfns[i]); psz += strlen (psz) + 1; } else { sprintf (buff, "ExpFn%04d()", enid++); strcpy (psz, buff); psz += 12; } enames++;} pdwAddress++; } return enames;}/* determine the total number of resources in the section */int GetNumberOfResources ( LPVOID lpFile){ PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType; PIMAGE_RESOURCE_DIRECTORY_ENTRY prde; int nCnt = 0, i; /* get root directory of resource tree */ if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL) return 0; /* set pointer to first resource type entry */ prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY)); /* loop through all resource directory entry types */ for (i = 0; i < prdRoot->NumberOfIdEntries; i++) { /* locate directory or each resource type */ prdType = (PIMAGE_RESOURCE_DIRECTORY) ((int) prdRoot + (int) prde->OffsetToData); /* mask off most significant bit of the data offset */ prdType = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType ^ 0x80000000); /* increment count of name'd and ID'd resources in directory */ nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries; /* increment to next entry */ prde++; } return nCnt;}//// This function is rewritten by sang cho/////* name each type of resource in the section */int GetListOfResourceTypes ( LPVOID lpFile, char **pszResTypes){ PIMAGE_RESOURCE_DIRECTORY prdRoot; PIMAGE_RESOURCE_DIRECTORY_ENTRY prde; char *pMem; char buff[32]; int nCnt, i; DWORD prdeName; /* get root directory of resource tree */ if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL) return 0; /* allocate enuff space to cover all types */ nCnt = prdRoot->NumberOfIdEntries * (MAXRESOURCENAME + 1); *pszResTypes = (char *) calloc (nCnt, 1); if ((pMem = *pszResTypes) == NULL) return 0; /* set pointer to first resource type entry */ prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY)); /* loop through all resource directory entry types */ for (i = 0; i < prdRoot->NumberOfIdEntries; i++) { prdeName = prde->Name; //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME)) // pMem += strlen (pMem) + 1; // // modified by ...................................Sang Cho.. // I can't user M/S provied funcitons here so I have to figure out // how to do above functions. But I can settle down with the following // code, which works pretty good for me. // if (prdeName == 1){ strcpy (pMem, "RT_CURSOR"); pMem += 10;} else if (prdeName == 2){ strcpy (pMem, "RT_BITMAP"); pMem += 10;} else if (prdeName == 3){ strcpy (pMem, "RT_ICON "); pMem += 10;} else if (prdeName == 4){ strcpy (pMem, "RT_MENU "); pMem += 10;} else if (prdeName == 5){ strcpy (pMem, "RT_DIALOG"); pMem += 10;} else if (prdeName == 6){ strcpy (pMem, "RT_STRING"); pMem += 10;} else if (prdeName == 7){ strcpy (pMem, "RT_FONTDIR"); pMem += 11;} else if (prdeName == 8){ strcpy (pMem, "RT_FONT "); pMem += 10;} else if (prdeName == 9){ strcpy (pMem, "RT_ACCELERATORS"); pMem += 16;} else if (prdeName == 10){ strcpy (pMem, "RT_RCDATA"); pMem += 10;} else if (prdeName == 11){ strcpy (pMem, "RT_MESSAGETABLE"); pMem += 16;} else if (prdeName == 12){ strcpy (pMem, "RT_GROUP_CURSOR"); pMem += 16;} else if (prdeName == 14){ strcpy (pMem, "RT_GROUP_ICON "); pMem += 16;} else if (prdeName == 16){ strcpy (pMem, "RT_VERSION"); pMem += 11;} else if (prdeName == 17){ strcpy (pMem, "RT_DLGINCLUDE "); pMem += 16;} else if (prdeName == 19){ strcpy (pMem, "RT_PLUGPLAY "); pMem += 16;} else if (prdeName == 20){ strcpy (pMem, "RT_VXD "); pMem += 10;} else if (prdeName == 21){ strcpy (pMem, "RT_ANICURSOR "); pMem += 16;} else if (prdeName == 22){ strcpy (pMem, "RT_ANIICON"); pMem += 11;} else if (prdeName == 0x2002){ strcpy (pMem, "RT_NEWBITMAP"); pMem += 13;} else if (prdeName == 0x2004){ strcpy (pMem, "RT_NEWMENU"); pMem += 11;} else if (prdeName == 0x2005){ strcpy (pMem, "RT_NEWDIALOG"); pMem += 13;} else if (prdeName == 0x7fff){ strcpy (pMem, "RT_ERROR "); pMem += 10;} else{ sprintf (buff, "RT_UNKNOWN:%08lX", prdeName); strcpy (pMem, buff); pMem += 20;} prde++; } return prdRoot->NumberOfIdEntries;}//// This function is written by sang cho// October 12, 1997///* copy menu information */void StrangeMenuFill ( char **psz,// results WORD ** pMenu,// read-only int size){ WORD *pwd; WORD *ptr, *pmax; pwd = *pMenu; pmax = (WORD *) ((DWORD) pwd + size); ptr = (WORD *) (*psz); while (pwd < pmax) { *ptr++ = *pwd++; } *psz = (char *) ptr; *pMenu = pwd;}//// This function is written by sang cho// October 1, 1997///* obtain menu information */int MenuScan ( int *len, WORD ** pMenu){ //int num = 0; //int ndetails; WORD *pwd; WORD flag, flag1; WORD id, ispopup; pwd = *pMenu; flag = *pwd;// so difficult to correctly code this so let's try this pwd++; (*len) += 2;// flag store if ((flag & 0x0010) == 0) { ispopup = flag; id = *pwd; pwd++; (*len) += 2;// id store } else { ispopup = flag; } while (*pwd) { (*len)++; pwd++; } (*len)++;// name and null character pwd++;// skip double null if ((flag & 0x0010) == 0)// normal node: done { *pMenu = pwd; return (int) flag; } // popup node: need to go on... while (1) { *pMenu = pwd; flag1 = (WORD) MenuScan (len, pMenu); pwd = *pMenu; if (flag1 & 0x0080)break; }// fill # of details to num above //(*len) += 2; *pMenu = pwd; return flag;}//// This function is written by sang cho// October 2, 1997///* copy menu information */int MenuFill ( char **psz, WORD ** pMenu){ //int num = 0; //int ndetails; char *ptr/*, *pTemp*/; WORD *pwd; WORD flag, flag1; WORD id/*, ispopup*/; ptr = *psz; pwd = *pMenu; //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags; flag = *pwd;// so difficult to correctly code this so let's try this pwd++; if ((flag & 0x0010) == 0) { *(WORD *) ptr = flag;// flag store ptr += 2; *(WORD *) ptr = id = *pwd;// id store ptr += 2; pwd++; } else { *(WORD *) ptr = flag;// flag store ptr += 2; } while (*pwd)// name extract { *ptr = *(char *) pwd; ptr++; pwd++; }//name and null character *ptr = 0; ptr++; pwd++;// skip double null if ((flag & 0x0010) == 0)// normal node: done { *pMenu = pwd; *psz = ptr; return (int) flag; } //pTemp = ptr; //ptr += 2; // popup node: need to go on... while (1) { //num++; *pMenu = pwd; *psz = ptr; flag1 = (WORD) MenuFill (psz, pMenu); pwd = *pMenu; ptr = *psz; if (flag1 & 0x0080)break; }// fill # of details to num above //*(WORD *)pTemp = (WORD)num; *pMenu = pwd; *psz = ptr; return flag;}////==============================================================================// The following program is based on preorder-tree-traversal.// once you understand how to traverse.....// the rest is pretty straight forward.// still we need to scan it first and fill it next time.// and finally we can print it.//// This function is written by sang cho// September 29, 1997// revised october 2, 1997// revised october 12, 1997// ..............................................................................// ------------------------------------------------------------------------------// I use same structure - which is used in P.E. programs - for my reporting.// So, my structure is as follows:// # of menu name is stored else where ( in directory I suppose )// supermenuname null terminated string, only ascii is considered.// flag tells : node is a leaf or a internal node.// popupname null terminated string//// flag normal menu flag (leaf node)// id normal menu id// name normal menu name// or or// flag popup menu flag (internal node)// popupname popup menu name//// flag it may folows// id normal menu id// name normal menu name// or or// flag popup menu// popupname popup menu name// .........// it goes on like this,// but usually, it only goes a few steps,...// ------------------------------------------------------------------------------/* scan menu and copy menu */int GetContentsOfMenu ( LPVOID lpFile, char **pszResTypes){ PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage; PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1; PIMAGE_RESOURCE_DIR_STRING_U pMenuName; PIMAGE_RESOURCE_DATA_ENTRY prData; //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE); PIMAGE_MENU_HEADER pMenuHeader; //PIMAGE_POPUP_MENU_ITEM pPopup; WORD* pPopup; //PIMAGE_NORMAL_MENU_ITEM pNormal; char buff[32]; int /*nCnt = 0,*/ i, j; //int num = 0; int size; int sLength, nMenus; WORD flag; WORD *pwd; //DWORD prdeName; //DWORD dwBase; obsolete char *pMem/*, *pTemp*/; //BOOL isStrange = FALSE; /* get root directory of resource tree */ if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL) return 0; /* set pointer to first resource type entry */ prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY)); for (i = 0; i < prdType->NumberOfIdEntries; i++) { if (prde->Name == RT_MENU)break; prde++; } if (prde->Name != RT_MENU) return 0; prdName = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdName == NULL) return 0; prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY)); // sometimes previous code tells you lots of things hidden underneath // I wish I could save all the revisions I made ... but again .... sigh. // october 12, 1997 sang //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress); nMenus = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries; sLength = 0; for (i = 0; i < prdName->NumberOfNamedEntries; i++) { pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD) prdType + (prde->Name ^ 0x80000000)); sLength += pMenuName->Length + 1; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; pMenuHeader = (PIMAGE_MENU_HEADER)GetActualAddress (lpFile, prData->OffsetToData); // // normally wVersion and cbHeaderSize should be zero // but if it is not then nothing is known to us... // so let's do our best ... namely guessing .... and trying .... // ... and suffering ... // it gave me many sleepless (not exactly but I like to say this) nights. // // strange case if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize){ //isStrange = TRUE; pwd = (WORD *) ((DWORD) pMenuHeader + 16); size = prData->Size; // expect to return the length needed to report. // sixteen more bytes to do something sLength += 16 + size; //StrangeMenuScan (&sLength, &pwd, size);} // normal case else{ pPopup = (WORD*) ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER)); while (1) { flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup)); if (flag & 0x0080)break; }} prde++; } for (i = 0; i < prdName->NumberOfIdEntries; i++) { sLength += 12; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; pMenuHeader = (PIMAGE_MENU_HEADER)GetActualAddress (lpFile, prData->OffsetToData); // strange case if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize){ pwd = (WORD *) ((DWORD) pMenuHeader + 16); size = prData->Size; // expect to return the length needed to report. // sixteen more bytes to do something sLength += 16 + size; //StrangeMenuScan (&sLength, &pwd, size);} // normal case else{ pPopup = (WORD*) ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER)); while (1) { flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup)); if (flag & 0x0080)break; }} prde++; } // // allocate memory for menu names // *pszResTypes = (char *) calloc (sLength, 1); pMem = *pszResTypes; // // and start all over again // prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY)); for (i = 0; i < prdName->NumberOfNamedEntries; i++) { pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD) prdType + (prde->Name ^ 0x80000000)); for (j = 0; j < pMenuName->Length; j++)*pMem++ = (char) (pMenuName->NameString[j]); *pMem = 0; pMem++; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; pMenuHeader = (PIMAGE_MENU_HEADER)GetActualAddress (lpFile, prData->OffsetToData); // strange case if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize){ pwd = (WORD *) ((DWORD) pMenuHeader); size = prData->Size; strcpy (pMem, ":::::::::::"); pMem += 12; *(int *) pMem = size; pMem += 4; StrangeMenuFill (&pMem, &pwd, size);} // normal case else{ pPopup = (WORD*) ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER)); while (1) { flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup)); if (flag & 0x0080)break; }} prde++; } for (i = 0; i < prdName->NumberOfIdEntries; i++) { sprintf (buff, "MenuId_%04lX", (prde->Name)); strcpy (pMem, buff); pMem += strlen (buff) + 1; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; pMenuHeader = (PIMAGE_MENU_HEADER)GetActualAddress (lpFile, prData->OffsetToData); // strange case if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize){ pwd = (WORD *) ((DWORD) pMenuHeader); size = prData->Size; strcpy (pMem, ":::::::::::"); pMem += 12; *(int *) pMem = size; pMem += 4; StrangeMenuFill (&pMem, &pwd, size);} // normal case else{ pPopup = (WORD*) ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER)); while (1) { flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup)); if (flag & 0x0080)break; }} prde++; } return nMenus;}//// This function is written by sang cho// October 12, 1997///* print contents of menu */int PrintStrangeMenu ( char **psz){ //int i, j, k, l; int num; //WORD flag1, flag2; //char buff[128]; char *ptr, *pmax; //return dumpMenu (psz, size); ptr = *psz; if (strncmp (ptr, ":::::::::::", 11) != 0) { printf ("/n#### I don't know why!!!"); dumpMenu (psz, 1024); exit (0); } ptr += 12; num = *(int *) ptr; ptr += 4; pmax = ptr + num; *psz = ptr; return dumpMenu (psz, num); // I will write some code later...}//// This function is written by sang cho// October 2, 1997///* print contents of menu */int PrintMenu ( int indent, char **psz){ int /*i, */ j, k, l; WORD id /*, num */ ; WORD flag; char buff[128]; char *ptr; ptr = *psz; //num = *(WORD *)ptr; //ptr += 2; while (1) { flag = *(WORD *) ptr; if (flag & 0x0010)// flag == popup{ printf ("/n/n"); for (j = 0; j < indent; j++) printf (" "); ptr += 2; printf ("%s {Popup}/n", ptr); ptr += strlen (ptr) + 1; *psz = ptr; PrintMenu (indent + 5, psz); ptr = *psz;} else// ispopup == 0{ printf ("/n"); for (j = 0; j < indent; j++) printf (" "); ptr += 2; id = *(WORD *) ptr; ptr += 2; strcpy (buff, ptr); l = strlen (ptr); ptr += l + 1; if (strchr (buff, 0x09) != NULL) { for (k = 0; k < l; k++)if (buff[k] == 0x09) break; for (j = 0; j < l - k; j++)buff[31 - j] = buff[l - j]; for (j = k; j < 32 + k - l; j++)buff[j] = 32; } if (strchr (buff, 0x08) != NULL) { for (k = 0; k < l; k++)if (buff[k] == 0x08) break; for (j = 0; j < l - k; j++)buff[31 - j] = buff[l - j]; for (j = k; j < 32 + k - l; j++)buff[j] = 32; } printf ("%s", buff); l = strlen (buff); for (j = l; j < 32; j++) printf (" "); printf ("[ID=%04Xh]", id); *psz = ptr;} if (flag & 0x0080)break; } return 0;}//// This function is written by sang cho// October 2, 1997///* the format of menu is not known so I'll do my best */int dumpMenu ( char **psz, int size){ int i, j, k, n, l, c; char buff[32]; char *ptr, *pmax; ptr = *psz; pmax = ptr + size; for (i = 0; i < (size / 16) + 1; i++) { n = 0; for (j = 0; j < 16; j++){ c = (int) (*ptr); if (c < 0) c += 256; buff[j] = c; printf ("%02X", c); ptr++; if (ptr >= pmax) break; n++; if (n % 4 == 0) printf (" ");} n++; if (n % 4 == 0)printf (" "); l = j; j++; for (; j < 16; j++){ n++; if (n % 4 == 0) printf (" "); else printf (" ");} printf (" "); for (k = 0; k < l; k++)if (isprint (c = buff[k])) printf ("%c", c);else printf ("."); printf ("/n"); if (ptr >= pmax)break; } *psz = ptr; return 0;}//// This function is written by sang cho// October 13, 1997///* scan dialog box and copy dialog box */int GetContentsOfDialog ( LPVOID lpFile, char **pszResTypes){ PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage; PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1; PIMAGE_RESOURCE_DIR_STRING_U pDialogName; PIMAGE_RESOURCE_DATA_ENTRY prData; PIMAGE_DIALOG_HEADER pDialogHeader; //PIMAGE_CONTROL_DATA pControlData; char buff[32]; int /*nCnt = 0,*/ i, j; //int num = 0; int size; int sLength, nDialogs; //WORD flag; WORD *pwd; //DWORD prdeName; char *pMem/*, *pTemp*/; //BOOL isStrange = FALSE; /* get root directory of resource tree */ if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL) return 0; /* set pointer to first resource type entry */ prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY)); for (i = 0; i < prdType->NumberOfIdEntries; i++) { if (prde->Name == RT_DIALOG)break; prde++; } if (prde->Name != RT_DIALOG) return 0; prdName = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdName == NULL) return 0; prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY)); nDialogs = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries; sLength = 0; for (i = 0; i < prdName->NumberOfNamedEntries; i++) { pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD) prdType + (prde->Name ^ 0x80000000)); sLength += pDialogName->Length + 1; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; size = prData->Size; sLength += 4 + size; prde++; } for (i = 0; i < prdName->NumberOfIdEntries; i++) { sLength += 14; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; size = prData->Size; sLength += 4 + size; prde++; } // // allocate memory for menu names // *pszResTypes = (char *) calloc (sLength, 1); pMem = *pszResTypes; // // and start all over again // prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY)); for (i = 0; i < prdName->NumberOfNamedEntries; i++) { pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)((DWORD) prdType + (prde->Name ^ 0x80000000)); for (j = 0; j < pDialogName->Length; j++)*pMem++ = (char) (pDialogName->NameString[j]); *pMem = 0; pMem++; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL)continue; prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL)continue; pDialogHeader = (PIMAGE_DIALOG_HEADER)GetActualAddress (lpFile, prData->OffsetToData); pwd = (WORD *) ((DWORD) pDialogHeader); size = prData->Size; *(int *) pMem = size; pMem += 4; StrangeMenuFill (&pMem, &pwd, size); prde++; } for (i = 0; i < prdName->NumberOfIdEntries; i++) { sprintf (buff, "DialogId_%04lX", (prde->Name)); strcpy (pMem, buff); pMem += strlen (buff) + 1; prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)((DWORD) prdType + (prde->OffsetToData ^ 0x80000000)); if (prdLanguage == NULL){ printf ("/nprdLanguage = NULL"); exit (0);} prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY)); prData = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD) prdType + prde1->OffsetToData); if (prData == NULL){ printf ("/nprData = NULL"); exit (0);} pDialogHeader = (PIMAGE_DIALOG_HEADER)GetActualAddress (lpFile, prData->OffsetToData); pwd = (WORD *) ((DWORD) pDialogHeader); size = prData->Size; *(int *) pMem = size; pMem += 4; StrangeMenuFill (&pMem, &pwd, size); prde++; } return nDialogs;}//// This function is written by sang cho// October 14, 1997///* print contents of dialog */void PrintNameOrOrdinal ( char **psz){ char *ptr; ptr = *psz; if (*(WORD *) ptr == 0xFFFF) { ptr += 2; printf ("%04X", *(WORD *) ptr); ptr += 2; } else { printf ("%c", '"'); while (*(WORD *) ptr){ printf ("%c", *ptr); ptr += 2;} ptr += 2; printf ("%c", '"'); } *psz = ptr;}//// This function is written by sang cho// October 14, 1997///* print contents of dialog */void PrintDialog ( char **psz){ int i/*, j, k, l, n, c*/; int num, size; DWORD flag; WORD class; //char buff[32]; char *ptr, *pmax; BOOL isStrange = FALSE; ptr = *psz; size = *(int *) ptr; ptr += 4; pmax = ptr + size; // IStype of Dialog Header flag = *(DWORD *) ptr; // // check if flag is right or not // it has been observed that some dialog information is strange // and extra work is needed to fix that ... so let's try something // if ((flag & 0xFFFF0000) == 0xFFFF0000) { flag = *(DWORD *) (ptr + 12); num = *(short *) (ptr + 16); isStrange = TRUE; ptr += 26; } else { num = *(short *) (ptr + 8); ptr += 18; } printf (", # of Controls=%03d, Caption:%c", num, '"'); // Menu name if (*(WORD *) ptr == 0xFFFF) ptr += 4;// ordinal else { while (*(WORD *) ptr)ptr += 2; ptr += 2; }// name // Class name if (*(WORD *) ptr == 0xFFFF) ptr += 4;// ordinal else { while (*(WORD *) ptr)ptr += 2; ptr += 2; }// name // Caption while (*(WORD *) ptr) { printf ("%c", *ptr); ptr += 2; } ptr += 2; printf ("%c", '"'); // FONT present if (flag & 0x00000040) { if (isStrange)ptr += 6; elseptr += 2;// FONT size while (*(WORD *) ptr)ptr += 2;// WCHARs ptr += 2;// double null } // strange case adjust if (isStrange) ptr += 8; // DWORD padding if ((ptr - *psz) % 4) ptr += 4 - ((ptr - *psz) % 4); // start reporting .. finally for (i = 0; i < num; i++) { flag = *(DWORD *) ptr; if (isStrange)ptr += 14; elseptr += 16; printf ("/n Control::%03d - ID:", i + 1); // Control ID printf ("%04X, Class:", *(WORD *) ptr); ptr += 2; // Control Class if (*(WORD *) ptr == 0xFFFF){ ptr += 2; class = *(WORD *) ptr; ptr += 2; switch (class) { case 0x80: printf ("BUTTON "); break; case 0x81: printf ("EDIT "); break; case 0x82: printf ("STATIC "); break; case 0x83: printf ("LISTBOX "); break; case 0x84: printf ("SCROLLBAR"); break; case 0x85: printf ("COMBOBOX "); break; default: printf ("%04X ", class); break; }} elsePrintNameOrOrdinal (&ptr); printf (" Text:"); // Text PrintNameOrOrdinal (&ptr); // nExtraStuff ptr += 2; // strange case adjust if (isStrange)ptr += 8; // DWORD padding if ((ptr - *psz) % 4)ptr += 4 - ((ptr - *psz) % 4); } /* ptr = *psz; printf("/n"); for (i=0; i<(size/16)+1; i++) { n = 0; for (j=0; j<16; j++) { c = (int)(*ptr); if (c<0) c+=256; buff[j] = c; printf ("%02X",c); ptr++; if (ptr >= pmax) break; n++; if (n%4 == 0) printf (" "); } n++; if (n%4 == 0) printf (" "); l = j; j++; for (; j<16; j++) { n++; if (n%4 == 0) printf (" "); else printf (" "); } printf (" "); for (k=0; k<l; k++) if (isprint(c=buff[k])) printf("%c", c); else printf("."); printf ("/n"); if (ptr >= pmax) break; } */ *psz = pmax;}/* function indicates whether debug info has been stripped from file */BOOL IsDebugInfoStripped ( LPVOID lpFile){ PIMAGE_FILE_HEADER pfh; pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile); return (pfh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED);}/* retrieve the module name from the debug misc. structure */int RetrieveModuleName ( LPVOID lpFile, char **pszModule){ PIMAGE_DEBUG_DIRECTORY pdd; PIMAGE_DEBUG_MISC pdm = NULL; int nCnt; if (!(pdd = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_DEBUG))) return 0; while (pdd->SizeOfData) { if (pdd->Type == IMAGE_DEBUG_TYPE_MISC){ pdm = (PIMAGE_DEBUG_MISC) ((DWORD) pdd->PointerToRawData + (DWORD) lpFile); *pszModule = (char *) calloc ((nCnt = (strlen ((char *)pdm->Data))) + 1, 1); // may need some unicode business here...above bcopy (pdm->Data, *pszModule, nCnt); break;} pdd++; } if (pdm != NULL) return nCnt; else return 0;}/* determine if this is a valid debug file */BOOL IsDebugFile ( LPVOID lpFile){ PIMAGE_SEPARATE_DEBUG_HEADER psdh; psdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile; return (psdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE);}/* copy separate debug header structure from debug file */BOOL GetSeparateDebugHeader ( LPVOID lpFile, PIMAGE_SEPARATE_DEBUG_HEADER psdh){ PIMAGE_SEPARATE_DEBUG_HEADER pdh; pdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile; if (pdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE) { bcopy ((LPVOID) pdh, (LPVOID) psdh, sizeof (IMAGE_SEPARATE_DEBUG_HEADER)); return TRUE; } return FALSE;}//// I tried to immitate the output of w32dasm disassembler.// which is a pretty good program.// but I am disappointed with this program and I myself// am writting a disassembler.// This PEdump program is a byproduct of that project.// so enjoy this program and I hope we will have a little more// knowledge on windows programming world.// .... sang cho#define MAXSECTIONNUMBER 16#define MAXNAMESTRNUMBER 40intmain ( int argc, char **argv){ DWORD fileType; LPVOID lpFile; FILE *my_fp; IMAGE_DOS_HEADER dosHdr; PIMAGE_FILE_HEADER pfh; PIMAGE_OPTIONAL_HEADER poh; PIMAGE_SECTION_HEADER psh; //IMAGE_SECTION_HEADER idsh; IMAGE_SECTION_HEADER shdr[MAXSECTIONNUMBER]; //PIMAGE_IMPORT_MODULE_DIRECTORY pid; int nSections;// number of sections int nResources;// number of resources int nMenus;// number of menus int nDialogs;// number of dialogs int nImportedModules;// number of imported modules int nFunctions;// number of functions in the imported module int nExportedFunctions;// number of exported funcions int imageBase; int entryPoint; /** TESTING **/ int sizeofimage; int timedatestamp; int entrypoint; /** END TESTING **/ int i, j, /*k,*/ n; //int mnsize; //int nCnt; //int nSize; int fsize; char *pnstr; char *pst; char *piNameBuff;// import module name buffer char *pfNameBuff;// import functions in the module name buffer char *peNameBuff;// export function name buffer char *pmNameBuff;// menu name buffer char *pdNameBuff;// dialog name buffer /* * Check user arguments. */ if (2 == argc) { my_fp = fopen (argv[1], "rb"); if (my_fp == NULL){ printf ( "%s: can not open input file /"%s/"./n", argv[0], argv[1] ); exit (0);} } else { printf ( "%s - PE/COFF file dumper/n" "Copyright (c) 1993 Randy Kath (MSDN Technology Group)/n" "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)/n" "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)/n" "Copyright (c) 2006 Quiet Earth http://www.quietearth.us/n/n", argv[0]); printf ( "usage: %s input_file_name/n", argv[0]); exit (0); } /* * Get input file's size. */ /* argv [0], */ fseek (my_fp, 0L, SEEK_END); fsize = ftell (my_fp); rewind (my_fp); /* * Buffer the file in memory. */ lpFile = (void *) calloc (fsize, 1); if (lpFile == NULL) { printf ( "%s: can not allocate memory./n", argv[0]); exit (0); } /* * --- Start of report --- */ printf ("/n/nDump of file: %s/n/n", argv[1]); n = fread (lpFile, fsize, 1, my_fp); if (n == -1) { printf ( "%s: failed to read the file /"%s/"./n", argv[0], argv[1]); exit (0); } GetDosHeader (lpFile, &dosHdr); if ((WORD) IMAGE_DOS_SIGNATURE == dosHdr.e_magic) { if ((dosHdr.e_lfanew > 4096) || (dosHdr.e_lfanew < 64)){ printf ( "%s: This file is not in PE format; it looks like in DOS format./n", argv[0] ); exit (0);} } else { printf ("%s: This doesn't look like an executable file (magic = 0x%04x)./n", argv[0], dosHdr.e_magic); exit (0); } fileType = ImageFileType (lpFile); if (fileType != IMAGE_NT_SIGNATURE) { printf ( "%s: This file is not in PE format (magic = 0x%08lx)./n", argv[0], fileType); exit (0); } //===================================== // now we can really start processing //===================================== pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile); poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile); psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile); nSections = pfh->NumberOfSections; imageBase = poh->ImageBase; entryPoint = poh->AddressOfEntryPoint; if (psh == NULL) return 0; /* store section headers */ for (i = 0; i < nSections; i++ ) { shdr[i] = *psh++; } /* * Get Code offset and size, * Data offset and size. */ for (i = 0; i < nSections; i++ ) { if (poh->BaseOfCode == shdr[i].VirtualAddress){printf ("/"Size of Code: %08lX/"/n", shdr[i].SizeOfRawData); printf ( "Code Offset = %08lX, Code Size = %08lX /n", shdr[i].PointerToRawData, shdr[i].SizeOfRawData );} if (((shdr[i].Characteristics) & 0xC0000040) == 0xC0000040){ printf ( "Data Offset = %08lX, Data Size = %08lX /n", shdr[i].PointerToRawData, shdr[i].SizeOfRawData ); break;} } printf ("/n"); printf ( "Number of Objects = %04d (dec), Imagebase = %08Xh /n", nSections, imageBase ); /** TESTING **/ sizeofimage = poh->SizeOfImage; printf("/"Size of Image: %08X/"/n", sizeofimage); timedatestamp = pfh->TimeDateStamp; printf("/"Time Date Stamp: %08X/"/n", timedatestamp); printf("/"Entry Point: %08X/"/n", entryPoint); /** END TESTING **/ /* * Object name alignment. */ for (i = 0; i < nSections; i++ ) { for (j = 0; j < 7; j++){ if (shdr[i].Name[j] == 0) { shdr[i].Name[j] = 32; }} shdr[i].Name[7] = 0; } for (i = 0; i < nSections; i++) printf ("/n Object%02d: %8s RVA: %08lX Offset: %08lX Size: %08lX Flags: %08lX ", i + 1, shdr[i].Name, shdr[i].VirtualAddress, shdr[i].PointerToRawData, shdr[i].SizeOfRawData, shdr[i].Characteristics); /* * Get List of Resources. */ nResources = GetListOfResourceTypes (lpFile, &pnstr); pst = pnstr; printf ("/n"); printf ("/n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++"); printf ("/n"); if (nResources == 0) printf ("/n There are no Resources in This Application./n"); else { printf ("/nNumber of Resource Types = %4d (decimal)/n", nResources); for (i = 0; i < nResources; i++){ printf ("/n Resource Type %03d: %s", i + 1, pst); pst += strlen ((char *) (pst)) + 1;} free ((void *) pnstr); printf ("/n"); printf ("/n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++"); printf ("/n"); nMenus = GetContentsOfMenu (lpFile, &pmNameBuff); if (nMenus == 0){ printf ("/n There are no Menus in This Application./n");} else{ pst = pmNameBuff; printf ("/nNumber of Menus = %4d (decimal)", nMenus); //dumpMenu(&pst, 8096); for (i = 0; i < nMenus; i++) { // menu ID print printf ("/n/n%s", pst); pst += strlen (pst) + 1; printf ("/n-------------"); if (strncmp (pst, ":::::::::::", 11) == 0){ printf ("/n"); PrintStrangeMenu (&pst);} else{ PrintMenu (6, &pst);} //else PrintStrangeMenu(&pst); } free ((void *) pmNameBuff); printf ("/n");} printf ("/n"); printf ("/n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++"); printf ("/n"); nDialogs = GetContentsOfDialog (lpFile, &pdNameBuff); if (nDialogs == 0){ printf ("/n There are no Dialogs in This Application./n");} else{ pst = pdNameBuff; printf ("/nNumber of Dialogs = %4d (decimal)", nDialogs); printf ("/n"); for (i = 0; i < nDialogs; i++) { // Dialog ID print printf ("/nName: %s", pst); pst += strlen (pst) + 1; PrintDialog (&pst); } free ((void *) pdNameBuff); printf ("/n");} } printf ("/n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++"); nImportedModules = GetImportModuleNames (lpFile, &piNameBuff); if (nImportedModules == 0) { printf ("/n There are no imported Functions in This Application./n"); } else { pnstr = piNameBuff; printf ("/nNumber of Imported Modules = %4d (decimal)/n", nImportedModules); for (i = 0; i < nImportedModules; i++){ printf ("/n Import Module %03d: %s", i + 1, pnstr); pnstr += strlen ((char *) (pnstr)) + 1;} printf ("/n"); printf ("/n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++"); pnstr = piNameBuff; for (i = 0; i < nImportedModules; i++){ printf ("/n/n Import Module %03d: %s /n", i + 1, pnstr); nFunctions = GetImportFunctionNamesByModule (lpFile, pnstr, &pfNameBuff); pnstr += strlen ((char *) (pnstr)) + 1; pst = pfNameBuff; for (j = 0; j < nFunctions; j++) { printf ("/nAddr:%08X hint(%04X) Name: %s", (*(int *) pst), (*(short *) (pst + 4)), //(pst+6)); TranslateFunctionName (pst + 6)); pst += strlen ((char *) (pst + 6)) + 1 + 6; } free ((void *) pfNameBuff);} free ((void *) piNameBuff); } printf ("/n"); printf ("/n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++"); nExportedFunctions = GetExportFunctionNames (lpFile, &peNameBuff); printf ("/nNumber of Exported Functions = %4d (decimal)/n", nExportedFunctions); if (nExportedFunctions > 0) { pst = peNameBuff; for (i = 0; i < nExportedFunctions; i++){ printf ("/nAddr:%08X Ord:%4d (%04Xh) Name: %s", (*(int *) pst), (*(WORD *) (pst + 4)), (*(WORD *) (pst + 4)), //(pst+6)); TranslateFunctionName (pst + 6)); pst += strlen ((char *) (pst + 6)) + 6 + 1;} free ((void *) peNameBuff); } free ((void *) lpFile); return 0;}/* EOF */
0 0
- pedump.c
- pedump.c
- 分享一个自己用Java写的 PEdump 字节码查看器
- 之前写的 PEdump 的改进版,添加了停止和继续
- c
- c
- c
- c
- C
- c
- c
- c
- C+
- c
- C
- c
- c
- c
- Linux中tty、pty、pts的概念区别
- 为什么工厂模式是华而不实的—浅谈工厂模式的利与弊
- 一个GRIDVIEW控件如何绑定两张不同的表
- dos命令及java简介
- Java多线程与并发库高级应用之倒计时计数器CountDownLatch
- pedump.c
- Web自动化测试(3): Selenium Web Driver 如何操作web页面。
- NSMutableAttributeString
- TranslateAnimation详解
- Eclipse快捷键 10个最有用的快捷键
- Builder 模式
- 关于Jpcap的配置问题
- 服务器负载均衡的部署方式
- 直接运行内存中的程序