2 // This program was written by Sang Cho, assistant professor at
4 // computer science and engineering
6 // this program is based on the program pefile.c
7 // which is written by Randy Kath(Microsoft Developmer Network Technology Group)
9 // I have investigated P.E. file format as thoroughly as possible,
10 // but I cannot claim that I am an expert yet, so some of its information
11 // may give you wrong results.
15 // language used: djgpp
16 // date of creation: September 28, 1997
18 // date of first release: October 15, 1997
21 // you can contact me: e-mail address: sangcho@alpha94.chongju.ac.kr
23 // phone number: (0431) 229-8491 +82-431-229-8491
27 // Copyright (C) 1997. by Sang Cho.
29 // Permission is granted to make and distribute verbatim copies of this
30 // program provided the copyright notice and this permission notice are
31 // preserved on all copies.
34 // File: pedump.c ( I included header file into source file. )
37 // Sources released under GNU General Public License version 2
38 // or later by Mr. Sang Cho permission.
41 // 2000-04-23 (ea) Initial adaptation to GCC/MinGW/ROS.
42 // 2000-08-05 (ea) Initial raw adaptation done.
54 #define bcopy(s,d,z) memcpy((d),(s),(z))
61 typedef unsigned short USHORT
;
62 typedef unsigned long DWORD
;
64 typedef unsigned char BYTE
;
65 typedef unsigned short WORD
;
68 typedef DWORD
*PDWORD
;
73 #define BOOLEAN boolean
82 #define LOWORD(l) ((WORD)(l))
83 #define WINAPI __stdcall
89 #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
90 #define IMAGE_OS2_SIGNATURE 0x454E // NE
91 #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
92 #define IMAGE_VXD_SIGNATURE 0x454C // LE
93 #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
95 typedef struct _IMAGE_DOS_HEADER
98 WORD e_magic
; // Magic number
100 WORD e_cblp
; // Bytes on last page of file
102 WORD e_cp
; // Pages in file
104 WORD e_crlc
; // Relocations
106 WORD e_cparhdr
; // Size of header in paragraphs
108 WORD e_minalloc
; // Minimum extra paragraphs needed
110 WORD e_maxalloc
; // Maximum extra paragraphs needed
112 WORD e_ss
; // Initial (relative) SS value
114 WORD e_sp
; // Initial SP value
116 WORD e_csum
; // Checksum
118 WORD e_ip
; // Initial IP value
120 WORD e_cs
; // Initial (relative) CS value
122 WORD e_lfarlc
; // File address of relocation table
124 WORD e_ovno
; // Overlay number
126 WORD e_res
[4]; // Reserved words
128 WORD e_oemid
; // OEM identifier (for e_oeminfo)
130 WORD e_oeminfo
; // OEM information; e_oemid specific
132 WORD e_res2
[10]; // Reserved words
134 LONG e_lfanew
; // File address of new exe header
137 IMAGE_DOS_HEADER
, *PIMAGE_DOS_HEADER
;
140 // File header format.
145 typedef struct _IMAGE_FILE_HEADER
148 WORD NumberOfSections
;
150 DWORD PointerToSymbolTable
;
151 DWORD NumberOfSymbols
;
152 WORD SizeOfOptionalHeader
;
153 WORD Characteristics
;
155 IMAGE_FILE_HEADER
, *PIMAGE_FILE_HEADER
;
157 #define IMAGE_SIZEOF_FILE_HEADER 20
159 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
160 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
161 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
162 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
163 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
164 #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
165 #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
166 #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
167 #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
168 #define IMAGE_FILE_SYSTEM 0x1000 // System File.
169 #define IMAGE_FILE_DLL 0x2000 // File is a DLL.
170 #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
171 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
173 #define IMAGE_FILE_MACHINE_UNKNOWN 0
174 #define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
175 #define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0x160 big-endian
176 #define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
177 #define IMAGE_FILE_MACHINE_R10000 0x168 // MIPS little-endian
178 #define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
179 #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
187 typedef struct _IMAGE_DATA_DIRECTORY
189 DWORD VirtualAddress
;
193 IMAGE_DATA_DIRECTORY
, *PIMAGE_DATA_DIRECTORY
;
195 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
198 // Optional header format.
201 typedef struct _IMAGE_OPTIONAL_HEADER
207 BYTE MajorLinkerVersion
;
208 BYTE MinorLinkerVersion
;
210 DWORD SizeOfInitializedData
;
211 DWORD SizeOfUninitializedData
;
212 DWORD AddressOfEntryPoint
;
217 // NT additional fields.
221 DWORD SectionAlignment
;
223 WORD MajorOperatingSystemVersion
;
224 WORD MinorOperatingSystemVersion
;
225 WORD MajorImageVersion
;
226 WORD MinorImageVersion
;
227 WORD MajorSubsystemVersion
;
228 WORD MinorSubsystemVersion
;
229 DWORD Win32VersionValue
;
234 WORD DllCharacteristics
;
235 DWORD SizeOfStackReserve
;
236 DWORD SizeOfStackCommit
;
237 DWORD SizeOfHeapReserve
;
238 DWORD SizeOfHeapCommit
;
240 DWORD NumberOfRvaAndSizes
;
241 IMAGE_DATA_DIRECTORY DataDirectory
[IMAGE_NUMBEROF_DIRECTORY_ENTRIES
];
244 IMAGE_OPTIONAL_HEADER
, *PIMAGE_OPTIONAL_HEADER
;
247 typedef struct _IMAGE_NT_HEADERS
250 IMAGE_FILE_HEADER FileHeader
;
251 IMAGE_OPTIONAL_HEADER OptionalHeader
;
254 IMAGE_NT_HEADERS
, *PIMAGE_NT_HEADERS
;
259 #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
260 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
261 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
262 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
263 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
264 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
265 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
266 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
267 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
268 #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
269 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
270 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
271 #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
274 // Section header format.
277 #define IMAGE_SIZEOF_SHORT_NAME 8
279 typedef struct _IMAGE_SECTION_HEADER
281 BYTE Name
[IMAGE_SIZEOF_SHORT_NAME
];
284 DWORD PhysicalAddress
;
288 DWORD VirtualAddress
;
290 DWORD PointerToRawData
;
291 DWORD PointerToRelocations
;
292 DWORD PointerToLinenumbers
;
293 WORD NumberOfRelocations
;
294 WORD NumberOfLinenumbers
;
295 DWORD Characteristics
;
298 IMAGE_SECTION_HEADER
, *PIMAGE_SECTION_HEADER
;
300 #define IMAGE_SIZEOF_SECTION_HEADER 40
307 typedef struct _IMAGE_EXPORT_DIRECTORY
309 DWORD Characteristics
;
315 DWORD NumberOfFunctions
;
317 PDWORD
*AddressOfFunctions
;
318 PDWORD
*AddressOfNames
;
319 PWORD
*AddressOfNameOrdinals
;
322 IMAGE_EXPORT_DIRECTORY
, *PIMAGE_EXPORT_DIRECTORY
;
328 typedef struct _IMAGE_IMPORT_BY_NAME
334 IMAGE_IMPORT_BY_NAME
, *PIMAGE_IMPORT_BY_NAME
;
336 #define IMAGE_ORDINAL_FLAG 0x80000000
337 #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
345 // Resource directory consists of two counts, following by a variable length
346 // array of directory entries. The first count is the number of entries at
347 // beginning of the array that have actual names associated with each entry.
348 // The entries are in ascending order, case insensitive strings. The second
349 // count is the number of entries that immediately follow the named entries.
350 // This second count identifies the number of entries that have 16-bit integer
351 // Ids as their name. These entries are also sorted in ascending order.
353 // This structure allows fast lookup by either name or number, but for any
354 // given resource entry only one form of lookup is supported, not both.
355 // This is consistant with the syntax of the .RC file and the .RES file.
358 // Predefined resource types ... there may be some more, but I don't have
359 // the information yet. .....sang cho.....
361 #define RT_NEWRESOURCE 0x2000
362 #define RT_ERROR 0x7fff
371 #define RT_ACCELERATORS 9
373 #define RT_MESSAGETABLE 11
374 #define RT_GROUP_CURSOR 12
375 #define RT_GROUP_ICON 14
376 #define RT_VERSION 16
377 #define NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)
378 #define NEWMENU (RT_MENU|RT_NEWRESOURCE)
379 #define NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)
382 typedef struct _IMAGE_RESOURCE_DIRECTORY
384 DWORD Characteristics
;
388 WORD NumberOfNamedEntries
;
389 WORD NumberOfIdEntries
;
390 // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1];
393 IMAGE_RESOURCE_DIRECTORY
, *PIMAGE_RESOURCE_DIRECTORY
;
395 #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
396 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
399 // Each directory contains the 32-bit Name of the entry and an offset,
400 // relative to the beginning of the resource directory of the data associated
401 // with this directory entry. If the name of the entry is an actual text
402 // string instead of an integer Id, then the high order bit of the name field
403 // is set to one and the low order 31-bits are an offset, relative to the
404 // beginning of the resource directory of the string, which is of type
405 // IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the
406 // low-order 16-bits are the integer Id that identify this resource directory
407 // entry. If the directory entry is yet another resource directory (i.e. a
408 // subdirectory), then the high order bit of the offset field will be
409 // set to indicate this. Otherwise the high bit is clear and the offset
410 // field points to a resource data entry.
413 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
419 IMAGE_RESOURCE_DIRECTORY_ENTRY
, *PIMAGE_RESOURCE_DIRECTORY_ENTRY
;
422 // For resource directory entries that have actual string names, the Name
423 // field of the directory entry points to an object of the following type.
424 // All of these string objects are stored together after the last resource
425 // directory entry and before the first resource data object. This minimizes
426 // the impact of these variable length objects on the alignment of the fixed
427 // size directory entry objects.
430 typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING
436 IMAGE_RESOURCE_DIRECTORY_STRING
, *PIMAGE_RESOURCE_DIRECTORY_STRING
;
439 typedef struct _IMAGE_RESOURCE_DIR_STRING_U
445 IMAGE_RESOURCE_DIR_STRING_U
, *PIMAGE_RESOURCE_DIR_STRING_U
;
449 // Each resource data entry describes a leaf node in the resource directory
450 // tree. It contains an offset, relative to the beginning of the resource
451 // directory of the data for the resource, a size field that gives the number
452 // of bytes of data at that offset, a CodePage that should be used when
453 // decoding code point values within the resource data. Typically for new
454 // applications the code page would be the unicode code page.
457 typedef struct _IMAGE_RESOURCE_DATA_ENTRY
465 IMAGE_RESOURCE_DATA_ENTRY
, *PIMAGE_RESOURCE_DATA_ENTRY
;
468 // Menu Resources ... added by .....sang cho....
470 // Menu resources are composed of a menu header followed by a sequential list
471 // of menu items. There are two types of menu items: pop-ups and normal menu
472 // itmes. The MENUITEM SEPARATOR is a special case of a normal menu item with
473 // an empty name, zero ID, and zero flags.
475 typedef struct _IMAGE_MENU_HEADER
477 WORD wVersion
; // Currently zero
479 WORD cbHeaderSize
; // Also zero
482 IMAGE_MENU_HEADER
, *PIMAGE_MENU_HEADER
;
484 typedef struct _IMAGE_POPUP_MENU_ITEM
490 IMAGE_POPUP_MENU_ITEM
, *PIMAGE_POPUP_MENU_ITEM
;
492 typedef struct _IMAGE_NORMAL_MENU_ITEM
499 IMAGE_NORMAL_MENU_ITEM
, *PIMAGE_NORMAL_MENU_ITEM
;
501 #define GRAYED 0x0001 // GRAYED keyword
502 #define INACTIVE 0x0002 // INACTIVE keyword
503 #define BITMAP 0x0004 // BITMAP keyword
504 #define OWNERDRAW 0x0100 // OWNERDRAW keyword
505 #define CHECKED 0x0008 // CHECKED keyword
506 #define POPUP 0x0010 // used internally
507 #define MENUBARBREAK 0x0020 // MENUBARBREAK keyword
508 #define MENUBREAK 0x0040 // MENUBREAK keyword
509 #define ENDMENU 0x0080 // used internally
512 // Dialog Box Resources .................. added by sang cho.
514 // A dialog box is contained in a single resource and has a header and
515 // a portion repeated for each control in the dialog box.
516 // The item DWORD IStyle is a standard window style composed of flags found
518 // The default style for a dialog box is:
519 // WS_POPUP | WS_BORDER | WS_SYSMENU
521 // The itme marked "Name or Ordinal" are :
522 // If the first word is an 0xffff, the next two bytes contain an ordinal ID.
523 // Otherwise, the first one or more WORDS contain a double-null-terminated string.
524 // An empty string is represented by a single WORD zero in the first location.
526 // The WORD wPointSize and WCHAR szFontName entries are present if the FONT
527 // statement was included for the dialog box. This can be detected by checking
528 // the entry IStyle. If IStyle & DS_SETFONT ( which is 0x40), then these
529 // entries will be present.
531 typedef struct _IMAGE_DIALOG_BOX_HEADER1
534 DWORD IExtendedStyle
; // New for Windows NT
536 WORD nControls
; // Number of Controls
542 // N_OR_O MenuName; // Name or Ordinal ID
543 // N_OR_O ClassName; // Name or Ordinal ID
544 // WCHAR szCaption[];
545 // WORD wPointSize; // Only here if FONT set for dialog
546 // WCHAR szFontName[]; // This too
548 IMAGE_DIALOG_HEADER
, *PIMAGE_DIALOG_HEADER
;
550 typedef union _NAME_OR_ORDINAL
551 { // Name or Ordinal ID
561 NAME_OR_ORDINAL
, *PNAME_OR_ORDINAL
;
563 // The data for each control starts on a DWORD boundary (which may require
564 // some padding from the previous control), and its format is as follows:
566 typedef struct _IMAGE_CONTROL_DATA
569 DWORD IExtendedStyle
;
579 IMAGE_CONTROL_DATA
, *PIMAGE_CONTROL_DATA
;
585 #define SCROLLBAR 0x84
586 #define COMBOBOX 0x85
588 // The various statements used in a dialog script are all mapped to these
589 // classes along with certain modifying styles. The values for these styles
590 // can be found in WINDOWS.H. All dialog controls have the default styles
591 // of WS_CHILD and WS_VISIBLE. A list of the default styles used follows:
593 // Statement Default Class Default Styles
594 // CONTROL None WS_CHILD|WS_VISIBLE
595 // LTEXT STATIC ES_LEFT
596 // RTEXT STATIC ES_RIGHT
597 // CTEXT STATIC ES_CENTER
598 // LISTBOX LISTBOX WS_BORDER|LBS_NOTIFY
599 // CHECKBOX BUTTON BS_CHECKBOX|WS_TABSTOP
600 // PUSHBUTTON BUTTON BS_PUSHBUTTON|WS_TABSTOP
601 // GROUPBOX BUTTON BS_GROUPBOX
602 // DEFPUSHBUTTON BUTTON BS_DFPUSHBUTTON|WS_TABSTOP
603 // RADIOBUTTON BUTTON BS_RADIOBUTTON
604 // AUTOCHECKBOX BUTTON BS_AUTOCHECKBOX
605 // AUTO3STATE BUTTON BS_AUTO3STATE
606 // AUTORADIOBUTTON BUTTON BS_AUTORADIOBUTTON
607 // PUSHBOX BUTTON BS_PUSHBOX
608 // STATE3 BUTTON BS_3STATE
609 // EDITTEXT EDIT ES_LEFT|WS_BORDER|WS_TABSTOP
610 // COMBOBOX COMBOBOX None
611 // ICON STATIC SS_ICON
612 // SCROLLBAR SCROLLBAR None
615 #define WS_OVERLAPPED 0x00000000L
616 #define WS_POPUP 0x80000000L
617 #define WS_CHILD 0x40000000L
618 #define WS_CLIPSIBLINGS 0x04000000L
619 #define WS_CLIPCHILDREN 0x02000000L
620 #define WS_VISIBLE 0x10000000L
621 #define WS_DISABLED 0x08000000L
622 #define WS_MINIMIZE 0x20000000L
623 #define WS_MAXIMIZE 0x01000000L
624 #define WS_CAPTION 0x00C00000L
625 #define WS_BORDER 0x00800000L
626 #define WS_DLGFRAME 0x00400000L
627 #define WS_VSCROLL 0x00200000L
628 #define WS_HSCROLL 0x00100000L
629 #define WS_SYSMENU 0x00080000L
630 #define WS_THICKFRAME 0x00040000L
631 #define WS_MINIMIZEBOX 0x00020000L
632 #define WS_MAXIMIZEBOX 0x00010000L
633 #define WS_GROUP 0x00020000L
634 #define WS_TABSTOP 0x00010000L
637 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
638 #define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
639 #define WS_CHILDWINDOW (WS_CHILD)
640 #define WS_TILED WS_OVERLAPPED
641 #define WS_ICONIC WS_MINIMIZE
642 #define WS_SIZEBOX WS_THICKFRAME
643 #define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
645 #define WS_EX_DLGMODALFRAME 0x00000001L
646 #define WS_EX_NOPARENTNOTIFY 0x00000004L
647 #define WS_EX_TOPMOST 0x00000008L
648 #define WS_EX_ACCEPTFILES 0x00000010L
649 #define WS_EX_TRANSPARENT 0x00000020L
651 #define BS_PUSHBUTTON 0x00000000L
652 #define BS_DEFPUSHBUTTON 0x00000001L
653 #define BS_CHECKBOX 0x00000002L
654 #define BS_AUTOCHECKBOX 0x00000003L
655 #define BS_RADIOBUTTON 0x00000004L
656 #define BS_3STATE 0x00000005L
657 #define BS_AUTO3STATE 0x00000006L
658 #define BS_GROUPBOX 0x00000007L
659 #define BS_USERBUTTON 0x00000008L
660 #define BS_AUTORADIOBUTTON 0x00000009L
661 #define BS_OWNERDRAW 0x0000000BL
662 #define BS_LEFTTEXT 0x00000020L
664 #define ES_LEFT 0x00000000L
665 #define ES_CENTER 0x00000001L
666 #define ES_RIGHT 0x00000002L
667 #define ES_MULTILINE 0x00000004L
668 #define ES_UPPERCASE 0x00000008L
669 #define ES_LOWERCASE 0x00000010L
670 #define ES_PASSWORD 0x00000020L
671 #define ES_AUTOVSCROLL 0x00000040L
672 #define ES_AUTOHSCROLL 0x00000080L
673 #define ES_NOHIDESEL 0x00000100L
674 #define ES_OEMCONVERT 0x00000400L
675 #define ES_READONLY 0x00000800L
676 #define ES_WANTRETURN 0x00001000L
678 #define LBS_NOTIFY 0x0001L
679 #define LBS_SORT 0x0002L
680 #define LBS_NOREDRAW 0x0004L
681 #define LBS_MULTIPLESEL 0x0008L
682 #define LBS_OWNERDRAWFIXED 0x0010L
683 #define LBS_OWNERDRAWVARIABLE 0x0020L
684 #define LBS_HASSTRINGS 0x0040L
685 #define LBS_USETABSTOPS 0x0080L
686 #define LBS_NOINTEGRALHEIGHT 0x0100L
687 #define LBS_MULTICOLUMN 0x0200L
688 #define LBS_WANTKEYBOARDINPUT 0x0400L
689 #define LBS_EXTENDEDSEL 0x0800L
690 #define LBS_DISABLENOSCROLL 0x1000L
692 #define SS_LEFT 0x00000000L
693 #define SS_CENTER 0x00000001L
694 #define SS_RIGHT 0x00000002L
695 #define SS_ICON 0x00000003L
696 #define SS_BLACKRECT 0x00000004L
697 #define SS_GRAYRECT 0x00000005L
698 #define SS_WHITERECT 0x00000006L
699 #define SS_BLACKFRAME 0x00000007L
700 #define SS_GRAYFRAME 0x00000008L
701 #define SS_WHITEFRAME 0x00000009L
702 #define SS_SIMPLE 0x0000000BL
703 #define SS_LEFTNOWORDWRAP 0x0000000CL
704 #define SS_BITMAP 0x0000000EL
710 typedef struct _IMAGE_DEBUG_DIRECTORY
712 DWORD Characteristics
;
718 DWORD AddressOfRawData
;
719 DWORD PointerToRawData
;
721 IMAGE_DEBUG_DIRECTORY
, *PIMAGE_DEBUG_DIRECTORY
;
723 #define IMAGE_DEBUG_TYPE_UNKNOWN 0
724 #define IMAGE_DEBUG_TYPE_COFF 1
725 #define IMAGE_DEBUG_TYPE_CODEVIEW 2
726 #define IMAGE_DEBUG_TYPE_FPO 3
727 #define IMAGE_DEBUG_TYPE_MISC 4
728 #define IMAGE_DEBUG_TYPE_EXCEPTION 5
729 #define IMAGE_DEBUG_TYPE_FIXUP 6
730 #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
731 #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
734 typedef struct _IMAGE_DEBUG_MISC
736 DWORD DataType
; // type of misc data, see defines
738 DWORD Length
; // total length of record, rounded to four
741 BOOLEAN Unicode
; // TRUE if data is unicode string
744 BYTE Data
[1]; // Actual data
747 IMAGE_DEBUG_MISC
, *PIMAGE_DEBUG_MISC
;
751 // Debugging information can be stripped from an image file and placed
752 // in a separate .DBG file, whose file name part is the same as the
753 // image file name part (e.g. symbols for CMD.EXE could be stripped
754 // and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
755 // flag in the Characteristics field of the file header. The beginning of
756 // the .DBG file contains the following structure which captures certain
757 // information from the image file. This allows a debug to proceed even if
758 // the original image file is not accessable. This header is followed by
759 // zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
760 // IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in
761 // the image file contain file offsets relative to the beginning of the
764 // If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
765 // is left in the image file, but not mapped. This allows a debugger to
766 // compute the name of the .DBG file, from the name of the image in the
767 // IMAGE_DEBUG_MISC structure.
770 typedef struct _IMAGE_SEPARATE_DEBUG_HEADER
775 WORD Characteristics
;
780 DWORD NumberOfSections
;
781 DWORD ExportedNamesSize
;
782 DWORD DebugDirectorySize
;
783 DWORD SectionAlignment
;
786 IMAGE_SEPARATE_DEBUG_HEADER
, *PIMAGE_SEPARATE_DEBUG_HEADER
;
788 #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
790 #define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000
791 #define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the
792 // old checksum didn't match.
800 #define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
801 #define MAXRESOURCENAME 13
803 /* global macros to define header offsets into file */
804 /* offset to PE file signature */
805 #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
806 ((PIMAGE_DOS_HEADER)a)->e_lfanew))
808 /* DOS header identifies the NT PEFile signature dword
809 the PEFILE header exists just after that dword */
810 #define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \
811 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
812 SIZE_OF_NT_SIGNATURE))
814 /* PE optional header is immediately after PEFile header */
815 #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \
816 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
817 SIZE_OF_NT_SIGNATURE + \
818 sizeof (IMAGE_FILE_HEADER)))
820 /* section headers are immediately after PE optional header */
821 #define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + \
822 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
823 SIZE_OF_NT_SIGNATURE + \
824 sizeof (IMAGE_FILE_HEADER) + \
825 sizeof (IMAGE_OPTIONAL_HEADER)))
828 typedef struct tagImportDirectory
830 DWORD dwRVAFunctionNameList
;
833 DWORD dwRVAModuleName
;
834 DWORD dwRVAFunctionAddressList
;
836 IMAGE_IMPORT_MODULE_DIRECTORY
, *PIMAGE_IMPORT_MODULE_DIRECTORY
;
839 /* global prototypes for functions in pefile.c */
840 /* PE file header info */
841 BOOL WINAPI
GetDosHeader (LPVOID
, PIMAGE_DOS_HEADER
);
842 DWORD WINAPI
ImageFileType (LPVOID
);
843 BOOL WINAPI
GetPEFileHeader (LPVOID
, PIMAGE_FILE_HEADER
);
845 /* PE optional header info */
846 BOOL WINAPI
GetPEOptionalHeader (LPVOID
, PIMAGE_OPTIONAL_HEADER
);
847 LPVOID WINAPI
GetModuleEntryPoint (LPVOID
);
848 int WINAPI
NumOfSections (LPVOID
);
849 LPVOID WINAPI
GetImageBase (LPVOID
);
850 LPVOID WINAPI
ImageDirectoryOffset (LPVOID
, DWORD
);
851 LPVOID WINAPI
ImageDirectorySection (LPVOID
, DWORD
);
853 /* PE section header info */
854 //int WINAPI GetSectionNames (LPVOID, HANDLE, char **);
855 int WINAPI
GetSectionNames (LPVOID
, char **);
856 BOOL WINAPI
GetSectionHdrByName (LPVOID
, PIMAGE_SECTION_HEADER
, char *);
859 // structur to store string tokens
861 typedef struct _Str_P
863 char flag
; // string_flag '@' or '%' or '#'
865 char *pos
; // starting postion of string
867 int length
; // length of string
869 BOOL wasString
; // if it were stringMode or not
874 /* import section info */
875 int WINAPI
GetImportModuleNames (LPVOID
, char **);
876 int WINAPI
GetImportFunctionNamesByModule (LPVOID
, char *, char **);
878 // import function name reporting
879 int WINAPI
GetStringLength (char *);
880 void WINAPI
GetPreviousParamString (char *, char *);
881 void WINAPI
TranslateParameters (char **, char **, char **);
882 BOOL WINAPI
StringExpands (char **, char **, char **, Str_P
*);
883 char * WINAPI
TranslateFunctionName (char *);
885 /* export section info */
886 int WINAPI
GetExportFunctionNames (LPVOID
, char **);
888 /* resource section info */
889 int WINAPI
GetNumberOfResources (LPVOID
);
890 int WINAPI
GetListOfResourceTypes (LPVOID
, char **);
891 int WINAPI
MenuScan (int *, WORD
**);
892 int WINAPI
MenuFill (char **, WORD
**);
893 void WINAPI
StrangeMenuFill (char **, WORD
**, int);
894 int WINAPI
GetContentsOfMenu (LPVOID
, char **);
895 int WINAPI
PrintMenu (int, char **);
896 int WINAPI
PrintStrangeMenu (char **);
897 int WINAPI
dumpMenu (char **psz
, int size
);
899 /* debug section info */
900 BOOL WINAPI
IsDebugInfoStripped (LPVOID
);
901 int WINAPI
RetrieveModuleName (LPVOID
, char **);
902 BOOL WINAPI
IsDebugFile (LPVOID
);
903 BOOL WINAPI
GetSeparateDebugHeader (LPVOID
, PIMAGE_SEPARATE_DEBUG_HEADER
);
906 /**********************************************************************
910 * Copy DOS header information to structure.
917 PIMAGE_DOS_HEADER pHeader
921 * DOS header represents first structure
922 * of bytes in PE image file.
924 if ((WORD
) IMAGE_DOS_SIGNATURE
== *(WORD
*) lpFile
)
929 sizeof (IMAGE_DOS_HEADER
)
939 /* return file signature */
944 /* dos file signature comes first */
945 if (*(USHORT
*) lpFile
== IMAGE_DOS_SIGNATURE
)
947 /* determine location of PE File header from dos header */
948 if (LOWORD (*(DWORD
*) NTSIGNATURE (lpFile
)) == IMAGE_OS2_SIGNATURE
||
949 LOWORD (*(DWORD
*) NTSIGNATURE (lpFile
)) == IMAGE_OS2_SIGNATURE_LE
)
950 return (DWORD
) LOWORD (*(DWORD
*) NTSIGNATURE (lpFile
));
952 else if (*(DWORD
*) NTSIGNATURE (lpFile
) == IMAGE_NT_SIGNATURE
)
953 return IMAGE_NT_SIGNATURE
;
956 return IMAGE_DOS_SIGNATURE
;
960 /* unknown file type */
967 /* copy file header information to structure */
971 PIMAGE_FILE_HEADER pHeader
)
973 /* file header follows dos header */
974 if (ImageFileType (lpFile
) == IMAGE_NT_SIGNATURE
)
975 bcopy (PEFHDROFFSET (lpFile
), (LPVOID
) pHeader
, sizeof (IMAGE_FILE_HEADER
));
986 /* copy optional header info to structure */
988 GetPEOptionalHeader (
990 PIMAGE_OPTIONAL_HEADER pHeader
)
992 /* optional header follows file header and dos header */
993 if (ImageFileType (lpFile
) == IMAGE_NT_SIGNATURE
)
994 bcopy (OPTHDROFFSET (lpFile
), (LPVOID
) pHeader
, sizeof (IMAGE_OPTIONAL_HEADER
));
1004 /* function returns the entry point for an exe module lpFile must
1005 be a memory mapped file pointer to the beginning of the image file */
1007 GetModuleEntryPoint (
1010 PIMAGE_OPTIONAL_HEADER poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
1013 return (LPVOID
) (poh
->AddressOfEntryPoint
);
1021 /* return the total number of sections in the module */
1026 /* number os sections is indicated in file header */
1027 return ((int) ((PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
))->NumberOfSections
);
1033 /* retrieve entry point */
1038 PIMAGE_OPTIONAL_HEADER poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
1041 return (LPVOID
) (poh
->ImageBase
);
1049 // This function is written by sang cho
1050 // .. october 5, 1997
1052 /* function returns the actual address of given RVA, lpFile must
1053 be a memory mapped file pointer to the beginning of the image file */
1059 // PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
1060 PIMAGE_SECTION_HEADER psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
1061 int nSections
= NumOfSections (lpFile
);
1066 if (dwRVA
& 0x80000000)
1068 //return (LPVOID)dwRVA;
1069 printf ("\n$$ what is going on $$");
1073 /* locate section containing image directory */
1074 while (i
++ < nSections
)
1076 if (psh
->VirtualAddress
<= (DWORD
) dwRVA
&&
1077 psh
->VirtualAddress
+ psh
->SizeOfRawData
> (DWORD
) dwRVA
)
1085 /* return image import directory offset */
1086 return (LPVOID
) (((int) lpFile
+ (int) dwRVA
- psh
->VirtualAddress
) +
1087 (int) psh
->PointerToRawData
);
1092 // This function is modified by sang cho
1095 /* return offset to specified IMAGE_DIRECTORY entry */
1097 ImageDirectoryOffset (
1099 DWORD dwIMAGE_DIRECTORY
)
1101 PIMAGE_OPTIONAL_HEADER poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
1102 PIMAGE_SECTION_HEADER psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
1103 int nSections
= NumOfSections (lpFile
);
1107 /* must be 0 thru (NumberOfRvaAndSizes-1) */
1108 if (dwIMAGE_DIRECTORY
>= poh
->NumberOfRvaAndSizes
)
1111 /* locate specific image directory's relative virtual address */
1112 VAImageDir
= (LPVOID
) poh
->DataDirectory
[dwIMAGE_DIRECTORY
].VirtualAddress
;
1114 if (VAImageDir
== NULL
)
1116 /* locate section containing image directory */
1117 while (i
++ < nSections
)
1119 if (psh
->VirtualAddress
<= (DWORD
) VAImageDir
&&
1120 psh
->VirtualAddress
+ psh
->SizeOfRawData
> (DWORD
) VAImageDir
)
1128 /* return image import directory offset */
1129 return (LPVOID
) (((int) lpFile
+ (int) VAImageDir
- psh
->VirtualAddress
) +
1130 (int) psh
->PointerToRawData
);
1134 /* function retrieve names of all the sections in the file */
1140 int nSections
= NumOfSections (lpFile
);
1142 PIMAGE_SECTION_HEADER psh
;
1146 if (ImageFileType (lpFile
) != IMAGE_NT_SIGNATURE
||
1147 (psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
)) == NULL
)
1150 /* count the number of chars used in the section names */
1151 for (i
= 0; i
< nSections
; i
++)
1152 nCnt
+= strlen ((char *)psh
[i
].Name
) + 1;
1154 /* allocate space for all section names from heap */
1155 ps
= *pszSections
= (char *) calloc (nCnt
, 1);
1158 for (i
= 0; i
< nSections
; i
++)
1160 strcpy (ps
, (char *)psh
[i
].Name
);
1161 ps
+= strlen ((char *)psh
[i
].Name
) + 1;
1170 /* function gets the function header for a section identified by name */
1172 GetSectionHdrByName (
1174 IMAGE_SECTION_HEADER
* sh
,
1177 PIMAGE_SECTION_HEADER psh
;
1178 int nSections
= NumOfSections (lpFile
);
1182 if ((psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
)) != NULL
)
1184 /* find the section by name */
1185 for (i
= 0; i
< nSections
; i
++)
1187 if (!strcmp ((char *)psh
->Name
, szSection
))
1189 /* copy data to header */
1190 bcopy ((LPVOID
) psh
, (LPVOID
) sh
, sizeof (IMAGE_SECTION_HEADER
));
1203 // This function is modified by sang cho
1206 /* get import modules names separated by null terminators, return module count */
1208 GetImportModuleNames (
1212 PIMAGE_IMPORT_MODULE_DIRECTORY pid
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
1213 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_IMPORT
);
1215 // sometimes there may be no section for idata or edata
1216 // instead rdata or data section may contain these sections ..
1217 // or even module names or function names are in different section.
1218 // so that's why we need to get actual address of RVAs each time.
1219 // ...................sang cho..................
1221 // PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1222 // ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1223 // BYTE *pData = (BYTE *)pid;
1224 // DWORD *pdw = (DWORD *)pid;
1225 int nCnt
= 0, nSize
= 0, i
;
1226 char *pModule
[1024]; /* hardcoded maximum number of modules?? */
1232 // pData = (BYTE *)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1234 /* extract all import modules */
1235 while (pid
->dwRVAModuleName
)
1237 /* allocate temporary buffer for absolute string offsets */
1238 //pModule[nCnt] = (char *)(pData + pid->dwRVAModuleName);
1239 pModule
[nCnt
] = (char *) GetActualAddress (lpFile
, pid
->dwRVAModuleName
);
1240 nSize
+= strlen (pModule
[nCnt
]) + 1;
1242 /* increment to the next import directory entry */
1247 /* copy all strings to one chunk of memory */
1248 *pszModules
= (char *) calloc (nSize
, 1);
1250 for (i
= 0; i
< nCnt
; i
++)
1252 strcpy (psz
, pModule
[i
]);
1253 psz
+= strlen (psz
) + 1;
1260 // This function is rewritten by sang cho
1263 /* get import module function names separated by null terminators, return function count */
1265 GetImportFunctionNamesByModule (
1268 char **pszFunctions
)
1270 PIMAGE_IMPORT_MODULE_DIRECTORY pid
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
1271 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_IMPORT
);
1273 // sometimes there may be no section for idata or edata
1274 // instead rdata or data section may contain these sections ..
1275 // or even module names or function names are in different section.
1276 // so that's why we need to get actual address each time.
1277 // ...................sang cho..................
1279 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1280 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1282 int nCnt
= 0, nSize
= 0;
1285 DWORD dwFunctionName
;
1286 DWORD dwFunctionAddress
;
1288 char buff
[256]; // enough for any string ??
1293 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1295 /* find module's pid */
1296 while (pid
->dwRVAModuleName
&&
1297 strcmp (pszModule
, (char *) GetActualAddress (lpFile
, pid
->dwRVAModuleName
)))
1300 /* exit if the module is not found */
1301 if (!pid
->dwRVAModuleName
)
1304 // I am doing this to get rid of .dll from module name
1305 strcpy (name
, pszModule
);
1306 mnlength
= strlen (pszModule
);
1307 for (i
= 0; i
< mnlength
; i
++)
1313 /* count number of function names and length of strings */
1314 dwFunctionName
= pid
->dwRVAFunctionNameList
;
1316 // IMAGE_IMPORT_BY_NAME OR IMAGE_THUNK_DATA
1317 // modified by Sang Cho
1318 while (dwFunctionName
&&
1319 *(pdw
= (DWORD
*) GetActualAddress (lpFile
, dwFunctionName
)))
1321 if ((*pdw
) & 0x80000000)
1322 nSize
+= mnlength
+ 10 + 1 + 6;
1324 nSize
+= strlen ((char *) GetActualAddress (lpFile
, *pdw
+ 2)) + 1 + 6;
1325 dwFunctionName
+= 4;
1329 /* allocate memory for function names */
1330 *pszFunctions
= (char *) calloc (nSize
, 1);
1331 psz
= *pszFunctions
;
1334 // I modified this part to store function address (4 bytes),
1335 // ord number (2 bytes),
1336 // and name strings (which was there originally)
1337 // so that's why there are 6 more bytes...... +6, or +4 and +2 etc.
1338 // these informations are used where they are needed.
1339 // ...........sang cho..................
1341 /* copy function names to mempry pointer */
1342 dwFunctionName
= pid
->dwRVAFunctionNameList
;
1343 dwFunctionAddress
= pid
->dwRVAFunctionAddressList
;
1344 while (dwFunctionName
&&
1345 *(pdw
= (DWORD
*) GetActualAddress (lpFile
, dwFunctionName
)))
1347 if ((*pdw
) & 0x80000000)
1349 *(int *) psz
= (int) (*(DWORD
*) GetActualAddress (lpFile
, dwFunctionAddress
));
1351 *(short *) psz
= *(short *) pdw
;
1353 sprintf (buff
, "%s:NoName%04d", name
, nnid
++);
1355 psz
+= strlen (buff
) + 1;
1359 *(int *) psz
= (int) (*(DWORD
*) GetActualAddress (lpFile
, dwFunctionAddress
));
1361 *(short *) psz
= (*(short *) GetActualAddress (lpFile
, *pdw
));
1363 strcpy (psz
, (char *) GetActualAddress (lpFile
, *pdw
+ 2));
1364 psz
+= strlen ((char *) GetActualAddress (lpFile
, *pdw
+ 2)) + 1;
1366 dwFunctionName
+= 4;
1367 dwFunctionAddress
+= 4;
1377 // This function is written by sang cho
1380 /* get numerically expressed string length */
1385 if (!isdigit (*psz
))
1387 if (isdigit (*(psz
+ 1)))
1388 return (*psz
- '0') * 10 + *(psz
+ 1) - '0';
1397 // This function is written by sang cho
1401 /* translate parameter part of condensed name */
1403 GetPreviousParamString (
1404 char *xpin
, // read-only source
1405 char *xpout
) // translated result
1418 printf ("\n **error PreviousParamString1 char = %c", *pin
);
1426 else if (*pin
== '<')
1428 else if (*pin
== ')')
1436 else if (strchr (",(", *pin
))
1441 //printf("\n ----- %s", pin);
1442 if (strchr (",(", *pin
))
1445 } // printf("\n %s", pin); }
1449 printf ("\n **error PreviousParamString2");
1454 strncpy (pout
, pin
, n
);
1462 // This function is written by sang cho
1466 /* translate parameter part of condensed name */
1468 TranslateParameters (
1469 char **ppin
, // read-only source
1470 char **ppout
, // translated result
1471 char **pps
) // parameter stack
1476 char *pin
, *pout
, *ps
;
1478 //printf(" %c ", **in);
1487 strcpy (pout
, "byte");
1492 strcpy (pout
, "char");
1497 strcpy (pout
, "double");
1502 strcpy (pout
, "float");
1507 strcpy (pout
, "long double");
1512 strcpy (pout
, "int");
1517 strcpy (pout
, "long");
1522 strcpy (pout
, "short");
1527 strcpy (pout
, "void");
1531 // postfix processing
1534 if (*(pin
+ 1) == 'p')
1557 if (*(pin
+ 1) == 'p')
1571 // repeat processing
1573 if (isdigit (*(pin
+ 1)))
1575 n
= *(pin
+ 1) - '0';
1578 GetPreviousParamString (pout
, name
);
1579 strcpy (pout
, name
);
1580 pout
+= strlen (name
);
1581 for (i
= 1; i
< n
; i
++)
1584 strcpy (pout
, name
);
1585 pout
+= strlen (name
);
1591 // prefix processing
1601 strcpy (pout
, "const ");
1609 strcpy (pout
, "static ");
1617 strcpy (pout
, "!1!");
1625 // need to process postfix finally
1627 if (strchr ("tqx", c
))
1629 if (*(pin
) && !strchr ("@$%", *(pin
)))
1639 strcpy (pout
, "*&");
1644 strcpy (pout
, "**");
1659 strcpy (pout
, "!2!");
1664 if (*(pin
) && !strchr ("@$%", *(pin
)))
1673 // This function is written by sang cho
1677 /* translate parameter part of condensed name */
1680 char **ppin
, // read-only source
1681 char **ppout
, // translated result
1682 char **pps
, // parameter stack
1683 Str_P
* pcstr
) // currently stored string
1687 char *pin
, *pout
, *ps
;
1689 BOOL stringMode
= TRUE
;
1696 if (strncmp (pin
, "bctr", 4) == 0)
1698 strncpy (pout
, c_str
.pos
, c_str
.length
);
1699 pout
+= c_str
.length
;
1702 else if (strncmp (pin
, "bdtr", 4) == 0)
1705 strncpy (pout
, c_str
.pos
, c_str
.length
);
1706 pout
+= c_str
.length
;
1709 else if (*pin
== 'o')
1711 strcpy (pout
, "const ");
1716 else if (*pin
== 'q')
1723 else if (*pin
== 't')
1725 //if (*(ps-1) == 't') { *pout++ = ','; pin++; } // this also got me...
1726 //else october 12 .. sang
1734 else if (strncmp (pin
, "xq", 2) == 0)
1742 else if (strncmp (pin
, "bcall", 5) == 0)
1744 strcpy (pout
, "operator ()");
1748 else if (strncmp (pin
, "bsubs", 5) == 0)
1750 strcpy (pout
, "operator []");
1754 else if (strncmp (pin
, "bnwa", 4) == 0)
1756 strcpy (pout
, "operator new[]");
1760 else if (strncmp (pin
, "bdla", 4) == 0)
1762 strcpy (pout
, "operator delete[]");
1766 else if (strncmp (pin
, "bnew", 4) == 0)
1768 strcpy (pout
, "operator new");
1772 else if (strncmp (pin
, "bdele", 5) == 0)
1774 strcpy (pout
, "operator delete");
1778 else if (strncmp (pin
, "blsh", 4) == 0)
1780 strcpy (pout
, "operator <<");
1784 else if (strncmp (pin
, "brsh", 4) == 0)
1786 strcpy (pout
, "operator >>");
1790 else if (strncmp (pin
, "binc", 4) == 0)
1792 strcpy (pout
, "operator ++");
1796 else if (strncmp (pin
, "bdec", 4) == 0)
1798 strcpy (pout
, "operator --");
1802 else if (strncmp (pin
, "badd", 4) == 0)
1804 strcpy (pout
, "operator +");
1808 else if (strncmp (pin
, "brplu", 5) == 0)
1810 strcpy (pout
, "operator +=");
1814 else if (strncmp (pin
, "bdiv", 4) == 0)
1816 strcpy (pout
, "operator /");
1820 else if (strncmp (pin
, "brdiv", 5) == 0)
1822 strcpy (pout
, "operator /=");
1826 else if (strncmp (pin
, "bmul", 4) == 0)
1828 strcpy (pout
, "operator *");
1832 else if (strncmp (pin
, "brmul", 5) == 0)
1834 strcpy (pout
, "operator *=");
1838 else if (strncmp (pin
, "basg", 4) == 0)
1840 strcpy (pout
, "operator =");
1844 else if (strncmp (pin
, "beql", 4) == 0)
1846 strcpy (pout
, "operator ==");
1850 else if (strncmp (pin
, "bneq", 4) == 0)
1852 strcpy (pout
, "operator !=");
1856 else if (strncmp (pin
, "bor", 3) == 0)
1858 strcpy (pout
, "operator |");
1862 else if (strncmp (pin
, "bror", 4) == 0)
1864 strcpy (pout
, "operator |=");
1868 else if (strncmp (pin
, "bcmp", 4) == 0)
1870 strcpy (pout
, "operator ~");
1874 else if (strncmp (pin
, "bnot", 4) == 0)
1876 strcpy (pout
, "operator !");
1880 else if (strncmp (pin
, "band", 4) == 0)
1882 strcpy (pout
, "operator &");
1886 else if (strncmp (pin
, "brand", 5) == 0)
1888 strcpy (pout
, "operator &=");
1892 else if (strncmp (pin
, "bxor", 4) == 0)
1894 strcpy (pout
, "operator ^");
1898 else if (strncmp (pin
, "brxor", 5) == 0)
1900 strcpy (pout
, "operator ^=");
1906 strcpy (pout
, "!$$$!");
1913 } // end of '$' processing
1917 //----------------------------------------------------------------------
1918 // structure to store string tokens
1919 //----------------------------------------------------------------------
1920 //typedef struct _Str_P {
1921 // char flag; // string_flag '@' or '%' or '#'
1922 // char *pos; // starting postion of string
1923 // int length; // length of string
1924 // BOOL wasString; // if it were stringMode or not
1926 //----------------------------------------------------------------------
1928 // I think I knocked it down finally. But who knows?
1929 // october 12, 1997 ... sang
1931 // well I have to rewrite whole part of TranslateFunctionName..
1932 // this time I am a little bit more experienced than 5 days ago.
1933 // or am i??? anyway i use stacks instead of recurcive calls
1934 // and i hope this will take care of every symptoms i have experienced..
1935 // october 10, 1997 .... sang
1936 // It took a lot of time for me to figure out what is all about....
1937 // but still some prefixes like z (static)
1938 // -- or some types like b (byte) ,g (long double) ,s (short) --
1939 // -- or postfix like M ( * )
1940 // -- or $or ( & ) which is pretty wierd. .. added.. october 12
1941 // -- also $t business is quite tricky too. (templates)
1942 // there may be a lot of things undiscovered yet....
1943 // I am not so sure my interpretation is correct or not
1944 // If I am wrong please let me know.
1945 // october 8, 1997 .... sang
1948 // This function is written by sang cho
1951 /* translate condesed import function name */
1953 TranslateFunctionName (
1962 static char buff
[512]; // result of translation
1965 char pStack
[32]; // parameter processing stack
1967 Str_P sStack
[32]; // String processing stack
1969 Str_P tok
; // String token
1971 Str_P c_str
; // current string
1974 char *endTab
[8]; // end of string position check
1978 BOOL stringMode
= TRUE
;
1986 //................................................................
1987 // serious users may need to run the following code.
1988 // so I may need to include some flag options...
1989 // If you want to know about how translation is done,
1990 // you can just revive following line and you can see it.
1991 // october 6, 1997 ... sang cho
1992 //printf ("\n................................... %s", psz); // for debugging...
1999 tok
.wasString
= stringMode
;
2000 sStack
[is
++] = tok
; // initialize sStack with dummy marker
2008 //---------------------------------------------
2009 // check for the end of number specified string
2010 //---------------------------------------------
2014 for (i
= 0; i
< iend
; i
++)
2015 if (pin
== endTab
[i
])
2019 // move the end of endTab to ith position
2020 endTab
[i
] = endTab
[iend
- 1];
2023 // get top of the string stack
2024 tok
= sStack
[is
- 1];
2026 // I am expecting '#' token from stack
2027 if (tok
.flag
!= '#')
2030 printf ("\n**some serious error1** %c is = %d char = %c",
2031 tok
.flag
, is
, *pin
);
2035 // pop '#' token I am happy now.
2038 //printf("\n pop # token ... current char = %c", c);
2039 //else printf("\n pop percent token..next char = NULL");
2044 stringMode
= tok
.wasString
;
2048 // need to process postfix finally
2050 if (strchr ("qtx", cc
))
2052 if (!strchr ("@$%", c
))
2060 strcpy (pout
, "*&");
2065 strcpy (pout
, "**");
2080 strcpy (pout
, "!3!");
2085 if (!strchr ("@$%", c
))
2089 // string mode restored...
2092 else; // do nothing..
2096 //------------------------------------------------
2097 // special control symbol processing:
2098 //------------------------------------------------
2100 if (strchr ("@$%", c
))
2103 //---------------------------------------------------------------
2104 // string part processing : no '$' met yet
2105 // or inside of '%' block
2106 // or inside of '#' block (numbered string)
2107 //---------------------------------------------------------------
2109 else if (stringMode
)
2111 //else if (is > 1) *pout++ = *pin++;
2113 //------------------------------------------------
2114 // parameter part processing: '$' met
2115 //------------------------------------------------
2117 else // parameter processing
2121 TranslateParameters (&pin
, &pout
, &ps
);
2122 else // number specified string processing
2125 n
= GetStringLength (pin
);
2133 //printf("\n push # token .. char = %c", *pin);
2134 //else printf("\n push percent token..next char = NULL");
2138 tok
.wasString
= stringMode
;
2141 // mark end of input string
2142 endTab
[iend
++] = pin
+ n
;
2146 } // end of inner while loop
2148 // beginning of new string or end of string ( quotation mark )
2153 pin
++; // anyway we have to proceed...
2155 tok
= sStack
[is
- 1]; // get top of the sStack
2157 if (tok
.flag
== '%')
2159 // pop '%' token and set c_str
2161 //printf("\n pop percent token..next char = %c", *pin);
2162 //else printf("\n pop percent token..next char = NULL");
2165 c_str
.length
= pout
- c_str
.pos
;
2166 if (*(ps
- 1) == 't')
2170 stringMode
= tok
.wasString
;
2174 printf ("\n**some string error3** stack = %c", *(ps
- 1));
2178 else if (tok
.flag
== 'A' || tok
.flag
== '#')
2182 //printf("\n push percent token..next char = %c", *pin);
2183 //else printf("\n push percent token..next char = NULL");
2187 tok
.wasString
= stringMode
;
2192 printf ("\n**some string error5**");
2197 // sometimes we need string to use as constructor name or destructor name
2199 else if (c
== '@') // get string from previous marker upto here.
2203 tok
= sStack
[is
- 1];
2205 c_str
.pos
= tok
.pos
;
2206 c_str
.length
= pout
- tok
.pos
;
2207 c_str
.wasString
= stringMode
;
2212 // we need to take care of parameter control sequence
2214 else if (c
== '$') // need to precess template or parameter part
2219 stringMode
= StringExpands (&pin
, &pout
, &ps
, &c_str
);
2221 { // template parameter mode I guess "$t"
2229 printf ("\nMYGOODNESS1 %c", *pin
);
2233 //if (*ps == 't') *pout++ = '>';
2234 //else { printf("\nMYGOODNESS2"); exit(0);}
2235 *pout
++ = ','; //pin++; ..this almost blowed me....
2238 // real parameter mode I guess
2239 // unexpected case is found ... humm what can I do...
2242 // this is newly found twist.. it really hurts.
2253 printf ("\n** I GIVEUP ***");
2263 else if (*ps
== '&')
2265 else if (*ps
== 'p')
2270 else if (*ps
== 'r')
2277 printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin
);
2288 else if (*ps
== '&')
2290 else if (*ps
== 'p')
2295 else if (*ps
== 'r')
2302 printf ("\n*** SOMETHING IS WRONG2***");
2311 } // end of '$' processing
2313 } // end of outer while loop
2315 // need to process remaining parameter stack
2330 strcpy (pout
, " const");
2334 strcpy (pout
, "*&");
2338 strcpy (pout
, "**");
2348 strcpy (pout
, "!4!");
2360 // This function is written by sang cho
2363 /* get exported function names separated by null terminators, return count of functions */
2365 GetExportFunctionNames (
2367 char **pszFunctions
)
2369 //PIMAGE_SECTION_HEADER psh;
2370 PIMAGE_EXPORT_DIRECTORY ped
;
2372 DWORD imageBase
; //===========================
2375 {NULL
,}; // maximum number of functions
2376 //=============================
2378 char buff
[256]; // enough for any string ??
2380 char *psz
= NULL
; //===============================
2386 int i
, nCnt
= 0, ntmp
= 0;
2387 int enid
= 0, ordBase
= 1; // usally ordBase is 1....
2391 /* get section header and pointer to data directory for .edata section */
2392 ped
= (PIMAGE_EXPORT_DIRECTORY
)
2393 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_EXPORT
);
2399 // sometimes there may be no section for idata or edata
2400 // instead rdata or data section may contain these sections ..
2401 // or even module names or function names are in different section.
2402 // so that's why we need to get actual address each time.
2403 // ...................sang cho..................
2405 //psh = (PIMAGE_SECTION_HEADER)
2406 //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2408 //if (psh == NULL) return 0;
2410 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2413 /* determine the offset of the export function names */
2415 pdwAddress
= (DWORD
*) GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfFunctions
);
2417 imageBase
= (DWORD
) GetImageBase (lpFile
);
2419 ordBase
= ped
->Base
;
2421 if (ped
->NumberOfNames
> 0)
2423 pdwNames
= (DWORD
*)
2424 GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNames
);
2426 GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNameOrdinals
);
2429 /* figure out how much memory to allocate for all strings */
2430 for (i
= 0; i
< (int) ped
->NumberOfNames
; i
++)
2432 nCnt
+= strlen ((char *)
2433 GetActualAddress (lpFile
, *(DWORD
*) pdwNames
)) + 1 + 6;
2436 // get the number of unnamed functions
2437 for (i
= 0; i
< (int) ped
->NumberOfFunctions
; i
++)
2440 // add memory required to show unnamed functions.
2441 if (ntmp
> (int) ped
->NumberOfNames
)
2442 nCnt
+= 18 * (ntmp
- (int) ped
->NumberOfNames
);
2444 /* allocate memory for function names */
2446 *pszFunctions
= (char *) calloc (nCnt
, 1);
2447 pdwNames
= (DWORD
*) GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNames
);
2449 /* copy string pointer to buffer */
2451 for (i
= 0; i
< (int) ped
->NumberOfNames
; i
++)
2453 pfns
[(int) (*pwOrd
) + ordBase
] =
2454 (char *) GetActualAddress (lpFile
, *(DWORD
*) pdwNames
);
2459 psz
= *pszFunctions
;
2462 for (i
= ordBase
; i
< (int) ped
->NumberOfFunctions
+ ordBase
; i
++)
2464 if (*pdwAddress
> 0)
2466 *(DWORD
*) psz
= imageBase
+ *pdwAddress
;
2468 *(WORD
*) psz
= (WORD
) (i
);
2472 strcpy (psz
, pfns
[i
]);
2473 psz
+= strlen (psz
) + 1;
2477 sprintf (buff
, "ExpFn%04d()", enid
++);
2491 /* determine the total number of resources in the section */
2493 GetNumberOfResources (
2496 PIMAGE_RESOURCE_DIRECTORY prdRoot
, prdType
;
2497 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
;
2501 /* get root directory of resource tree */
2502 if ((prdRoot
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2503 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2506 /* set pointer to first resource type entry */
2507 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) ((DWORD
) prdRoot
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2509 /* loop through all resource directory entry types */
2510 for (i
= 0; i
< prdRoot
->NumberOfIdEntries
; i
++)
2512 /* locate directory or each resource type */
2513 prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ((int) prdRoot
+ (int) prde
->OffsetToData
);
2515 /* mask off most significant bit of the data offset */
2516 prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ((DWORD
) prdType
^ 0x80000000);
2518 /* increment count of name'd and ID'd resources in directory */
2519 nCnt
+= prdType
->NumberOfNamedEntries
+ prdType
->NumberOfIdEntries
;
2521 /* increment to next entry */
2531 // This function is rewritten by sang cho
2534 /* name each type of resource in the section */
2536 GetListOfResourceTypes (
2540 PIMAGE_RESOURCE_DIRECTORY prdRoot
;
2541 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
;
2548 /* get root directory of resource tree */
2549 if ((prdRoot
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2550 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2553 /* allocate enuff space to cover all types */
2554 nCnt
= prdRoot
->NumberOfIdEntries
* (MAXRESOURCENAME
+ 1);
2555 *pszResTypes
= (char *) calloc (nCnt
, 1);
2556 if ((pMem
= *pszResTypes
) == NULL
)
2559 /* set pointer to first resource type entry */
2560 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) ((DWORD
) prdRoot
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2562 /* loop through all resource directory entry types */
2563 for (i
= 0; i
< prdRoot
->NumberOfIdEntries
; i
++)
2565 prdeName
= prde
->Name
;
2567 //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2568 // pMem += strlen (pMem) + 1;
2570 // modified by ...................................Sang Cho..
2571 // I can't user M/S provied funcitons here so I have to figure out
2572 // how to do above functions. But I can settle down with the following
2573 // code, which works pretty good for me.
2577 strcpy (pMem
, "RT_CURSOR");
2580 else if (prdeName
== 2)
2582 strcpy (pMem
, "RT_BITMAP");
2585 else if (prdeName
== 3)
2587 strcpy (pMem
, "RT_ICON ");
2590 else if (prdeName
== 4)
2592 strcpy (pMem
, "RT_MENU ");
2595 else if (prdeName
== 5)
2597 strcpy (pMem
, "RT_DIALOG");
2600 else if (prdeName
== 6)
2602 strcpy (pMem
, "RT_STRING");
2605 else if (prdeName
== 7)
2607 strcpy (pMem
, "RT_FONTDIR");
2610 else if (prdeName
== 8)
2612 strcpy (pMem
, "RT_FONT ");
2615 else if (prdeName
== 9)
2617 strcpy (pMem
, "RT_ACCELERATORS");
2620 else if (prdeName
== 10)
2622 strcpy (pMem
, "RT_RCDATA");
2625 else if (prdeName
== 11)
2627 strcpy (pMem
, "RT_MESSAGETABLE");
2630 else if (prdeName
== 12)
2632 strcpy (pMem
, "RT_GROUP_CURSOR");
2635 else if (prdeName
== 14)
2637 strcpy (pMem
, "RT_GROUP_ICON ");
2640 else if (prdeName
== 16)
2642 strcpy (pMem
, "RT_VERSION");
2645 else if (prdeName
== 17)
2647 strcpy (pMem
, "RT_DLGINCLUDE ");
2650 else if (prdeName
== 19)
2652 strcpy (pMem
, "RT_PLUGPLAY ");
2655 else if (prdeName
== 20)
2657 strcpy (pMem
, "RT_VXD ");
2660 else if (prdeName
== 21)
2662 strcpy (pMem
, "RT_ANICURSOR ");
2665 else if (prdeName
== 22)
2667 strcpy (pMem
, "RT_ANIICON");
2670 else if (prdeName
== 0x2002)
2672 strcpy (pMem
, "RT_NEWBITMAP");
2675 else if (prdeName
== 0x2004)
2677 strcpy (pMem
, "RT_NEWMENU");
2680 else if (prdeName
== 0x2005)
2682 strcpy (pMem
, "RT_NEWDIALOG");
2685 else if (prdeName
== 0x7fff)
2687 strcpy (pMem
, "RT_ERROR ");
2692 sprintf (buff
, "RT_UNKNOWN:%08lX", prdeName
);
2693 strcpy (pMem
, buff
);
2699 return prdRoot
->NumberOfIdEntries
;
2705 // This function is written by sang cho
2708 /* copy menu information */
2711 char **psz
, // results
2712 WORD
** pMenu
, // read-only
2719 pmax
= (WORD
*) ((DWORD
) pwd
+ size
);
2720 ptr
= (WORD
*) (*psz
);
2726 *psz
= (char *) ptr
;
2733 // This function is written by sang cho
2736 /* obtain menu information */
2751 flag
= *pwd
; // so difficult to correctly code this so let's try this
2754 (*len
) += 2; // flag store
2756 if ((flag
& 0x0010) == 0)
2761 (*len
) += 2; // id store
2774 (*len
)++; // name and null character
2776 pwd
++; // skip double null
2778 if ((flag
& 0x0010) == 0) // normal node: done
2784 // popup node: need to go on...
2788 flag1
= (WORD
) MenuScan (len
, pMenu
);
2793 // fill # of details to num above
2801 // This function is written by sang cho
2804 /* copy menu information */
2812 char *ptr
/*, *pTemp*/;
2815 WORD id
/*, ispopup*/;
2819 //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2820 flag
= *pwd
; // so difficult to correctly code this so let's try this
2823 if ((flag
& 0x0010) == 0)
2825 *(WORD
*) ptr
= flag
; // flag store
2828 *(WORD
*) ptr
= id
= *pwd
; // id store
2835 *(WORD
*) ptr
= flag
; // flag store
2840 while (*pwd
) // name extract
2843 *ptr
= *(char *) pwd
;
2846 } //name and null character
2850 pwd
++; // skip double null
2852 if ((flag
& 0x0010) == 0) // normal node: done
2861 // popup node: need to go on...
2867 flag1
= (WORD
) MenuFill (psz
, pMenu
);
2873 // fill # of details to num above
2874 //*(WORD *)pTemp = (WORD)num;
2882 //==============================================================================
2883 // The following program is based on preorder-tree-traversal.
2884 // once you understand how to traverse.....
2885 // the rest is pretty straight forward.
2886 // still we need to scan it first and fill it next time.
2887 // and finally we can print it.
2889 // This function is written by sang cho
2890 // September 29, 1997
2891 // revised october 2, 1997
2892 // revised october 12, 1997
2893 // ..............................................................................
2894 // ------------------------------------------------------------------------------
2895 // I use same structure - which is used in P.E. programs - for my reporting.
2896 // So, my structure is as follows:
2897 // # of menu name is stored else where ( in directory I suppose )
2898 // supermenuname null terminated string, only ascii is considered.
2899 // flag tells : node is a leaf or a internal node.
2900 // popupname null terminated string
2902 // flag normal menu flag (leaf node)
2903 // id normal menu id
2904 // name normal menu name
2906 // flag popup menu flag (internal node)
2907 // popupname popup menu name
2909 // flag it may folows
2910 // id normal menu id
2911 // name normal menu name
2914 // popupname popup menu name
2916 // it goes on like this,
2917 // but usually, it only goes a few steps,...
2918 // ------------------------------------------------------------------------------
2919 /* scan menu and copy menu */
2925 PIMAGE_RESOURCE_DIRECTORY prdType
, prdName
, prdLanguage
;
2926 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
, prde1
;
2927 PIMAGE_RESOURCE_DIR_STRING_U pMenuName
;
2928 PIMAGE_RESOURCE_DATA_ENTRY prData
;
2929 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
2930 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE);
2931 PIMAGE_MENU_HEADER pMenuHeader
;
2932 //PIMAGE_POPUP_MENU_ITEM pPopup;
2934 //PIMAGE_NORMAL_MENU_ITEM pNormal;
2936 int /*nCnt = 0,*/ i
, j
;
2939 int sLength
, nMenus
;
2943 //DWORD dwBase; obsolete
2944 char *pMem
/*, *pTemp*/;
2945 //BOOL isStrange = FALSE;
2948 /* get root directory of resource tree */
2949 if ((prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2950 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2953 /* set pointer to first resource type entry */
2954 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2955 ((DWORD
) prdType
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2957 for (i
= 0; i
< prdType
->NumberOfIdEntries
; i
++)
2959 if (prde
->Name
== RT_MENU
)
2963 if (prde
->Name
!= RT_MENU
)
2966 prdName
= (PIMAGE_RESOURCE_DIRECTORY
)
2967 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
2968 if (prdName
== NULL
)
2971 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2972 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2974 // sometimes previous code tells you lots of things hidden underneath
2975 // I wish I could save all the revisions I made ... but again .... sigh.
2976 // october 12, 1997 sang
2977 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2979 nMenus
= prdName
->NumberOfNamedEntries
+ prdName
->NumberOfIdEntries
;
2982 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
2984 pMenuName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
2985 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
2986 sLength
+= pMenuName
->Length
+ 1;
2988 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
2989 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
2990 if (prdLanguage
== NULL
)
2993 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2994 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2996 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
2997 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3001 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3002 GetActualAddress (lpFile
, prData
->OffsetToData
);
3005 // normally wVersion and cbHeaderSize should be zero
3006 // but if it is not then nothing is known to us...
3007 // so let's do our best ... namely guessing .... and trying ....
3008 // ... and suffering ...
3009 // it gave me many sleepless (not exactly but I like to say this) nights.
3013 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3016 pwd
= (WORD
*) ((DWORD
) pMenuHeader
+ 16);
3017 size
= prData
->Size
;
3018 // expect to return the length needed to report.
3019 // sixteen more bytes to do something
3020 sLength
+= 16 + size
;
3021 //StrangeMenuScan (&sLength, &pwd, size);
3027 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3030 flag
= (WORD
) MenuScan (&sLength
, (WORD
**) (&pPopup
));
3037 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3041 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3042 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3043 if (prdLanguage
== NULL
)
3046 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3047 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3049 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3050 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3054 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3055 GetActualAddress (lpFile
, prData
->OffsetToData
);
3057 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3059 pwd
= (WORD
*) ((DWORD
) pMenuHeader
+ 16);
3060 size
= prData
->Size
;
3061 // expect to return the length needed to report.
3062 // sixteen more bytes to do something
3063 sLength
+= 16 + size
;
3064 //StrangeMenuScan (&sLength, &pwd, size);
3070 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3073 flag
= (WORD
) MenuScan (&sLength
, (WORD
**) (&pPopup
));
3081 // allocate memory for menu names
3083 *pszResTypes
= (char *) calloc (sLength
, 1);
3085 pMem
= *pszResTypes
;
3087 // and start all over again
3089 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3090 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3092 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3094 pMenuName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3095 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3098 for (j
= 0; j
< pMenuName
->Length
; j
++)
3099 *pMem
++ = (char) (pMenuName
->NameString
[j
]);
3104 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3105 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3106 if (prdLanguage
== NULL
)
3109 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3110 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3112 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3113 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3117 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3118 GetActualAddress (lpFile
, prData
->OffsetToData
);
3120 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3122 pwd
= (WORD
*) ((DWORD
) pMenuHeader
);
3123 size
= prData
->Size
;
3124 strcpy (pMem
, ":::::::::::");
3126 *(int *) pMem
= size
;
3128 StrangeMenuFill (&pMem
, &pwd
, size
);
3134 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3137 flag
= (WORD
) MenuFill (&pMem
, (WORD
**) (&pPopup
));
3144 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3147 sprintf (buff
, "MenuId_%04lX", (prde
->Name
));
3148 strcpy (pMem
, buff
);
3149 pMem
+= strlen (buff
) + 1;
3151 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3152 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3153 if (prdLanguage
== NULL
)
3156 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3157 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3159 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3160 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3164 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3165 GetActualAddress (lpFile
, prData
->OffsetToData
);
3167 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3169 pwd
= (WORD
*) ((DWORD
) pMenuHeader
);
3170 size
= prData
->Size
;
3171 strcpy (pMem
, ":::::::::::");
3173 *(int *) pMem
= size
;
3175 StrangeMenuFill (&pMem
, &pwd
, size
);
3181 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3184 flag
= (WORD
) MenuFill (&pMem
, (WORD
**) (&pPopup
));
3197 // This function is written by sang cho
3200 /* print contents of menu */
3208 //WORD flag1, flag2;
3212 //return dumpMenu (psz, size);
3216 if (strncmp (ptr
, ":::::::::::", 11) != 0)
3218 printf ("\n#### I don't know why!!!");
3219 dumpMenu (psz
, 1024);
3229 return dumpMenu (psz
, num
);
3231 // I will write some code later...
3239 // This function is written by sang cho
3242 /* print contents of menu */
3249 int /*i, */ j
, k
, l
;
3250 WORD id
/*, num */ ;
3257 //num = *(WORD *)ptr;
3261 flag
= *(WORD
*) ptr
;
3262 if (flag
& 0x0010) // flag == popup
3266 for (j
= 0; j
< indent
; j
++)
3269 printf ("%s {Popup}\n", ptr
);
3270 ptr
+= strlen (ptr
) + 1;
3272 PrintMenu (indent
+ 5, psz
);
3275 else // ispopup == 0
3279 for (j
= 0; j
< indent
; j
++)
3287 if (strchr (buff
, 0x09) != NULL
)
3289 for (k
= 0; k
< l
; k
++)
3290 if (buff
[k
] == 0x09)
3292 for (j
= 0; j
< l
- k
; j
++)
3293 buff
[31 - j
] = buff
[l
- j
];
3294 for (j
= k
; j
< 32 + k
- l
; j
++)
3297 if (strchr (buff
, 0x08) != NULL
)
3299 for (k
= 0; k
< l
; k
++)
3300 if (buff
[k
] == 0x08)
3302 for (j
= 0; j
< l
- k
; j
++)
3303 buff
[31 - j
] = buff
[l
- j
];
3304 for (j
= k
; j
< 32 + k
- l
; j
++)
3307 printf ("%s", buff
);
3309 for (j
= l
; j
< 32; j
++)
3311 printf ("[ID=%04Xh]", id
);
3322 // This function is written by sang cho
3325 /* the format of menu is not known so I'll do my best */
3332 int i
, j
, k
, n
, l
, c
;
3338 for (i
= 0; i
< (size
/ 16) + 1; i
++)
3341 for (j
= 0; j
< 16; j
++)
3369 for (k
= 0; k
< l
; k
++)
3370 if (isprint (c
= buff
[k
]))
3387 // This function is written by sang cho
3390 /* scan dialog box and copy dialog box */
3392 GetContentsOfDialog (
3396 PIMAGE_RESOURCE_DIRECTORY prdType
, prdName
, prdLanguage
;
3397 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
, prde1
;
3398 PIMAGE_RESOURCE_DIR_STRING_U pDialogName
;
3399 PIMAGE_RESOURCE_DATA_ENTRY prData
;
3400 PIMAGE_DIALOG_HEADER pDialogHeader
;
3401 //PIMAGE_CONTROL_DATA pControlData;
3403 int /*nCnt = 0,*/ i
, j
;
3406 int sLength
, nDialogs
;
3410 char *pMem
/*, *pTemp*/;
3411 //BOOL isStrange = FALSE;
3414 /* get root directory of resource tree */
3415 if ((prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
3416 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
3419 /* set pointer to first resource type entry */
3420 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3421 ((DWORD
) prdType
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3423 for (i
= 0; i
< prdType
->NumberOfIdEntries
; i
++)
3425 if (prde
->Name
== RT_DIALOG
)
3429 if (prde
->Name
!= RT_DIALOG
)
3432 prdName
= (PIMAGE_RESOURCE_DIRECTORY
)
3433 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3434 if (prdName
== NULL
)
3437 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3438 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3441 nDialogs
= prdName
->NumberOfNamedEntries
+ prdName
->NumberOfIdEntries
;
3444 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3446 pDialogName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3447 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3448 sLength
+= pDialogName
->Length
+ 1;
3450 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3451 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3452 if (prdLanguage
== NULL
)
3455 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3456 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3458 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3459 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3463 size
= prData
->Size
;
3464 sLength
+= 4 + size
;
3467 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3471 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3472 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3473 if (prdLanguage
== NULL
)
3476 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3477 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3479 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3480 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3484 size
= prData
->Size
;
3485 sLength
+= 4 + size
;
3489 // allocate memory for menu names
3491 *pszResTypes
= (char *) calloc (sLength
, 1);
3493 pMem
= *pszResTypes
;
3495 // and start all over again
3497 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3498 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3500 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3502 pDialogName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3503 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3506 for (j
= 0; j
< pDialogName
->Length
; j
++)
3507 *pMem
++ = (char) (pDialogName
->NameString
[j
]);
3512 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3513 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3514 if (prdLanguage
== NULL
)
3517 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3518 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3520 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3521 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3525 pDialogHeader
= (PIMAGE_DIALOG_HEADER
)
3526 GetActualAddress (lpFile
, prData
->OffsetToData
);
3530 pwd
= (WORD
*) ((DWORD
) pDialogHeader
);
3531 size
= prData
->Size
;
3532 *(int *) pMem
= size
;
3534 StrangeMenuFill (&pMem
, &pwd
, size
);
3538 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3541 sprintf (buff
, "DialogId_%04lX", (prde
->Name
));
3542 strcpy (pMem
, buff
);
3543 pMem
+= strlen (buff
) + 1;
3545 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3546 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3547 if (prdLanguage
== NULL
)
3549 printf ("\nprdLanguage = NULL");
3553 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3554 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3556 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3557 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3560 printf ("\nprData = NULL");
3564 pDialogHeader
= (PIMAGE_DIALOG_HEADER
)
3565 GetActualAddress (lpFile
, prData
->OffsetToData
);
3568 pwd
= (WORD
*) ((DWORD
) pDialogHeader
);
3569 size
= prData
->Size
;
3570 *(int *) pMem
= size
;
3572 StrangeMenuFill (&pMem
, &pwd
, size
);
3582 // This function is written by sang cho
3585 /* print contents of dialog */
3587 PrintNameOrOrdinal (
3593 if (*(WORD
*) ptr
== 0xFFFF)
3596 printf ("%04X", *(WORD
*) ptr
);
3602 while (*(WORD
*) ptr
)
3604 printf ("%c", *ptr
);
3615 // This function is written by sang cho
3618 /* print contents of dialog */
3623 int i
/*, j, k, l, n, c*/;
3629 BOOL isStrange
= FALSE
;
3632 size
= *(int *) ptr
;
3636 // IStype of Dialog Header
3637 flag
= *(DWORD
*) ptr
;
3639 // check if flag is right or not
3640 // it has been observed that some dialog information is strange
3641 // and extra work is needed to fix that ... so let's try something
3644 if ((flag
& 0xFFFF0000) == 0xFFFF0000)
3646 flag
= *(DWORD
*) (ptr
+ 12);
3647 num
= *(short *) (ptr
+ 16);
3653 num
= *(short *) (ptr
+ 8);
3656 printf (", # of Controls=%03d, Caption:%c", num
, '"');
3659 if (*(WORD
*) ptr
== 0xFFFF)
3660 ptr
+= 4; // ordinal
3664 while (*(WORD
*) ptr
)
3670 if (*(WORD
*) ptr
== 0xFFFF)
3671 ptr
+= 4; // ordinal
3675 while (*(WORD
*) ptr
)
3681 while (*(WORD
*) ptr
)
3683 printf ("%c", *ptr
);
3690 if (flag
& 0x00000040)
3695 ptr
+= 2; // FONT size
3697 while (*(WORD
*) ptr
)
3700 ptr
+= 2; // double null
3704 // strange case adjust
3709 if ((ptr
- *psz
) % 4)
3710 ptr
+= 4 - ((ptr
- *psz
) % 4);
3712 // start reporting .. finally
3713 for (i
= 0; i
< num
; i
++)
3715 flag
= *(DWORD
*) ptr
;
3720 printf ("\n Control::%03d - ID:", i
+ 1);
3723 printf ("%04X, Class:", *(WORD
*) ptr
);
3727 if (*(WORD
*) ptr
== 0xFFFF)
3730 class = *(WORD
*) ptr
;
3744 printf ("LISTBOX ");
3747 printf ("SCROLLBAR");
3750 printf ("COMBOBOX ");
3753 printf ("%04X ", class);
3758 PrintNameOrOrdinal (&ptr
);
3763 PrintNameOrOrdinal (&ptr
);
3768 // strange case adjust
3773 if ((ptr
- *psz
) % 4)
3774 ptr
+= 4 - ((ptr
- *psz
) % 4);
3781 for (i=0; i<(size/16)+1; i++)
3784 for (j=0; j<16; j++)
3791 if (ptr >= pmax) break;
3793 if (n%4 == 0) printf (" ");
3795 n++; if (n%4 == 0) printf (" ");
3799 { n++; if (n%4 == 0) printf (" "); else printf (" "); }
3802 if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3804 if (ptr >= pmax) break;
3817 /* function indicates whether debug info has been stripped from file */
3819 IsDebugInfoStripped (
3822 PIMAGE_FILE_HEADER pfh
;
3824 pfh
= (PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
);
3826 return (pfh
->Characteristics
& IMAGE_FILE_DEBUG_STRIPPED
);
3832 /* retrieve the module name from the debug misc. structure */
3834 RetrieveModuleName (
3839 PIMAGE_DEBUG_DIRECTORY pdd
;
3840 PIMAGE_DEBUG_MISC pdm
= NULL
;
3843 if (!(pdd
= (PIMAGE_DEBUG_DIRECTORY
) ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_DEBUG
)))
3846 while (pdd
->SizeOfData
)
3848 if (pdd
->Type
== IMAGE_DEBUG_TYPE_MISC
)
3850 pdm
= (PIMAGE_DEBUG_MISC
) ((DWORD
) pdd
->PointerToRawData
+ (DWORD
) lpFile
);
3851 *pszModule
= (char *) calloc ((nCnt
= (strlen ((char *)pdm
->Data
))) + 1, 1);
3852 // may need some unicode business here...above
3853 bcopy (pdm
->Data
, *pszModule
, nCnt
);
3871 /* determine if this is a valid debug file */
3876 PIMAGE_SEPARATE_DEBUG_HEADER psdh
;
3878 psdh
= (PIMAGE_SEPARATE_DEBUG_HEADER
) lpFile
;
3880 return (psdh
->Signature
== IMAGE_SEPARATE_DEBUG_SIGNATURE
);
3886 /* copy separate debug header structure from debug file */
3888 GetSeparateDebugHeader (
3890 PIMAGE_SEPARATE_DEBUG_HEADER psdh
)
3892 PIMAGE_SEPARATE_DEBUG_HEADER pdh
;
3894 pdh
= (PIMAGE_SEPARATE_DEBUG_HEADER
) lpFile
;
3896 if (pdh
->Signature
== IMAGE_SEPARATE_DEBUG_SIGNATURE
)
3898 bcopy ((LPVOID
) pdh
, (LPVOID
) psdh
, sizeof (IMAGE_SEPARATE_DEBUG_HEADER
));
3906 // I tried to immitate the output of w32dasm disassembler.
3907 // which is a pretty good program.
3908 // but I am disappointed with this program and I myself
3909 // am writting a disassembler.
3910 // This PEdump program is a byproduct of that project.
3911 // so enjoy this program and I hope we will have a little more
3912 // knowledge on windows programming world.
3915 #define MAXSECTIONNUMBER 16
3916 #define MAXNAMESTRNUMBER 40
3926 IMAGE_DOS_HEADER dosHdr
;
3927 PIMAGE_FILE_HEADER pfh
;
3928 PIMAGE_OPTIONAL_HEADER poh
;
3929 PIMAGE_SECTION_HEADER psh
;
3930 //IMAGE_SECTION_HEADER idsh;
3931 IMAGE_SECTION_HEADER shdr
[MAXSECTIONNUMBER
];
3932 //PIMAGE_IMPORT_MODULE_DIRECTORY pid;
3934 int nSections
; // number of sections
3936 int nResources
; // number of resources
3938 int nMenus
; // number of menus
3940 int nDialogs
; // number of dialogs
3942 int nImportedModules
; // number of imported modules
3944 int nFunctions
; // number of functions in the imported module
3946 int nExportedFunctions
; // number of exported funcions
3958 char *piNameBuff
; // import module name buffer
3960 char *pfNameBuff
; // import functions in the module name buffer
3962 char *peNameBuff
; // export function name buffer
3964 char *pmNameBuff
; // menu name buffer
3966 char *pdNameBuff
; // dialog name buffer
3969 * Check user arguments.
3973 my_fp
= fopen (argv
[1], "rb");
3977 "%s: can not open input file \"%s\".\n",
3987 "%s - PE/COFF file dumper\n"
3988 "Copyright (c) 1993 Randy Kath (MSDN Technology Group)\n"
3989 "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)\n"
3990 "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)\n\n",
3994 "usage: %s input_file_name\n",
4000 * Get input file's size.
4003 fseek (my_fp
, 0L, SEEK_END
);
4004 fsize
= ftell (my_fp
);
4007 * Buffer the file in memory.
4009 lpFile
= (void *) calloc (fsize
, 1);
4013 "%s: can not allocate memory.\n",
4020 * --- Start of report ---
4022 printf ("\n\nDump of file: %s\n\n", argv
[1]);
4024 n
= fread (lpFile
, fsize
, 1, my_fp
);
4030 "%s: failed to read the file \"%s\".\n",
4038 GetDosHeader (lpFile
, &dosHdr
);
4040 if ((WORD
) IMAGE_DOS_SIGNATURE
== dosHdr
.e_magic
)
4042 if ((dosHdr
.e_lfanew
> 4096)
4043 || (dosHdr
.e_lfanew
< 64)
4047 "%s: This file is not in PE format; it looks like in DOS format.\n",
4057 "%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4065 fileType
= ImageFileType (lpFile
);
4067 if (fileType
!= IMAGE_NT_SIGNATURE
)
4070 "%s: This file is not in PE format (magic = 0x%08lx).\n",
4078 //=====================================
4079 // now we can really start processing
4080 //=====================================
4082 pfh
= (PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
);
4084 poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
4086 psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
4088 nSections
= pfh
->NumberOfSections
;
4090 imageBase
= poh
->ImageBase
;
4092 entryPoint
= poh
->AddressOfEntryPoint
;
4100 /* store section headers */
4110 * Get Code offset and size,
4111 * Data offset and size.
4118 if (poh
->BaseOfCode
== shdr
[i
].VirtualAddress
)
4121 "Code Offset = %08lX, Code Size = %08lX \n",
4122 shdr
[i
].PointerToRawData
,
4123 shdr
[i
].SizeOfRawData
4126 if (((shdr
[i
].Characteristics
) & 0xC0000040) == 0xC0000040)
4129 "Data Offset = %08lX, Data Size = %08lX \n",
4130 shdr
[i
].PointerToRawData
,
4131 shdr
[i
].SizeOfRawData
4140 "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
4145 * Object name alignment.
4157 if (shdr
[i
].Name
[j
] == 0)
4159 shdr
[i
].Name
[j
] = 32;
4162 shdr
[i
].Name
[7] = 0;
4164 for (i
= 0; i
< nSections
; i
++)
4165 printf ("\n Object%02d: %8s RVA: %08lX Offset: %08lX Size: %08lX Flags: %08lX ",
4166 i
+ 1, shdr
[i
].Name
, shdr
[i
].VirtualAddress
, shdr
[i
].PointerToRawData
,
4167 shdr
[i
].SizeOfRawData
, shdr
[i
].Characteristics
);
4169 * Get List of Resources.
4171 nResources
= GetListOfResourceTypes (lpFile
, &pnstr
);
4174 printf ("\n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++");
4176 if (nResources
== 0)
4177 printf ("\n There are no Resources in This Application.\n");
4180 printf ("\nNumber of Resource Types = %4d (decimal)\n", nResources
);
4181 for (i
= 0; i
< nResources
; i
++)
4183 printf ("\n Resource Type %03d: %s", i
+ 1, pst
);
4184 pst
+= strlen ((char *) (pst
)) + 1;
4186 free ((void *) pnstr
);
4189 printf ("\n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++");
4192 nMenus
= GetContentsOfMenu (lpFile
, &pmNameBuff
);
4196 printf ("\n There are no Menus in This Application.\n");
4201 printf ("\nNumber of Menus = %4d (decimal)", nMenus
);
4203 //dumpMenu(&pst, 8096);
4204 for (i
= 0; i
< nMenus
; i
++)
4207 printf ("\n\n%s", pst
);
4208 pst
+= strlen (pst
) + 1;
4209 printf ("\n-------------");
4210 if (strncmp (pst
, ":::::::::::", 11) == 0)
4213 PrintStrangeMenu (&pst
);
4217 PrintMenu (6, &pst
);
4219 //else PrintStrangeMenu(&pst);
4221 free ((void *) pmNameBuff
);
4226 printf ("\n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++");
4229 nDialogs
= GetContentsOfDialog (lpFile
, &pdNameBuff
);
4233 printf ("\n There are no Dialogs in This Application.\n");
4238 printf ("\nNumber of Dialogs = %4d (decimal)", nDialogs
);
4242 for (i
= 0; i
< nDialogs
; i
++)
4245 printf ("\nName: %s", pst
);
4246 pst
+= strlen (pst
) + 1;
4249 free ((void *) pdNameBuff
);
4254 printf ("\n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++");
4256 nImportedModules
= GetImportModuleNames (lpFile
, &piNameBuff
);
4257 if (nImportedModules
== 0)
4259 printf ("\n There are no imported Functions in This Application.\n");
4264 printf ("\nNumber of Imported Modules = %4d (decimal)\n", nImportedModules
);
4265 for (i
= 0; i
< nImportedModules
; i
++)
4267 printf ("\n Import Module %03d: %s", i
+ 1, pnstr
);
4268 pnstr
+= strlen ((char *) (pnstr
)) + 1;
4272 printf ("\n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++");
4274 for (i
= 0; i
< nImportedModules
; i
++)
4276 printf ("\n\n Import Module %03d: %s \n", i
+ 1, pnstr
);
4277 nFunctions
= GetImportFunctionNamesByModule (lpFile
, pnstr
, &pfNameBuff
);
4278 pnstr
+= strlen ((char *) (pnstr
)) + 1;
4280 for (j
= 0; j
< nFunctions
; j
++)
4282 printf ("\nAddr:%08X hint(%04X) Name: %s",
4283 (*(int *) pst
), (*(short *) (pst
+ 4)),
4285 TranslateFunctionName (pst
+ 6));
4286 pst
+= strlen ((char *) (pst
+ 6)) + 1 + 6;
4288 free ((void *) pfNameBuff
);
4290 free ((void *) piNameBuff
);
4294 printf ("\n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++");
4296 nExportedFunctions
= GetExportFunctionNames (lpFile
, &peNameBuff
);
4297 printf ("\nNumber of Exported Functions = %4d (decimal)\n", nExportedFunctions
);
4299 if (nExportedFunctions
> 0)
4303 for (i
= 0; i
< nExportedFunctions
; i
++)
4305 printf ("\nAddr:%08X Ord:%4d (%04Xh) Name: %s",
4306 (*(int *) pst
), (*(WORD
*) (pst
+ 4)), (*(WORD
*) (pst
+ 4)),
4308 TranslateFunctionName (pst
+ 6));
4309 pst
+= strlen ((char *) (pst
+ 6)) + 6 + 1;
4311 free ((void *) peNameBuff
);
4314 free ((void *) lpFile
);