--- /dev/null
+// $Id: pedump.c,v 1.1 2001/01/13 18:19:23 ea Exp $
+//
+// 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.
+//
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <setjmp.h>
+#include <malloc.h>
+
+#ifndef bcopy
+#define bcopy(s,d,z) memcpy((d),(s),(z))
+#endif
+
+typedef 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 WINAPI __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 // PE00
+
+typedef 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 8
+
+typedef 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 8
+
+
+typedef 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_SIGNATURE sizeof (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 WINAPI GetDosHeader (LPVOID, PIMAGE_DOS_HEADER);
+DWORD WINAPI ImageFileType (LPVOID);
+BOOL WINAPI GetPEFileHeader (LPVOID, PIMAGE_FILE_HEADER);
+
+/* PE optional header info */
+BOOL WINAPI GetPEOptionalHeader (LPVOID, PIMAGE_OPTIONAL_HEADER);
+LPVOID WINAPI GetModuleEntryPoint (LPVOID);
+int WINAPI NumOfSections (LPVOID);
+LPVOID WINAPI GetImageBase (LPVOID);
+LPVOID WINAPI ImageDirectoryOffset (LPVOID, DWORD);
+LPVOID WINAPI ImageDirectorySection (LPVOID, DWORD);
+
+/* PE section header info */
+//int WINAPI GetSectionNames (LPVOID, HANDLE, char **);
+int WINAPI GetSectionNames (LPVOID, char **);
+BOOL WINAPI 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 WINAPI GetImportModuleNames (LPVOID, char **);
+int WINAPI GetImportFunctionNamesByModule (LPVOID, char *, char **);
+
+// import function name reporting
+int WINAPI GetStringLength (char *);
+void WINAPI GetPreviousParamString (char *, char *);
+void WINAPI TranslateParameters (char **, char **, char **);
+BOOL WINAPI StringExpands (char **, char **, char **, Str_P *);
+LPVOID WINAPI TranslateFunctionName (char *);
+
+/* export section info */
+int WINAPI GetExportFunctionNames (LPVOID, char **);
+
+/* resource section info */
+int WINAPI GetNumberOfResources (LPVOID);
+int WINAPI GetListOfResourceTypes (LPVOID, char **);
+int WINAPI MenuScan (int *, WORD **);
+int WINAPI MenuFill (char **, WORD **);
+void WINAPI StrangeMenuFill (char **, WORD **, int);
+int WINAPI GetContentsOfMenu (LPVOID, char **);
+int WINAPI PrintMenu (int, char **);
+int WINAPI PrintStrangeMenu (char **);
+int WINAPI dumpMenu (char **psz, int size);
+
+/* debug section info */
+BOOL WINAPI IsDebugInfoStripped (LPVOID);
+int WINAPI RetrieveModuleName (LPVOID, char **);
+BOOL WINAPI IsDebugFile (LPVOID);
+BOOL WINAPI GetSeparateDebugHeader (LPVOID, PIMAGE_SEPARATE_DEBUG_HEADER);
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ * Copy DOS header information to structure.
+ *
+ * ARGUMENTS
+ */
+BOOL WINAPI
+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 WINAPI
+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;
+
+ else
+ return IMAGE_DOS_SIGNATURE;
+ }
+
+ else
+ /* unknown file type */
+ return 0;
+}
+
+
+
+
+/* copy file header information to structure */
+BOOL WINAPI
+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 WINAPI
+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 WINAPI
+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 WINAPI
+NumOfSections (
+ LPVOID lpFile)
+{
+ /* number os sections is indicated in file header */
+ return ((int) ((PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile))->NumberOfSections);
+}
+
+
+
+
+/* retrieve entry point */
+LPVOID WINAPI
+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 WINAPI
+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 == NULL)
+ 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 WINAPI
+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 WINAPI
+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 (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, psh[i].Name);
+ ps += strlen (psh[i].Name) + 1;
+ }
+
+ return nCnt;
+}
+
+
+
+
+/* function gets the function header for a section identified by name */
+BOOL WINAPI
+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 (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 WINAPI
+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 WINAPI
+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;
+ else
+ nSize += 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 WINAPI
+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 WINAPI
+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 WINAPI
+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);
+ }
+ }
+ else
+ pin++;
+ 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 WINAPI
+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 */
+LPVOID WINAPI
+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 WINAPI
+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; //===============================
+
+ 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 WINAPI
+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 WINAPI
+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:%08X", prdeName);
+ strcpy (pMem, buff);
+ pMem += 20;
+ }
+ prde++;
+ }
+
+ return prdRoot->NumberOfIdEntries;
+}
+
+
+
+//
+// This function is written by sang cho
+// October 12, 1997
+//
+/* copy menu information */
+void WINAPI
+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 WINAPI
+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 WINAPI
+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 WINAPI
+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;
+ 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 = (PIMAGE_POPUP_MENU_ITEM)
+ ((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 = (PIMAGE_POPUP_MENU_ITEM)
+ ((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 = (PIMAGE_POPUP_MENU_ITEM)
+ ((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_%04X", (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 = (PIMAGE_POPUP_MENU_ITEM)
+ ((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 WINAPI
+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 WINAPI
+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 WINAPI
+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 WINAPI
+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_%04X", (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 */
+int WINAPI
+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 */
+int WINAPI
+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;
+ else
+ ptr += 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;
+ else
+ ptr += 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;
+ }
+ }
+ else
+ PrintNameOrOrdinal (&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 WINAPI
+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 WINAPI
+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 (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 WINAPI
+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 WINAPI
+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 40
+int
+main (
+ 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;
+
+ 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\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%08x).\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 (
+ "Code Offset = %08X, Code Size = %08X \n",
+ shdr[i].PointerToRawData,
+ shdr[i].SizeOfRawData
+ );
+ }
+ if (((shdr[i].Characteristics) & 0xC0000040) == 0xC0000040)
+ {
+ printf (
+ "Data Offset = %08X, Data Size = %08X \n",
+ shdr[i].PointerToRawData,
+ shdr[i].SizeOfRawData
+ );
+ break;
+ }
+ }
+
+ printf ("\n");
+
+ printf (
+ "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
+ nSections,
+ imageBase
+ );
+ /*
+ * 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: %08X Offset: %08X Size: %08X Flags: %08X ",
+ 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 */