3 // This program was written by Sang Cho, assistant professor at
5 // computer science and engineering
7 // this program is based on the program pefile.c
8 // which is written by Randy Kath(Microsoft Developmer Network Technology Group)
10 // I have investigated P.E. file format as thoroughly as possible,
11 // but I cannot claim that I am an expert yet, so some of its information
12 // may give you wrong results.
16 // language used: djgpp
17 // date of creation: September 28, 1997
19 // date of first release: October 15, 1997
22 // you can contact me: e-mail address: sangcho@alpha94.chongju.ac.kr
24 // phone number: (0431) 229-8491 +82-431-229-8491
28 // Copyright (C) 1997. by Sang Cho.
30 // Permission is granted to make and distribute verbatim copies of this
31 // program provided the copyright notice and this permission notice are
32 // preserved on all copies.
35 // File: pedump.c ( I included header file into source file. )
38 // Sources released under GNU General Public License version 2
39 // or later by Mr. Sang Cho permission.
42 // 2000-04-23 (ea) Initial adaptation to GCC/MinGW/ROS.
43 // 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 (
1961 static char buff
[512]; // result of translation
1964 char pStack
[32]; // parameter processing stack
1966 Str_P sStack
[32]; // String processing stack
1968 Str_P tok
; // String token
1970 Str_P c_str
; // current string
1973 char *endTab
[8]; // end of string position check
1977 BOOL stringMode
= TRUE
;
1985 //................................................................
1986 // serious users may need to run the following code.
1987 // so I may need to include some flag options...
1988 // If you want to know about how translation is done,
1989 // you can just revive following line and you can see it.
1990 // october 6, 1997 ... sang cho
1991 //printf ("\n................................... %s", psz); // for debugging...
1998 tok
.wasString
= stringMode
;
1999 sStack
[is
++] = tok
; // initialize sStack with dummy marker
2007 //---------------------------------------------
2008 // check for the end of number specified string
2009 //---------------------------------------------
2013 for (i
= 0; i
< iend
; i
++)
2014 if (pin
== endTab
[i
])
2018 // move the end of endTab to ith position
2019 endTab
[i
] = endTab
[iend
- 1];
2022 // get top of the string stack
2023 tok
= sStack
[is
- 1];
2025 // I am expecting '#' token from stack
2026 if (tok
.flag
!= '#')
2029 printf ("\n**some serious error1** %c is = %d char = %c",
2030 tok
.flag
, is
, *pin
);
2034 // pop '#' token I am happy now.
2037 //printf("\n pop # token ... current char = %c", c);
2038 //else printf("\n pop percent token..next char = NULL");
2043 stringMode
= tok
.wasString
;
2047 // need to process postfix finally
2049 if (strchr ("qtx", cc
))
2051 if (!strchr ("@$%", c
))
2059 strcpy (pout
, "*&");
2064 strcpy (pout
, "**");
2079 strcpy (pout
, "!3!");
2084 if (!strchr ("@$%", c
))
2088 // string mode restored...
2091 else; // do nothing..
2095 //------------------------------------------------
2096 // special control symbol processing:
2097 //------------------------------------------------
2099 if (strchr ("@$%", c
))
2102 //---------------------------------------------------------------
2103 // string part processing : no '$' met yet
2104 // or inside of '%' block
2105 // or inside of '#' block (numbered string)
2106 //---------------------------------------------------------------
2108 else if (stringMode
)
2110 //else if (is > 1) *pout++ = *pin++;
2112 //------------------------------------------------
2113 // parameter part processing: '$' met
2114 //------------------------------------------------
2116 else // parameter processing
2120 TranslateParameters (&pin
, &pout
, &ps
);
2121 else // number specified string processing
2124 n
= GetStringLength (pin
);
2132 //printf("\n push # token .. char = %c", *pin);
2133 //else printf("\n push percent token..next char = NULL");
2137 tok
.wasString
= stringMode
;
2140 // mark end of input string
2141 endTab
[iend
++] = pin
+ n
;
2145 } // end of inner while loop
2147 // beginning of new string or end of string ( quotation mark )
2152 pin
++; // anyway we have to proceed...
2154 tok
= sStack
[is
- 1]; // get top of the sStack
2156 if (tok
.flag
== '%')
2158 // pop '%' token and set c_str
2160 //printf("\n pop percent token..next char = %c", *pin);
2161 //else printf("\n pop percent token..next char = NULL");
2164 c_str
.length
= pout
- c_str
.pos
;
2165 if (*(ps
- 1) == 't')
2169 stringMode
= tok
.wasString
;
2173 printf ("\n**some string error3** stack = %c", *(ps
- 1));
2177 else if (tok
.flag
== 'A' || tok
.flag
== '#')
2181 //printf("\n push percent token..next char = %c", *pin);
2182 //else printf("\n push percent token..next char = NULL");
2186 tok
.wasString
= stringMode
;
2191 printf ("\n**some string error5**");
2196 // sometimes we need string to use as constructor name or destructor name
2198 else if (c
== '@') // get string from previous marker upto here.
2202 tok
= sStack
[is
- 1];
2204 c_str
.pos
= tok
.pos
;
2205 c_str
.length
= pout
- tok
.pos
;
2206 c_str
.wasString
= stringMode
;
2211 // we need to take care of parameter control sequence
2213 else if (c
== '$') // need to precess template or parameter part
2218 stringMode
= StringExpands (&pin
, &pout
, &ps
, &c_str
);
2220 { // template parameter mode I guess "$t"
2228 printf ("\nMYGOODNESS1 %c", *pin
);
2232 //if (*ps == 't') *pout++ = '>';
2233 //else { printf("\nMYGOODNESS2"); exit(0);}
2234 *pout
++ = ','; //pin++; ..this almost blowed me....
2237 // real parameter mode I guess
2238 // unexpected case is found ... humm what can I do...
2241 // this is newly found twist.. it really hurts.
2252 printf ("\n** I GIVEUP ***");
2262 else if (*ps
== '&')
2264 else if (*ps
== 'p')
2269 else if (*ps
== 'r')
2276 printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin
);
2287 else if (*ps
== '&')
2289 else if (*ps
== 'p')
2294 else if (*ps
== 'r')
2301 printf ("\n*** SOMETHING IS WRONG2***");
2310 } // end of '$' processing
2312 } // end of outer while loop
2314 // need to process remaining parameter stack
2329 strcpy (pout
, " const");
2333 strcpy (pout
, "*&");
2337 strcpy (pout
, "**");
2347 strcpy (pout
, "!4!");
2359 // This function is written by sang cho
2362 /* get exported function names separated by null terminators, return count of functions */
2364 GetExportFunctionNames (
2366 char **pszFunctions
)
2368 //PIMAGE_SECTION_HEADER psh;
2369 PIMAGE_EXPORT_DIRECTORY ped
;
2371 DWORD imageBase
; //===========================
2374 {NULL
,}; // maximum number of functions
2375 //=============================
2377 char buff
[256]; // enough for any string ??
2379 char *psz
= NULL
; //===============================
2385 int i
, nCnt
= 0, ntmp
= 0;
2386 int enid
= 0, ordBase
= 1; // usally ordBase is 1....
2390 /* get section header and pointer to data directory for .edata section */
2391 ped
= (PIMAGE_EXPORT_DIRECTORY
)
2392 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_EXPORT
);
2398 // sometimes there may be no section for idata or edata
2399 // instead rdata or data section may contain these sections ..
2400 // or even module names or function names are in different section.
2401 // so that's why we need to get actual address each time.
2402 // ...................sang cho..................
2404 //psh = (PIMAGE_SECTION_HEADER)
2405 //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2407 //if (psh == NULL) return 0;
2409 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2412 /* determine the offset of the export function names */
2414 pdwAddress
= (DWORD
*) GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfFunctions
);
2416 imageBase
= (DWORD
) GetImageBase (lpFile
);
2418 ordBase
= ped
->Base
;
2420 if (ped
->NumberOfNames
> 0)
2422 pdwNames
= (DWORD
*)
2423 GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNames
);
2425 GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNameOrdinals
);
2428 /* figure out how much memory to allocate for all strings */
2429 for (i
= 0; i
< (int) ped
->NumberOfNames
; i
++)
2431 nCnt
+= strlen ((char *)
2432 GetActualAddress (lpFile
, *(DWORD
*) pdwNames
)) + 1 + 6;
2435 // get the number of unnamed functions
2436 for (i
= 0; i
< (int) ped
->NumberOfFunctions
; i
++)
2439 // add memory required to show unnamed functions.
2440 if (ntmp
> (int) ped
->NumberOfNames
)
2441 nCnt
+= 18 * (ntmp
- (int) ped
->NumberOfNames
);
2443 /* allocate memory for function names */
2445 *pszFunctions
= (char *) calloc (nCnt
, 1);
2446 pdwNames
= (DWORD
*) GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNames
);
2448 /* copy string pointer to buffer */
2450 for (i
= 0; i
< (int) ped
->NumberOfNames
; i
++)
2452 pfns
[(int) (*pwOrd
) + ordBase
] =
2453 (char *) GetActualAddress (lpFile
, *(DWORD
*) pdwNames
);
2458 psz
= *pszFunctions
;
2461 for (i
= ordBase
; i
< (int) ped
->NumberOfFunctions
+ ordBase
; i
++)
2463 if (*pdwAddress
> 0)
2465 *(DWORD
*) psz
= imageBase
+ *pdwAddress
;
2467 *(WORD
*) psz
= (WORD
) (i
);
2471 strcpy (psz
, pfns
[i
]);
2472 psz
+= strlen (psz
) + 1;
2476 sprintf (buff
, "ExpFn%04d()", enid
++);
2490 /* determine the total number of resources in the section */
2492 GetNumberOfResources (
2495 PIMAGE_RESOURCE_DIRECTORY prdRoot
, prdType
;
2496 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
;
2500 /* get root directory of resource tree */
2501 if ((prdRoot
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2502 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2505 /* set pointer to first resource type entry */
2506 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) ((DWORD
) prdRoot
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2508 /* loop through all resource directory entry types */
2509 for (i
= 0; i
< prdRoot
->NumberOfIdEntries
; i
++)
2511 /* locate directory or each resource type */
2512 prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ((int) prdRoot
+ (int) prde
->OffsetToData
);
2514 /* mask off most significant bit of the data offset */
2515 prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ((DWORD
) prdType
^ 0x80000000);
2517 /* increment count of name'd and ID'd resources in directory */
2518 nCnt
+= prdType
->NumberOfNamedEntries
+ prdType
->NumberOfIdEntries
;
2520 /* increment to next entry */
2530 // This function is rewritten by sang cho
2533 /* name each type of resource in the section */
2535 GetListOfResourceTypes (
2539 PIMAGE_RESOURCE_DIRECTORY prdRoot
;
2540 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
;
2547 /* get root directory of resource tree */
2548 if ((prdRoot
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2549 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2552 /* allocate enuff space to cover all types */
2553 nCnt
= prdRoot
->NumberOfIdEntries
* (MAXRESOURCENAME
+ 1);
2554 *pszResTypes
= (char *) calloc (nCnt
, 1);
2555 if ((pMem
= *pszResTypes
) == NULL
)
2558 /* set pointer to first resource type entry */
2559 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) ((DWORD
) prdRoot
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2561 /* loop through all resource directory entry types */
2562 for (i
= 0; i
< prdRoot
->NumberOfIdEntries
; i
++)
2564 prdeName
= prde
->Name
;
2566 //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2567 // pMem += strlen (pMem) + 1;
2569 // modified by ...................................Sang Cho..
2570 // I can't user M/S provied funcitons here so I have to figure out
2571 // how to do above functions. But I can settle down with the following
2572 // code, which works pretty good for me.
2576 strcpy (pMem
, "RT_CURSOR");
2579 else if (prdeName
== 2)
2581 strcpy (pMem
, "RT_BITMAP");
2584 else if (prdeName
== 3)
2586 strcpy (pMem
, "RT_ICON ");
2589 else if (prdeName
== 4)
2591 strcpy (pMem
, "RT_MENU ");
2594 else if (prdeName
== 5)
2596 strcpy (pMem
, "RT_DIALOG");
2599 else if (prdeName
== 6)
2601 strcpy (pMem
, "RT_STRING");
2604 else if (prdeName
== 7)
2606 strcpy (pMem
, "RT_FONTDIR");
2609 else if (prdeName
== 8)
2611 strcpy (pMem
, "RT_FONT ");
2614 else if (prdeName
== 9)
2616 strcpy (pMem
, "RT_ACCELERATORS");
2619 else if (prdeName
== 10)
2621 strcpy (pMem
, "RT_RCDATA");
2624 else if (prdeName
== 11)
2626 strcpy (pMem
, "RT_MESSAGETABLE");
2629 else if (prdeName
== 12)
2631 strcpy (pMem
, "RT_GROUP_CURSOR");
2634 else if (prdeName
== 14)
2636 strcpy (pMem
, "RT_GROUP_ICON ");
2639 else if (prdeName
== 16)
2641 strcpy (pMem
, "RT_VERSION");
2644 else if (prdeName
== 17)
2646 strcpy (pMem
, "RT_DLGINCLUDE ");
2649 else if (prdeName
== 19)
2651 strcpy (pMem
, "RT_PLUGPLAY ");
2654 else if (prdeName
== 20)
2656 strcpy (pMem
, "RT_VXD ");
2659 else if (prdeName
== 21)
2661 strcpy (pMem
, "RT_ANICURSOR ");
2664 else if (prdeName
== 22)
2666 strcpy (pMem
, "RT_ANIICON");
2669 else if (prdeName
== 0x2002)
2671 strcpy (pMem
, "RT_NEWBITMAP");
2674 else if (prdeName
== 0x2004)
2676 strcpy (pMem
, "RT_NEWMENU");
2679 else if (prdeName
== 0x2005)
2681 strcpy (pMem
, "RT_NEWDIALOG");
2684 else if (prdeName
== 0x7fff)
2686 strcpy (pMem
, "RT_ERROR ");
2691 sprintf (buff
, "RT_UNKNOWN:%08lX", prdeName
);
2692 strcpy (pMem
, buff
);
2698 return prdRoot
->NumberOfIdEntries
;
2704 // This function is written by sang cho
2707 /* copy menu information */
2710 char **psz
, // results
2711 WORD
** pMenu
, // read-only
2718 pmax
= (WORD
*) ((DWORD
) pwd
+ size
);
2719 ptr
= (WORD
*) (*psz
);
2725 *psz
= (char *) ptr
;
2732 // This function is written by sang cho
2735 /* obtain menu information */
2750 flag
= *pwd
; // so difficult to correctly code this so let's try this
2753 (*len
) += 2; // flag store
2755 if ((flag
& 0x0010) == 0)
2760 (*len
) += 2; // id store
2773 (*len
)++; // name and null character
2775 pwd
++; // skip double null
2777 if ((flag
& 0x0010) == 0) // normal node: done
2783 // popup node: need to go on...
2787 flag1
= (WORD
) MenuScan (len
, pMenu
);
2792 // fill # of details to num above
2800 // This function is written by sang cho
2803 /* copy menu information */
2811 char *ptr
/*, *pTemp*/;
2814 WORD id
/*, ispopup*/;
2818 //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2819 flag
= *pwd
; // so difficult to correctly code this so let's try this
2822 if ((flag
& 0x0010) == 0)
2824 *(WORD
*) ptr
= flag
; // flag store
2827 *(WORD
*) ptr
= id
= *pwd
; // id store
2834 *(WORD
*) ptr
= flag
; // flag store
2839 while (*pwd
) // name extract
2842 *ptr
= *(char *) pwd
;
2845 } //name and null character
2849 pwd
++; // skip double null
2851 if ((flag
& 0x0010) == 0) // normal node: done
2860 // popup node: need to go on...
2866 flag1
= (WORD
) MenuFill (psz
, pMenu
);
2872 // fill # of details to num above
2873 //*(WORD *)pTemp = (WORD)num;
2881 //==============================================================================
2882 // The following program is based on preorder-tree-traversal.
2883 // once you understand how to traverse.....
2884 // the rest is pretty straight forward.
2885 // still we need to scan it first and fill it next time.
2886 // and finally we can print it.
2888 // This function is written by sang cho
2889 // September 29, 1997
2890 // revised october 2, 1997
2891 // revised october 12, 1997
2892 // ..............................................................................
2893 // ------------------------------------------------------------------------------
2894 // I use same structure - which is used in P.E. programs - for my reporting.
2895 // So, my structure is as follows:
2896 // # of menu name is stored else where ( in directory I suppose )
2897 // supermenuname null terminated string, only ascii is considered.
2898 // flag tells : node is a leaf or a internal node.
2899 // popupname null terminated string
2901 // flag normal menu flag (leaf node)
2902 // id normal menu id
2903 // name normal menu name
2905 // flag popup menu flag (internal node)
2906 // popupname popup menu name
2908 // flag it may folows
2909 // id normal menu id
2910 // name normal menu name
2913 // popupname popup menu name
2915 // it goes on like this,
2916 // but usually, it only goes a few steps,...
2917 // ------------------------------------------------------------------------------
2918 /* scan menu and copy menu */
2924 PIMAGE_RESOURCE_DIRECTORY prdType
, prdName
, prdLanguage
;
2925 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
, prde1
;
2926 PIMAGE_RESOURCE_DIR_STRING_U pMenuName
;
2927 PIMAGE_RESOURCE_DATA_ENTRY prData
;
2928 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
2929 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE);
2930 PIMAGE_MENU_HEADER pMenuHeader
;
2931 //PIMAGE_POPUP_MENU_ITEM pPopup;
2933 //PIMAGE_NORMAL_MENU_ITEM pNormal;
2935 int /*nCnt = 0,*/ i
, j
;
2938 int sLength
, nMenus
;
2942 //DWORD dwBase; obsolete
2943 char *pMem
/*, *pTemp*/;
2944 //BOOL isStrange = FALSE;
2947 /* get root directory of resource tree */
2948 if ((prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2949 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2952 /* set pointer to first resource type entry */
2953 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2954 ((DWORD
) prdType
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2956 for (i
= 0; i
< prdType
->NumberOfIdEntries
; i
++)
2958 if (prde
->Name
== RT_MENU
)
2962 if (prde
->Name
!= RT_MENU
)
2965 prdName
= (PIMAGE_RESOURCE_DIRECTORY
)
2966 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
2967 if (prdName
== NULL
)
2970 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2971 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2973 // sometimes previous code tells you lots of things hidden underneath
2974 // I wish I could save all the revisions I made ... but again .... sigh.
2975 // october 12, 1997 sang
2976 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2978 nMenus
= prdName
->NumberOfNamedEntries
+ prdName
->NumberOfIdEntries
;
2981 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
2983 pMenuName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
2984 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
2985 sLength
+= pMenuName
->Length
+ 1;
2987 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
2988 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
2989 if (prdLanguage
== NULL
)
2992 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2993 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2995 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
2996 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3000 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3001 GetActualAddress (lpFile
, prData
->OffsetToData
);
3004 // normally wVersion and cbHeaderSize should be zero
3005 // but if it is not then nothing is known to us...
3006 // so let's do our best ... namely guessing .... and trying ....
3007 // ... and suffering ...
3008 // it gave me many sleepless (not exactly but I like to say this) nights.
3012 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3015 pwd
= (WORD
*) ((DWORD
) pMenuHeader
+ 16);
3016 size
= prData
->Size
;
3017 // expect to return the length needed to report.
3018 // sixteen more bytes to do something
3019 sLength
+= 16 + size
;
3020 //StrangeMenuScan (&sLength, &pwd, size);
3026 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3029 flag
= (WORD
) MenuScan (&sLength
, (WORD
**) (&pPopup
));
3036 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3040 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3041 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3042 if (prdLanguage
== NULL
)
3045 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3046 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3048 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3049 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3053 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3054 GetActualAddress (lpFile
, prData
->OffsetToData
);
3056 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3058 pwd
= (WORD
*) ((DWORD
) pMenuHeader
+ 16);
3059 size
= prData
->Size
;
3060 // expect to return the length needed to report.
3061 // sixteen more bytes to do something
3062 sLength
+= 16 + size
;
3063 //StrangeMenuScan (&sLength, &pwd, size);
3069 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3072 flag
= (WORD
) MenuScan (&sLength
, (WORD
**) (&pPopup
));
3080 // allocate memory for menu names
3082 *pszResTypes
= (char *) calloc (sLength
, 1);
3084 pMem
= *pszResTypes
;
3086 // and start all over again
3088 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3089 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3091 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3093 pMenuName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3094 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3097 for (j
= 0; j
< pMenuName
->Length
; j
++)
3098 *pMem
++ = (char) (pMenuName
->NameString
[j
]);
3103 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3104 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3105 if (prdLanguage
== NULL
)
3108 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3109 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3111 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3112 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3116 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3117 GetActualAddress (lpFile
, prData
->OffsetToData
);
3119 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3121 pwd
= (WORD
*) ((DWORD
) pMenuHeader
);
3122 size
= prData
->Size
;
3123 strcpy (pMem
, ":::::::::::");
3125 *(int *) pMem
= size
;
3127 StrangeMenuFill (&pMem
, &pwd
, size
);
3133 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3136 flag
= (WORD
) MenuFill (&pMem
, (WORD
**) (&pPopup
));
3143 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3146 sprintf (buff
, "MenuId_%04lX", (prde
->Name
));
3147 strcpy (pMem
, buff
);
3148 pMem
+= strlen (buff
) + 1;
3150 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3151 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3152 if (prdLanguage
== NULL
)
3155 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3156 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3158 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3159 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3163 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3164 GetActualAddress (lpFile
, prData
->OffsetToData
);
3166 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3168 pwd
= (WORD
*) ((DWORD
) pMenuHeader
);
3169 size
= prData
->Size
;
3170 strcpy (pMem
, ":::::::::::");
3172 *(int *) pMem
= size
;
3174 StrangeMenuFill (&pMem
, &pwd
, size
);
3180 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3183 flag
= (WORD
) MenuFill (&pMem
, (WORD
**) (&pPopup
));
3196 // This function is written by sang cho
3199 /* print contents of menu */
3207 //WORD flag1, flag2;
3211 //return dumpMenu (psz, size);
3215 if (strncmp (ptr
, ":::::::::::", 11) != 0)
3217 printf ("\n#### I don't know why!!!");
3218 dumpMenu (psz
, 1024);
3228 return dumpMenu (psz
, num
);
3230 // I will write some code later...
3238 // This function is written by sang cho
3241 /* print contents of menu */
3248 int /*i, */ j
, k
, l
;
3249 WORD id
/*, num */ ;
3256 //num = *(WORD *)ptr;
3260 flag
= *(WORD
*) ptr
;
3261 if (flag
& 0x0010) // flag == popup
3265 for (j
= 0; j
< indent
; j
++)
3268 printf ("%s {Popup}\n", ptr
);
3269 ptr
+= strlen (ptr
) + 1;
3271 PrintMenu (indent
+ 5, psz
);
3274 else // ispopup == 0
3278 for (j
= 0; j
< indent
; j
++)
3286 if (strchr (buff
, 0x09) != NULL
)
3288 for (k
= 0; k
< l
; k
++)
3289 if (buff
[k
] == 0x09)
3291 for (j
= 0; j
< l
- k
; j
++)
3292 buff
[31 - j
] = buff
[l
- j
];
3293 for (j
= k
; j
< 32 + k
- l
; j
++)
3296 if (strchr (buff
, 0x08) != NULL
)
3298 for (k
= 0; k
< l
; k
++)
3299 if (buff
[k
] == 0x08)
3301 for (j
= 0; j
< l
- k
; j
++)
3302 buff
[31 - j
] = buff
[l
- j
];
3303 for (j
= k
; j
< 32 + k
- l
; j
++)
3306 printf ("%s", buff
);
3308 for (j
= l
; j
< 32; j
++)
3310 printf ("[ID=%04Xh]", id
);
3321 // This function is written by sang cho
3324 /* the format of menu is not known so I'll do my best */
3331 int i
, j
, k
, n
, l
, c
;
3337 for (i
= 0; i
< (size
/ 16) + 1; i
++)
3340 for (j
= 0; j
< 16; j
++)
3368 for (k
= 0; k
< l
; k
++)
3369 if (isprint (c
= buff
[k
]))
3386 // This function is written by sang cho
3389 /* scan dialog box and copy dialog box */
3391 GetContentsOfDialog (
3395 PIMAGE_RESOURCE_DIRECTORY prdType
, prdName
, prdLanguage
;
3396 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
, prde1
;
3397 PIMAGE_RESOURCE_DIR_STRING_U pDialogName
;
3398 PIMAGE_RESOURCE_DATA_ENTRY prData
;
3399 PIMAGE_DIALOG_HEADER pDialogHeader
;
3400 //PIMAGE_CONTROL_DATA pControlData;
3402 int /*nCnt = 0,*/ i
, j
;
3405 int sLength
, nDialogs
;
3409 char *pMem
/*, *pTemp*/;
3410 //BOOL isStrange = FALSE;
3413 /* get root directory of resource tree */
3414 if ((prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
3415 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
3418 /* set pointer to first resource type entry */
3419 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3420 ((DWORD
) prdType
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3422 for (i
= 0; i
< prdType
->NumberOfIdEntries
; i
++)
3424 if (prde
->Name
== RT_DIALOG
)
3428 if (prde
->Name
!= RT_DIALOG
)
3431 prdName
= (PIMAGE_RESOURCE_DIRECTORY
)
3432 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3433 if (prdName
== NULL
)
3436 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3437 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3440 nDialogs
= prdName
->NumberOfNamedEntries
+ prdName
->NumberOfIdEntries
;
3443 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3445 pDialogName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3446 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3447 sLength
+= pDialogName
->Length
+ 1;
3449 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3450 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3451 if (prdLanguage
== NULL
)
3454 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3455 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3457 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3458 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3462 size
= prData
->Size
;
3463 sLength
+= 4 + size
;
3466 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3470 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3471 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3472 if (prdLanguage
== NULL
)
3475 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3476 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3478 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3479 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3483 size
= prData
->Size
;
3484 sLength
+= 4 + size
;
3488 // allocate memory for menu names
3490 *pszResTypes
= (char *) calloc (sLength
, 1);
3492 pMem
= *pszResTypes
;
3494 // and start all over again
3496 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3497 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3499 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3501 pDialogName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3502 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3505 for (j
= 0; j
< pDialogName
->Length
; j
++)
3506 *pMem
++ = (char) (pDialogName
->NameString
[j
]);
3511 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3512 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3513 if (prdLanguage
== NULL
)
3516 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3517 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3519 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3520 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3524 pDialogHeader
= (PIMAGE_DIALOG_HEADER
)
3525 GetActualAddress (lpFile
, prData
->OffsetToData
);
3529 pwd
= (WORD
*) ((DWORD
) pDialogHeader
);
3530 size
= prData
->Size
;
3531 *(int *) pMem
= size
;
3533 StrangeMenuFill (&pMem
, &pwd
, size
);
3537 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3540 sprintf (buff
, "DialogId_%04lX", (prde
->Name
));
3541 strcpy (pMem
, buff
);
3542 pMem
+= strlen (buff
) + 1;
3544 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3545 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3546 if (prdLanguage
== NULL
)
3548 printf ("\nprdLanguage = NULL");
3552 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3553 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3555 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3556 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3559 printf ("\nprData = NULL");
3563 pDialogHeader
= (PIMAGE_DIALOG_HEADER
)
3564 GetActualAddress (lpFile
, prData
->OffsetToData
);
3567 pwd
= (WORD
*) ((DWORD
) pDialogHeader
);
3568 size
= prData
->Size
;
3569 *(int *) pMem
= size
;
3571 StrangeMenuFill (&pMem
, &pwd
, size
);
3581 // This function is written by sang cho
3584 /* print contents of dialog */
3586 PrintNameOrOrdinal (
3592 if (*(WORD
*) ptr
== 0xFFFF)
3595 printf ("%04X", *(WORD
*) ptr
);
3601 while (*(WORD
*) ptr
)
3603 printf ("%c", *ptr
);
3614 // This function is written by sang cho
3617 /* print contents of dialog */
3622 int i
/*, j, k, l, n, c*/;
3628 BOOL isStrange
= FALSE
;
3631 size
= *(int *) ptr
;
3635 // IStype of Dialog Header
3636 flag
= *(DWORD
*) ptr
;
3638 // check if flag is right or not
3639 // it has been observed that some dialog information is strange
3640 // and extra work is needed to fix that ... so let's try something
3643 if ((flag
& 0xFFFF0000) == 0xFFFF0000)
3645 flag
= *(DWORD
*) (ptr
+ 12);
3646 num
= *(short *) (ptr
+ 16);
3652 num
= *(short *) (ptr
+ 8);
3655 printf (", # of Controls=%03d, Caption:%c", num
, '"');
3658 if (*(WORD
*) ptr
== 0xFFFF)
3659 ptr
+= 4; // ordinal
3663 while (*(WORD
*) ptr
)
3669 if (*(WORD
*) ptr
== 0xFFFF)
3670 ptr
+= 4; // ordinal
3674 while (*(WORD
*) ptr
)
3680 while (*(WORD
*) ptr
)
3682 printf ("%c", *ptr
);
3689 if (flag
& 0x00000040)
3694 ptr
+= 2; // FONT size
3696 while (*(WORD
*) ptr
)
3699 ptr
+= 2; // double null
3703 // strange case adjust
3708 if ((ptr
- *psz
) % 4)
3709 ptr
+= 4 - ((ptr
- *psz
) % 4);
3711 // start reporting .. finally
3712 for (i
= 0; i
< num
; i
++)
3714 flag
= *(DWORD
*) ptr
;
3719 printf ("\n Control::%03d - ID:", i
+ 1);
3722 printf ("%04X, Class:", *(WORD
*) ptr
);
3726 if (*(WORD
*) ptr
== 0xFFFF)
3729 class = *(WORD
*) ptr
;
3743 printf ("LISTBOX ");
3746 printf ("SCROLLBAR");
3749 printf ("COMBOBOX ");
3752 printf ("%04X ", class);
3757 PrintNameOrOrdinal (&ptr
);
3762 PrintNameOrOrdinal (&ptr
);
3767 // strange case adjust
3772 if ((ptr
- *psz
) % 4)
3773 ptr
+= 4 - ((ptr
- *psz
) % 4);
3780 for (i=0; i<(size/16)+1; i++)
3783 for (j=0; j<16; j++)
3790 if (ptr >= pmax) break;
3792 if (n%4 == 0) printf (" ");
3794 n++; if (n%4 == 0) printf (" ");
3798 { n++; if (n%4 == 0) printf (" "); else printf (" "); }
3801 if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3803 if (ptr >= pmax) break;
3816 /* function indicates whether debug info has been stripped from file */
3818 IsDebugInfoStripped (
3821 PIMAGE_FILE_HEADER pfh
;
3823 pfh
= (PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
);
3825 return (pfh
->Characteristics
& IMAGE_FILE_DEBUG_STRIPPED
);
3831 /* retrieve the module name from the debug misc. structure */
3833 RetrieveModuleName (
3838 PIMAGE_DEBUG_DIRECTORY pdd
;
3839 PIMAGE_DEBUG_MISC pdm
= NULL
;
3842 if (!(pdd
= (PIMAGE_DEBUG_DIRECTORY
) ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_DEBUG
)))
3845 while (pdd
->SizeOfData
)
3847 if (pdd
->Type
== IMAGE_DEBUG_TYPE_MISC
)
3849 pdm
= (PIMAGE_DEBUG_MISC
) ((DWORD
) pdd
->PointerToRawData
+ (DWORD
) lpFile
);
3850 *pszModule
= (char *) calloc ((nCnt
= (strlen ((char *)pdm
->Data
))) + 1, 1);
3851 // may need some unicode business here...above
3852 bcopy (pdm
->Data
, *pszModule
, nCnt
);
3870 /* determine if this is a valid debug file */
3875 PIMAGE_SEPARATE_DEBUG_HEADER psdh
;
3877 psdh
= (PIMAGE_SEPARATE_DEBUG_HEADER
) lpFile
;
3879 return (psdh
->Signature
== IMAGE_SEPARATE_DEBUG_SIGNATURE
);
3885 /* copy separate debug header structure from debug file */
3887 GetSeparateDebugHeader (
3889 PIMAGE_SEPARATE_DEBUG_HEADER psdh
)
3891 PIMAGE_SEPARATE_DEBUG_HEADER pdh
;
3893 pdh
= (PIMAGE_SEPARATE_DEBUG_HEADER
) lpFile
;
3895 if (pdh
->Signature
== IMAGE_SEPARATE_DEBUG_SIGNATURE
)
3897 bcopy ((LPVOID
) pdh
, (LPVOID
) psdh
, sizeof (IMAGE_SEPARATE_DEBUG_HEADER
));
3905 // I tried to immitate the output of w32dasm disassembler.
3906 // which is a pretty good program.
3907 // but I am disappointed with this program and I myself
3908 // am writting a disassembler.
3909 // This PEdump program is a byproduct of that project.
3910 // so enjoy this program and I hope we will have a little more
3911 // knowledge on windows programming world.
3914 #define MAXSECTIONNUMBER 16
3915 #define MAXNAMESTRNUMBER 40
3925 IMAGE_DOS_HEADER dosHdr
;
3926 PIMAGE_FILE_HEADER pfh
;
3927 PIMAGE_OPTIONAL_HEADER poh
;
3928 PIMAGE_SECTION_HEADER psh
;
3929 //IMAGE_SECTION_HEADER idsh;
3930 IMAGE_SECTION_HEADER shdr
[MAXSECTIONNUMBER
];
3931 //PIMAGE_IMPORT_MODULE_DIRECTORY pid;
3933 int nSections
; // number of sections
3935 int nResources
; // number of resources
3937 int nMenus
; // number of menus
3939 int nDialogs
; // number of dialogs
3941 int nImportedModules
; // number of imported modules
3943 int nFunctions
; // number of functions in the imported module
3945 int nExportedFunctions
; // number of exported funcions
3957 char *piNameBuff
; // import module name buffer
3959 char *pfNameBuff
; // import functions in the module name buffer
3961 char *peNameBuff
; // export function name buffer
3963 char *pmNameBuff
; // menu name buffer
3965 char *pdNameBuff
; // dialog name buffer
3968 * Check user arguments.
3972 my_fp
= fopen (argv
[1], "rb");
3976 "%s: can not open input file \"%s\".\n",
3986 "%s - PE/COFF file dumper\n"
3987 "Copyright (c) 1993 Randy Kath (MSDN Technology Group)\n"
3988 "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)\n"
3989 "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)\n\n",
3993 "usage: %s input_file_name\n",
3999 * Get input file's size.
4002 fseek (my_fp
, 0L, SEEK_END
);
4003 fsize
= ftell (my_fp
);
4006 * Buffer the file in memory.
4008 lpFile
= (void *) calloc (fsize
, 1);
4012 "%s: can not allocate memory.\n",
4018 * --- Start of report ---
4020 printf ("\n\nDump of file: %s\n\n", argv
[1]);
4022 n
= fread (lpFile
, fsize
, 1, my_fp
);
4027 "%s: failed to read the file \"%s\".\n",
4034 GetDosHeader (lpFile
, &dosHdr
);
4036 if ((WORD
) IMAGE_DOS_SIGNATURE
== dosHdr
.e_magic
)
4038 if ((dosHdr
.e_lfanew
> 4096)
4039 || (dosHdr
.e_lfanew
< 64)
4043 "%s: This file is not in PE format; it looks like in DOS format.\n",
4052 "%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4059 fileType
= ImageFileType (lpFile
);
4061 if (fileType
!= IMAGE_NT_SIGNATURE
)
4064 "%s: This file is not in PE format (magic = 0x%08lx).\n",
4071 //=====================================
4072 // now we can really start processing
4073 //=====================================
4075 pfh
= (PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
);
4077 poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
4079 psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
4081 nSections
= pfh
->NumberOfSections
;
4083 imageBase
= poh
->ImageBase
;
4085 entryPoint
= poh
->AddressOfEntryPoint
;
4090 /* store section headers */
4100 * Get Code offset and size,
4101 * Data offset and size.
4108 if (poh
->BaseOfCode
== shdr
[i
].VirtualAddress
)
4111 "Code Offset = %08lX, Code Size = %08lX \n",
4112 shdr
[i
].PointerToRawData
,
4113 shdr
[i
].SizeOfRawData
4116 if (((shdr
[i
].Characteristics
) & 0xC0000040) == 0xC0000040)
4119 "Data Offset = %08lX, Data Size = %08lX \n",
4120 shdr
[i
].PointerToRawData
,
4121 shdr
[i
].SizeOfRawData
4130 "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
4135 * Object name alignment.
4147 if (shdr
[i
].Name
[j
] == 0)
4149 shdr
[i
].Name
[j
] = 32;
4152 shdr
[i
].Name
[7] = 0;
4154 for (i
= 0; i
< nSections
; i
++)
4155 printf ("\n Object%02d: %8s RVA: %08lX Offset: %08lX Size: %08lX Flags: %08lX ",
4156 i
+ 1, shdr
[i
].Name
, shdr
[i
].VirtualAddress
, shdr
[i
].PointerToRawData
,
4157 shdr
[i
].SizeOfRawData
, shdr
[i
].Characteristics
);
4159 * Get List of Resources.
4161 nResources
= GetListOfResourceTypes (lpFile
, &pnstr
);
4164 printf ("\n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++");
4166 if (nResources
== 0)
4167 printf ("\n There are no Resources in This Application.\n");
4170 printf ("\nNumber of Resource Types = %4d (decimal)\n", nResources
);
4171 for (i
= 0; i
< nResources
; i
++)
4173 printf ("\n Resource Type %03d: %s", i
+ 1, pst
);
4174 pst
+= strlen ((char *) (pst
)) + 1;
4176 free ((void *) pnstr
);
4179 printf ("\n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++");
4182 nMenus
= GetContentsOfMenu (lpFile
, &pmNameBuff
);
4186 printf ("\n There are no Menus in This Application.\n");
4191 printf ("\nNumber of Menus = %4d (decimal)", nMenus
);
4193 //dumpMenu(&pst, 8096);
4194 for (i
= 0; i
< nMenus
; i
++)
4197 printf ("\n\n%s", pst
);
4198 pst
+= strlen (pst
) + 1;
4199 printf ("\n-------------");
4200 if (strncmp (pst
, ":::::::::::", 11) == 0)
4203 PrintStrangeMenu (&pst
);
4207 PrintMenu (6, &pst
);
4209 //else PrintStrangeMenu(&pst);
4211 free ((void *) pmNameBuff
);
4216 printf ("\n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++");
4219 nDialogs
= GetContentsOfDialog (lpFile
, &pdNameBuff
);
4223 printf ("\n There are no Dialogs in This Application.\n");
4228 printf ("\nNumber of Dialogs = %4d (decimal)", nDialogs
);
4232 for (i
= 0; i
< nDialogs
; i
++)
4235 printf ("\nName: %s", pst
);
4236 pst
+= strlen (pst
) + 1;
4239 free ((void *) pdNameBuff
);
4244 printf ("\n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++");
4246 nImportedModules
= GetImportModuleNames (lpFile
, &piNameBuff
);
4247 if (nImportedModules
== 0)
4249 printf ("\n There are no imported Functions in This Application.\n");
4254 printf ("\nNumber of Imported Modules = %4d (decimal)\n", nImportedModules
);
4255 for (i
= 0; i
< nImportedModules
; i
++)
4257 printf ("\n Import Module %03d: %s", i
+ 1, pnstr
);
4258 pnstr
+= strlen ((char *) (pnstr
)) + 1;
4262 printf ("\n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++");
4264 for (i
= 0; i
< nImportedModules
; i
++)
4266 printf ("\n\n Import Module %03d: %s \n", i
+ 1, pnstr
);
4267 nFunctions
= GetImportFunctionNamesByModule (lpFile
, pnstr
, &pfNameBuff
);
4268 pnstr
+= strlen ((char *) (pnstr
)) + 1;
4270 for (j
= 0; j
< nFunctions
; j
++)
4272 printf ("\nAddr:%08X hint(%04X) Name: %s",
4273 (*(int *) pst
), (*(short *) (pst
+ 4)),
4275 TranslateFunctionName (pst
+ 6));
4276 pst
+= strlen ((char *) (pst
+ 6)) + 1 + 6;
4278 free ((void *) pfNameBuff
);
4280 free ((void *) piNameBuff
);
4284 printf ("\n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++");
4286 nExportedFunctions
= GetExportFunctionNames (lpFile
, &peNameBuff
);
4287 printf ("\nNumber of Exported Functions = %4d (decimal)\n", nExportedFunctions
);
4289 if (nExportedFunctions
> 0)
4293 for (i
= 0; i
< nExportedFunctions
; i
++)
4295 printf ("\nAddr:%08X Ord:%4d (%04Xh) Name: %s",
4296 (*(int *) pst
), (*(WORD
*) (pst
+ 4)), (*(WORD
*) (pst
+ 4)),
4298 TranslateFunctionName (pst
+ 6));
4299 pst
+= strlen ((char *) (pst
+ 6)) + 6 + 1;
4301 free ((void *) peNameBuff
);
4304 free ((void *) lpFile
);