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
原创粉丝点击