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.
55 #define bcopy(s,d,z) memcpy((d),(s),(z))
62 typedef unsigned short USHORT
;
63 typedef unsigned long DWORD
;
65 typedef unsigned char BYTE
;
66 typedef unsigned short WORD
;
69 typedef DWORD
*PDWORD
;
74 #define BOOLEAN boolean
83 #define LOWORD(l) ((WORD)(l))
84 #define WINAPI __stdcall
90 #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
91 #define IMAGE_OS2_SIGNATURE 0x454E // NE
92 #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
93 #define IMAGE_VXD_SIGNATURE 0x454C // LE
94 #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
96 typedef struct _IMAGE_DOS_HEADER
99 WORD e_magic
; // Magic number
101 WORD e_cblp
; // Bytes on last page of file
103 WORD e_cp
; // Pages in file
105 WORD e_crlc
; // Relocations
107 WORD e_cparhdr
; // Size of header in paragraphs
109 WORD e_minalloc
; // Minimum extra paragraphs needed
111 WORD e_maxalloc
; // Maximum extra paragraphs needed
113 WORD e_ss
; // Initial (relative) SS value
115 WORD e_sp
; // Initial SP value
117 WORD e_csum
; // Checksum
119 WORD e_ip
; // Initial IP value
121 WORD e_cs
; // Initial (relative) CS value
123 WORD e_lfarlc
; // File address of relocation table
125 WORD e_ovno
; // Overlay number
127 WORD e_res
[4]; // Reserved words
129 WORD e_oemid
; // OEM identifier (for e_oeminfo)
131 WORD e_oeminfo
; // OEM information; e_oemid specific
133 WORD e_res2
[10]; // Reserved words
135 LONG e_lfanew
; // File address of new exe header
138 IMAGE_DOS_HEADER
, *PIMAGE_DOS_HEADER
;
141 // File header format.
146 typedef struct _IMAGE_FILE_HEADER
149 WORD NumberOfSections
;
151 DWORD PointerToSymbolTable
;
152 DWORD NumberOfSymbols
;
153 WORD SizeOfOptionalHeader
;
154 WORD Characteristics
;
156 IMAGE_FILE_HEADER
, *PIMAGE_FILE_HEADER
;
158 #define IMAGE_SIZEOF_FILE_HEADER 20
160 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
161 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
162 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
163 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
164 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
165 #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
166 #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
167 #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
168 #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
169 #define IMAGE_FILE_SYSTEM 0x1000 // System File.
170 #define IMAGE_FILE_DLL 0x2000 // File is a DLL.
171 #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
172 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
174 #define IMAGE_FILE_MACHINE_UNKNOWN 0
175 #define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
176 #define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0x160 big-endian
177 #define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
178 #define IMAGE_FILE_MACHINE_R10000 0x168 // MIPS little-endian
179 #define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
180 #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
188 typedef struct _IMAGE_DATA_DIRECTORY
190 DWORD VirtualAddress
;
194 IMAGE_DATA_DIRECTORY
, *PIMAGE_DATA_DIRECTORY
;
196 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
199 // Optional header format.
202 typedef struct _IMAGE_OPTIONAL_HEADER
208 BYTE MajorLinkerVersion
;
209 BYTE MinorLinkerVersion
;
211 DWORD SizeOfInitializedData
;
212 DWORD SizeOfUninitializedData
;
213 DWORD AddressOfEntryPoint
;
218 // NT additional fields.
222 DWORD SectionAlignment
;
224 WORD MajorOperatingSystemVersion
;
225 WORD MinorOperatingSystemVersion
;
226 WORD MajorImageVersion
;
227 WORD MinorImageVersion
;
228 WORD MajorSubsystemVersion
;
229 WORD MinorSubsystemVersion
;
230 DWORD Win32VersionValue
;
235 WORD DllCharacteristics
;
236 DWORD SizeOfStackReserve
;
237 DWORD SizeOfStackCommit
;
238 DWORD SizeOfHeapReserve
;
239 DWORD SizeOfHeapCommit
;
241 DWORD NumberOfRvaAndSizes
;
242 IMAGE_DATA_DIRECTORY DataDirectory
[IMAGE_NUMBEROF_DIRECTORY_ENTRIES
];
245 IMAGE_OPTIONAL_HEADER
, *PIMAGE_OPTIONAL_HEADER
;
248 typedef struct _IMAGE_NT_HEADERS
251 IMAGE_FILE_HEADER FileHeader
;
252 IMAGE_OPTIONAL_HEADER OptionalHeader
;
255 IMAGE_NT_HEADERS
, *PIMAGE_NT_HEADERS
;
260 #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
261 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
262 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
263 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
264 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
265 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
266 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
267 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
268 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
269 #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
270 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
271 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
272 #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
275 // Section header format.
278 #define IMAGE_SIZEOF_SHORT_NAME 8
280 typedef struct _IMAGE_SECTION_HEADER
282 BYTE Name
[IMAGE_SIZEOF_SHORT_NAME
];
285 DWORD PhysicalAddress
;
289 DWORD VirtualAddress
;
291 DWORD PointerToRawData
;
292 DWORD PointerToRelocations
;
293 DWORD PointerToLinenumbers
;
294 WORD NumberOfRelocations
;
295 WORD NumberOfLinenumbers
;
296 DWORD Characteristics
;
299 IMAGE_SECTION_HEADER
, *PIMAGE_SECTION_HEADER
;
301 #define IMAGE_SIZEOF_SECTION_HEADER 40
308 typedef struct _IMAGE_EXPORT_DIRECTORY
310 DWORD Characteristics
;
316 DWORD NumberOfFunctions
;
318 PDWORD
*AddressOfFunctions
;
319 PDWORD
*AddressOfNames
;
320 PWORD
*AddressOfNameOrdinals
;
323 IMAGE_EXPORT_DIRECTORY
, *PIMAGE_EXPORT_DIRECTORY
;
329 typedef struct _IMAGE_IMPORT_BY_NAME
335 IMAGE_IMPORT_BY_NAME
, *PIMAGE_IMPORT_BY_NAME
;
337 #define IMAGE_ORDINAL_FLAG 0x80000000
338 #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
346 // Resource directory consists of two counts, following by a variable length
347 // array of directory entries. The first count is the number of entries at
348 // beginning of the array that have actual names associated with each entry.
349 // The entries are in ascending order, case insensitive strings. The second
350 // count is the number of entries that immediately follow the named entries.
351 // This second count identifies the number of entries that have 16-bit integer
352 // Ids as their name. These entries are also sorted in ascending order.
354 // This structure allows fast lookup by either name or number, but for any
355 // given resource entry only one form of lookup is supported, not both.
356 // This is consistant with the syntax of the .RC file and the .RES file.
359 // Predefined resource types ... there may be some more, but I don't have
360 // the information yet. .....sang cho.....
362 #define RT_NEWRESOURCE 0x2000
363 #define RT_ERROR 0x7fff
372 #define RT_ACCELERATORS 9
374 #define RT_MESSAGETABLE 11
375 #define RT_GROUP_CURSOR 12
376 #define RT_GROUP_ICON 14
377 #define RT_VERSION 16
378 #define NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)
379 #define NEWMENU (RT_MENU|RT_NEWRESOURCE)
380 #define NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)
383 typedef struct _IMAGE_RESOURCE_DIRECTORY
385 DWORD Characteristics
;
389 WORD NumberOfNamedEntries
;
390 WORD NumberOfIdEntries
;
391 // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1];
394 IMAGE_RESOURCE_DIRECTORY
, *PIMAGE_RESOURCE_DIRECTORY
;
396 #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
397 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
400 // Each directory contains the 32-bit Name of the entry and an offset,
401 // relative to the beginning of the resource directory of the data associated
402 // with this directory entry. If the name of the entry is an actual text
403 // string instead of an integer Id, then the high order bit of the name field
404 // is set to one and the low order 31-bits are an offset, relative to the
405 // beginning of the resource directory of the string, which is of type
406 // IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the
407 // low-order 16-bits are the integer Id that identify this resource directory
408 // entry. If the directory entry is yet another resource directory (i.e. a
409 // subdirectory), then the high order bit of the offset field will be
410 // set to indicate this. Otherwise the high bit is clear and the offset
411 // field points to a resource data entry.
414 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
420 IMAGE_RESOURCE_DIRECTORY_ENTRY
, *PIMAGE_RESOURCE_DIRECTORY_ENTRY
;
423 // For resource directory entries that have actual string names, the Name
424 // field of the directory entry points to an object of the following type.
425 // All of these string objects are stored together after the last resource
426 // directory entry and before the first resource data object. This minimizes
427 // the impact of these variable length objects on the alignment of the fixed
428 // size directory entry objects.
431 typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING
437 IMAGE_RESOURCE_DIRECTORY_STRING
, *PIMAGE_RESOURCE_DIRECTORY_STRING
;
440 typedef struct _IMAGE_RESOURCE_DIR_STRING_U
446 IMAGE_RESOURCE_DIR_STRING_U
, *PIMAGE_RESOURCE_DIR_STRING_U
;
450 // Each resource data entry describes a leaf node in the resource directory
451 // tree. It contains an offset, relative to the beginning of the resource
452 // directory of the data for the resource, a size field that gives the number
453 // of bytes of data at that offset, a CodePage that should be used when
454 // decoding code point values within the resource data. Typically for new
455 // applications the code page would be the unicode code page.
458 typedef struct _IMAGE_RESOURCE_DATA_ENTRY
466 IMAGE_RESOURCE_DATA_ENTRY
, *PIMAGE_RESOURCE_DATA_ENTRY
;
469 // Menu Resources ... added by .....sang cho....
471 // Menu resources are composed of a menu header followed by a sequential list
472 // of menu items. There are two types of menu items: pop-ups and normal menu
473 // itmes. The MENUITEM SEPARATOR is a special case of a normal menu item with
474 // an empty name, zero ID, and zero flags.
476 typedef struct _IMAGE_MENU_HEADER
478 WORD wVersion
; // Currently zero
480 WORD cbHeaderSize
; // Also zero
483 IMAGE_MENU_HEADER
, *PIMAGE_MENU_HEADER
;
485 typedef struct _IMAGE_POPUP_MENU_ITEM
491 IMAGE_POPUP_MENU_ITEM
, *PIMAGE_POPUP_MENU_ITEM
;
493 typedef struct _IMAGE_NORMAL_MENU_ITEM
500 IMAGE_NORMAL_MENU_ITEM
, *PIMAGE_NORMAL_MENU_ITEM
;
502 #define GRAYED 0x0001 // GRAYED keyword
503 #define INACTIVE 0x0002 // INACTIVE keyword
504 #define BITMAP 0x0004 // BITMAP keyword
505 #define OWNERDRAW 0x0100 // OWNERDRAW keyword
506 #define CHECKED 0x0008 // CHECKED keyword
507 #define POPUP 0x0010 // used internally
508 #define MENUBARBREAK 0x0020 // MENUBARBREAK keyword
509 #define MENUBREAK 0x0040 // MENUBREAK keyword
510 #define ENDMENU 0x0080 // used internally
513 // Dialog Box Resources .................. added by sang cho.
515 // A dialog box is contained in a single resource and has a header and
516 // a portion repeated for each control in the dialog box.
517 // The item DWORD IStyle is a standard window style composed of flags found
519 // The default style for a dialog box is:
520 // WS_POPUP | WS_BORDER | WS_SYSMENU
522 // The itme marked "Name or Ordinal" are :
523 // If the first word is an 0xffff, the next two bytes contain an ordinal ID.
524 // Otherwise, the first one or more WORDS contain a double-null-terminated string.
525 // An empty string is represented by a single WORD zero in the first location.
527 // The WORD wPointSize and WCHAR szFontName entries are present if the FONT
528 // statement was included for the dialog box. This can be detected by checking
529 // the entry IStyle. If IStyle & DS_SETFONT ( which is 0x40), then these
530 // entries will be present.
532 typedef struct _IMAGE_DIALOG_BOX_HEADER1
535 DWORD IExtendedStyle
; // New for Windows NT
537 WORD nControls
; // Number of Controls
543 // N_OR_O MenuName; // Name or Ordinal ID
544 // N_OR_O ClassName; // Name or Ordinal ID
545 // WCHAR szCaption[];
546 // WORD wPointSize; // Only here if FONT set for dialog
547 // WCHAR szFontName[]; // This too
549 IMAGE_DIALOG_HEADER
, *PIMAGE_DIALOG_HEADER
;
551 typedef union _NAME_OR_ORDINAL
552 { // Name or Ordinal ID
562 NAME_OR_ORDINAL
, *PNAME_OR_ORDINAL
;
564 // The data for each control starts on a DWORD boundary (which may require
565 // some padding from the previous control), and its format is as follows:
567 typedef struct _IMAGE_CONTROL_DATA
570 DWORD IExtendedStyle
;
580 IMAGE_CONTROL_DATA
, *PIMAGE_CONTROL_DATA
;
586 #define SCROLLBAR 0x84
587 #define COMBOBOX 0x85
589 // The various statements used in a dialog script are all mapped to these
590 // classes along with certain modifying styles. The values for these styles
591 // can be found in WINDOWS.H. All dialog controls have the default styles
592 // of WS_CHILD and WS_VISIBLE. A list of the default styles used follows:
594 // Statement Default Class Default Styles
595 // CONTROL None WS_CHILD|WS_VISIBLE
596 // LTEXT STATIC ES_LEFT
597 // RTEXT STATIC ES_RIGHT
598 // CTEXT STATIC ES_CENTER
599 // LISTBOX LISTBOX WS_BORDER|LBS_NOTIFY
600 // CHECKBOX BUTTON BS_CHECKBOX|WS_TABSTOP
601 // PUSHBUTTON BUTTON BS_PUSHBUTTON|WS_TABSTOP
602 // GROUPBOX BUTTON BS_GROUPBOX
603 // DEFPUSHBUTTON BUTTON BS_DFPUSHBUTTON|WS_TABSTOP
604 // RADIOBUTTON BUTTON BS_RADIOBUTTON
605 // AUTOCHECKBOX BUTTON BS_AUTOCHECKBOX
606 // AUTO3STATE BUTTON BS_AUTO3STATE
607 // AUTORADIOBUTTON BUTTON BS_AUTORADIOBUTTON
608 // PUSHBOX BUTTON BS_PUSHBOX
609 // STATE3 BUTTON BS_3STATE
610 // EDITTEXT EDIT ES_LEFT|WS_BORDER|WS_TABSTOP
611 // COMBOBOX COMBOBOX None
612 // ICON STATIC SS_ICON
613 // SCROLLBAR SCROLLBAR None
616 #define WS_OVERLAPPED 0x00000000L
617 #define WS_POPUP 0x80000000L
618 #define WS_CHILD 0x40000000L
619 #define WS_CLIPSIBLINGS 0x04000000L
620 #define WS_CLIPCHILDREN 0x02000000L
621 #define WS_VISIBLE 0x10000000L
622 #define WS_DISABLED 0x08000000L
623 #define WS_MINIMIZE 0x20000000L
624 #define WS_MAXIMIZE 0x01000000L
625 #define WS_CAPTION 0x00C00000L
626 #define WS_BORDER 0x00800000L
627 #define WS_DLGFRAME 0x00400000L
628 #define WS_VSCROLL 0x00200000L
629 #define WS_HSCROLL 0x00100000L
630 #define WS_SYSMENU 0x00080000L
631 #define WS_THICKFRAME 0x00040000L
632 #define WS_MINIMIZEBOX 0x00020000L
633 #define WS_MAXIMIZEBOX 0x00010000L
634 #define WS_GROUP 0x00020000L
635 #define WS_TABSTOP 0x00010000L
638 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
639 #define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
640 #define WS_CHILDWINDOW (WS_CHILD)
641 #define WS_TILED WS_OVERLAPPED
642 #define WS_ICONIC WS_MINIMIZE
643 #define WS_SIZEBOX WS_THICKFRAME
644 #define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
646 #define WS_EX_DLGMODALFRAME 0x00000001L
647 #define WS_EX_NOPARENTNOTIFY 0x00000004L
648 #define WS_EX_TOPMOST 0x00000008L
649 #define WS_EX_ACCEPTFILES 0x00000010L
650 #define WS_EX_TRANSPARENT 0x00000020L
652 #define BS_PUSHBUTTON 0x00000000L
653 #define BS_DEFPUSHBUTTON 0x00000001L
654 #define BS_CHECKBOX 0x00000002L
655 #define BS_AUTOCHECKBOX 0x00000003L
656 #define BS_RADIOBUTTON 0x00000004L
657 #define BS_3STATE 0x00000005L
658 #define BS_AUTO3STATE 0x00000006L
659 #define BS_GROUPBOX 0x00000007L
660 #define BS_USERBUTTON 0x00000008L
661 #define BS_AUTORADIOBUTTON 0x00000009L
662 #define BS_OWNERDRAW 0x0000000BL
663 #define BS_LEFTTEXT 0x00000020L
665 #define ES_LEFT 0x00000000L
666 #define ES_CENTER 0x00000001L
667 #define ES_RIGHT 0x00000002L
668 #define ES_MULTILINE 0x00000004L
669 #define ES_UPPERCASE 0x00000008L
670 #define ES_LOWERCASE 0x00000010L
671 #define ES_PASSWORD 0x00000020L
672 #define ES_AUTOVSCROLL 0x00000040L
673 #define ES_AUTOHSCROLL 0x00000080L
674 #define ES_NOHIDESEL 0x00000100L
675 #define ES_OEMCONVERT 0x00000400L
676 #define ES_READONLY 0x00000800L
677 #define ES_WANTRETURN 0x00001000L
679 #define LBS_NOTIFY 0x0001L
680 #define LBS_SORT 0x0002L
681 #define LBS_NOREDRAW 0x0004L
682 #define LBS_MULTIPLESEL 0x0008L
683 #define LBS_OWNERDRAWFIXED 0x0010L
684 #define LBS_OWNERDRAWVARIABLE 0x0020L
685 #define LBS_HASSTRINGS 0x0040L
686 #define LBS_USETABSTOPS 0x0080L
687 #define LBS_NOINTEGRALHEIGHT 0x0100L
688 #define LBS_MULTICOLUMN 0x0200L
689 #define LBS_WANTKEYBOARDINPUT 0x0400L
690 #define LBS_EXTENDEDSEL 0x0800L
691 #define LBS_DISABLENOSCROLL 0x1000L
693 #define SS_LEFT 0x00000000L
694 #define SS_CENTER 0x00000001L
695 #define SS_RIGHT 0x00000002L
696 #define SS_ICON 0x00000003L
697 #define SS_BLACKRECT 0x00000004L
698 #define SS_GRAYRECT 0x00000005L
699 #define SS_WHITERECT 0x00000006L
700 #define SS_BLACKFRAME 0x00000007L
701 #define SS_GRAYFRAME 0x00000008L
702 #define SS_WHITEFRAME 0x00000009L
703 #define SS_SIMPLE 0x0000000BL
704 #define SS_LEFTNOWORDWRAP 0x0000000CL
705 #define SS_BITMAP 0x0000000EL
711 typedef struct _IMAGE_DEBUG_DIRECTORY
713 DWORD Characteristics
;
719 DWORD AddressOfRawData
;
720 DWORD PointerToRawData
;
722 IMAGE_DEBUG_DIRECTORY
, *PIMAGE_DEBUG_DIRECTORY
;
724 #define IMAGE_DEBUG_TYPE_UNKNOWN 0
725 #define IMAGE_DEBUG_TYPE_COFF 1
726 #define IMAGE_DEBUG_TYPE_CODEVIEW 2
727 #define IMAGE_DEBUG_TYPE_FPO 3
728 #define IMAGE_DEBUG_TYPE_MISC 4
729 #define IMAGE_DEBUG_TYPE_EXCEPTION 5
730 #define IMAGE_DEBUG_TYPE_FIXUP 6
731 #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
732 #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
735 typedef struct _IMAGE_DEBUG_MISC
737 DWORD DataType
; // type of misc data, see defines
739 DWORD Length
; // total length of record, rounded to four
742 BOOLEAN Unicode
; // TRUE if data is unicode string
745 BYTE Data
[1]; // Actual data
748 IMAGE_DEBUG_MISC
, *PIMAGE_DEBUG_MISC
;
752 // Debugging information can be stripped from an image file and placed
753 // in a separate .DBG file, whose file name part is the same as the
754 // image file name part (e.g. symbols for CMD.EXE could be stripped
755 // and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
756 // flag in the Characteristics field of the file header. The beginning of
757 // the .DBG file contains the following structure which captures certain
758 // information from the image file. This allows a debug to proceed even if
759 // the original image file is not accessable. This header is followed by
760 // zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
761 // IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in
762 // the image file contain file offsets relative to the beginning of the
765 // If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
766 // is left in the image file, but not mapped. This allows a debugger to
767 // compute the name of the .DBG file, from the name of the image in the
768 // IMAGE_DEBUG_MISC structure.
771 typedef struct _IMAGE_SEPARATE_DEBUG_HEADER
776 WORD Characteristics
;
781 DWORD NumberOfSections
;
782 DWORD ExportedNamesSize
;
783 DWORD DebugDirectorySize
;
784 DWORD SectionAlignment
;
787 IMAGE_SEPARATE_DEBUG_HEADER
, *PIMAGE_SEPARATE_DEBUG_HEADER
;
789 #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
791 #define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000
792 #define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the
793 // old checksum didn't match.
801 #define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
802 #define MAXRESOURCENAME 13
804 /* global macros to define header offsets into file */
805 /* offset to PE file signature */
806 #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
807 ((PIMAGE_DOS_HEADER)a)->e_lfanew))
809 /* DOS header identifies the NT PEFile signature dword
810 the PEFILE header exists just after that dword */
811 #define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \
812 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
813 SIZE_OF_NT_SIGNATURE))
815 /* PE optional header is immediately after PEFile header */
816 #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \
817 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
818 SIZE_OF_NT_SIGNATURE + \
819 sizeof (IMAGE_FILE_HEADER)))
821 /* section headers are immediately after PE optional header */
822 #define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + \
823 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
824 SIZE_OF_NT_SIGNATURE + \
825 sizeof (IMAGE_FILE_HEADER) + \
826 sizeof (IMAGE_OPTIONAL_HEADER)))
829 typedef struct tagImportDirectory
831 DWORD dwRVAFunctionNameList
;
834 DWORD dwRVAModuleName
;
835 DWORD dwRVAFunctionAddressList
;
837 IMAGE_IMPORT_MODULE_DIRECTORY
, *PIMAGE_IMPORT_MODULE_DIRECTORY
;
840 /* global prototypes for functions in pefile.c */
841 /* PE file header info */
842 BOOL WINAPI
GetDosHeader (LPVOID
, PIMAGE_DOS_HEADER
);
843 DWORD WINAPI
ImageFileType (LPVOID
);
844 BOOL WINAPI
GetPEFileHeader (LPVOID
, PIMAGE_FILE_HEADER
);
846 /* PE optional header info */
847 BOOL WINAPI
GetPEOptionalHeader (LPVOID
, PIMAGE_OPTIONAL_HEADER
);
848 LPVOID WINAPI
GetModuleEntryPoint (LPVOID
);
849 int WINAPI
NumOfSections (LPVOID
);
850 LPVOID WINAPI
GetImageBase (LPVOID
);
851 LPVOID WINAPI
ImageDirectoryOffset (LPVOID
, DWORD
);
852 LPVOID WINAPI
ImageDirectorySection (LPVOID
, DWORD
);
854 /* PE section header info */
855 //int WINAPI GetSectionNames (LPVOID, HANDLE, char **);
856 int WINAPI
GetSectionNames (LPVOID
, char **);
857 BOOL WINAPI
GetSectionHdrByName (LPVOID
, PIMAGE_SECTION_HEADER
, char *);
860 // structur to store string tokens
862 typedef struct _Str_P
864 char flag
; // string_flag '@' or '%' or '#'
866 char *pos
; // starting postion of string
868 int length
; // length of string
870 BOOL wasString
; // if it were stringMode or not
875 /* import section info */
876 int WINAPI
GetImportModuleNames (LPVOID
, char **);
877 int WINAPI
GetImportFunctionNamesByModule (LPVOID
, char *, char **);
879 // import function name reporting
880 int WINAPI
GetStringLength (char *);
881 void WINAPI
GetPreviousParamString (char *, char *);
882 void WINAPI
TranslateParameters (char **, char **, char **);
883 BOOL WINAPI
StringExpands (char **, char **, char **, Str_P
*);
884 char * WINAPI
TranslateFunctionName (char *);
886 /* export section info */
887 int WINAPI
GetExportFunctionNames (LPVOID
, char **);
889 /* resource section info */
890 int WINAPI
GetNumberOfResources (LPVOID
);
891 int WINAPI
GetListOfResourceTypes (LPVOID
, char **);
892 int WINAPI
MenuScan (int *, WORD
**);
893 int WINAPI
MenuFill (char **, WORD
**);
894 void WINAPI
StrangeMenuFill (char **, WORD
**, int);
895 int WINAPI
GetContentsOfMenu (LPVOID
, char **);
896 int WINAPI
PrintMenu (int, char **);
897 int WINAPI
PrintStrangeMenu (char **);
898 int WINAPI
dumpMenu (char **psz
, int size
);
900 /* debug section info */
901 BOOL WINAPI
IsDebugInfoStripped (LPVOID
);
902 int WINAPI
RetrieveModuleName (LPVOID
, char **);
903 BOOL WINAPI
IsDebugFile (LPVOID
);
904 BOOL WINAPI
GetSeparateDebugHeader (LPVOID
, PIMAGE_SEPARATE_DEBUG_HEADER
);
907 /**********************************************************************
911 * Copy DOS header information to structure.
918 PIMAGE_DOS_HEADER pHeader
922 * DOS header represents first structure
923 * of bytes in PE image file.
925 if ((WORD
) IMAGE_DOS_SIGNATURE
== *(WORD
*) lpFile
)
930 sizeof (IMAGE_DOS_HEADER
)
940 /* return file signature */
945 /* dos file signature comes first */
946 if (*(USHORT
*) lpFile
== IMAGE_DOS_SIGNATURE
)
948 /* determine location of PE File header from dos header */
949 if (LOWORD (*(DWORD
*) NTSIGNATURE (lpFile
)) == IMAGE_OS2_SIGNATURE
||
950 LOWORD (*(DWORD
*) NTSIGNATURE (lpFile
)) == IMAGE_OS2_SIGNATURE_LE
)
951 return (DWORD
) LOWORD (*(DWORD
*) NTSIGNATURE (lpFile
));
953 else if (*(DWORD
*) NTSIGNATURE (lpFile
) == IMAGE_NT_SIGNATURE
)
954 return IMAGE_NT_SIGNATURE
;
957 return IMAGE_DOS_SIGNATURE
;
961 /* unknown file type */
968 /* copy file header information to structure */
972 PIMAGE_FILE_HEADER pHeader
)
974 /* file header follows dos header */
975 if (ImageFileType (lpFile
) == IMAGE_NT_SIGNATURE
)
976 bcopy (PEFHDROFFSET (lpFile
), (LPVOID
) pHeader
, sizeof (IMAGE_FILE_HEADER
));
987 /* copy optional header info to structure */
989 GetPEOptionalHeader (
991 PIMAGE_OPTIONAL_HEADER pHeader
)
993 /* optional header follows file header and dos header */
994 if (ImageFileType (lpFile
) == IMAGE_NT_SIGNATURE
)
995 bcopy (OPTHDROFFSET (lpFile
), (LPVOID
) pHeader
, sizeof (IMAGE_OPTIONAL_HEADER
));
1005 /* function returns the entry point for an exe module lpFile must
1006 be a memory mapped file pointer to the beginning of the image file */
1008 GetModuleEntryPoint (
1011 PIMAGE_OPTIONAL_HEADER poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
1014 return (LPVOID
) (poh
->AddressOfEntryPoint
);
1022 /* return the total number of sections in the module */
1027 /* number os sections is indicated in file header */
1028 return ((int) ((PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
))->NumberOfSections
);
1034 /* retrieve entry point */
1039 PIMAGE_OPTIONAL_HEADER poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
1042 return (LPVOID
) (poh
->ImageBase
);
1050 // This function is written by sang cho
1051 // .. october 5, 1997
1053 /* function returns the actual address of given RVA, lpFile must
1054 be a memory mapped file pointer to the beginning of the image file */
1060 // PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
1061 PIMAGE_SECTION_HEADER psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
1062 int nSections
= NumOfSections (lpFile
);
1067 if (dwRVA
& 0x80000000)
1069 //return (LPVOID)dwRVA;
1070 printf ("\n$$ what is going on $$");
1074 /* locate section containing image directory */
1075 while (i
++ < nSections
)
1077 if (psh
->VirtualAddress
<= (DWORD
) dwRVA
&&
1078 psh
->VirtualAddress
+ psh
->SizeOfRawData
> (DWORD
) dwRVA
)
1086 /* return image import directory offset */
1087 return (LPVOID
) (((int) lpFile
+ (int) dwRVA
- psh
->VirtualAddress
) +
1088 (int) psh
->PointerToRawData
);
1093 // This function is modified by sang cho
1096 /* return offset to specified IMAGE_DIRECTORY entry */
1098 ImageDirectoryOffset (
1100 DWORD dwIMAGE_DIRECTORY
)
1102 PIMAGE_OPTIONAL_HEADER poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
1103 PIMAGE_SECTION_HEADER psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
1104 int nSections
= NumOfSections (lpFile
);
1108 /* must be 0 thru (NumberOfRvaAndSizes-1) */
1109 if (dwIMAGE_DIRECTORY
>= poh
->NumberOfRvaAndSizes
)
1112 /* locate specific image directory's relative virtual address */
1113 VAImageDir
= (LPVOID
) poh
->DataDirectory
[dwIMAGE_DIRECTORY
].VirtualAddress
;
1115 if (VAImageDir
== NULL
)
1117 /* locate section containing image directory */
1118 while (i
++ < nSections
)
1120 if (psh
->VirtualAddress
<= (DWORD
) VAImageDir
&&
1121 psh
->VirtualAddress
+ psh
->SizeOfRawData
> (DWORD
) VAImageDir
)
1129 /* return image import directory offset */
1130 return (LPVOID
) (((int) lpFile
+ (int) VAImageDir
- psh
->VirtualAddress
) +
1131 (int) psh
->PointerToRawData
);
1135 /* function retrieve names of all the sections in the file */
1141 int nSections
= NumOfSections (lpFile
);
1143 PIMAGE_SECTION_HEADER psh
;
1147 if (ImageFileType (lpFile
) != IMAGE_NT_SIGNATURE
||
1148 (psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
)) == NULL
)
1151 /* count the number of chars used in the section names */
1152 for (i
= 0; i
< nSections
; i
++)
1153 nCnt
+= strlen ((char *)psh
[i
].Name
) + 1;
1155 /* allocate space for all section names from heap */
1156 ps
= *pszSections
= (char *) calloc (nCnt
, 1);
1159 for (i
= 0; i
< nSections
; i
++)
1161 strcpy (ps
, (char *)psh
[i
].Name
);
1162 ps
+= strlen ((char *)psh
[i
].Name
) + 1;
1171 /* function gets the function header for a section identified by name */
1173 GetSectionHdrByName (
1175 IMAGE_SECTION_HEADER
* sh
,
1178 PIMAGE_SECTION_HEADER psh
;
1179 int nSections
= NumOfSections (lpFile
);
1183 if ((psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
)) != NULL
)
1185 /* find the section by name */
1186 for (i
= 0; i
< nSections
; i
++)
1188 if (!strcmp ((char *)psh
->Name
, szSection
))
1190 /* copy data to header */
1191 bcopy ((LPVOID
) psh
, (LPVOID
) sh
, sizeof (IMAGE_SECTION_HEADER
));
1204 // This function is modified by sang cho
1207 /* get import modules names separated by null terminators, return module count */
1209 GetImportModuleNames (
1213 PIMAGE_IMPORT_MODULE_DIRECTORY pid
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
1214 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_IMPORT
);
1216 // sometimes there may be no section for idata or edata
1217 // instead rdata or data section may contain these sections ..
1218 // or even module names or function names are in different section.
1219 // so that's why we need to get actual address of RVAs each time.
1220 // ...................sang cho..................
1222 // PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1223 // ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1224 // BYTE *pData = (BYTE *)pid;
1225 // DWORD *pdw = (DWORD *)pid;
1226 int nCnt
= 0, nSize
= 0, i
;
1227 char *pModule
[1024]; /* hardcoded maximum number of modules?? */
1233 // pData = (BYTE *)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1235 /* extract all import modules */
1236 while (pid
->dwRVAModuleName
)
1238 /* allocate temporary buffer for absolute string offsets */
1239 //pModule[nCnt] = (char *)(pData + pid->dwRVAModuleName);
1240 pModule
[nCnt
] = (char *) GetActualAddress (lpFile
, pid
->dwRVAModuleName
);
1241 nSize
+= strlen (pModule
[nCnt
]) + 1;
1243 /* increment to the next import directory entry */
1248 /* copy all strings to one chunk of memory */
1249 *pszModules
= (char *) calloc (nSize
, 1);
1251 for (i
= 0; i
< nCnt
; i
++)
1253 strcpy (psz
, pModule
[i
]);
1254 psz
+= strlen (psz
) + 1;
1261 // This function is rewritten by sang cho
1264 /* get import module function names separated by null terminators, return function count */
1266 GetImportFunctionNamesByModule (
1269 char **pszFunctions
)
1271 PIMAGE_IMPORT_MODULE_DIRECTORY pid
= (PIMAGE_IMPORT_MODULE_DIRECTORY
)
1272 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_IMPORT
);
1274 // sometimes there may be no section for idata or edata
1275 // instead rdata or data section may contain these sections ..
1276 // or even module names or function names are in different section.
1277 // so that's why we need to get actual address each time.
1278 // ...................sang cho..................
1280 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1281 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1283 int nCnt
= 0, nSize
= 0;
1286 DWORD dwFunctionName
;
1287 DWORD dwFunctionAddress
;
1289 char buff
[256]; // enough for any string ??
1294 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1296 /* find module's pid */
1297 while (pid
->dwRVAModuleName
&&
1298 strcmp (pszModule
, (char *) GetActualAddress (lpFile
, pid
->dwRVAModuleName
)))
1301 /* exit if the module is not found */
1302 if (!pid
->dwRVAModuleName
)
1305 // I am doing this to get rid of .dll from module name
1306 strcpy (name
, pszModule
);
1307 mnlength
= strlen (pszModule
);
1308 for (i
= 0; i
< mnlength
; i
++)
1314 /* count number of function names and length of strings */
1315 dwFunctionName
= pid
->dwRVAFunctionNameList
;
1317 // IMAGE_IMPORT_BY_NAME OR IMAGE_THUNK_DATA
1318 // modified by Sang Cho
1319 while (dwFunctionName
&&
1320 *(pdw
= (DWORD
*) GetActualAddress (lpFile
, dwFunctionName
)))
1322 if ((*pdw
) & 0x80000000)
1323 nSize
+= mnlength
+ 10 + 1 + 6;
1325 nSize
+= strlen ((char *) GetActualAddress (lpFile
, *pdw
+ 2)) + 1 + 6;
1326 dwFunctionName
+= 4;
1330 /* allocate memory for function names */
1331 *pszFunctions
= (char *) calloc (nSize
, 1);
1332 psz
= *pszFunctions
;
1335 // I modified this part to store function address (4 bytes),
1336 // ord number (2 bytes),
1337 // and name strings (which was there originally)
1338 // so that's why there are 6 more bytes...... +6, or +4 and +2 etc.
1339 // these informations are used where they are needed.
1340 // ...........sang cho..................
1342 /* copy function names to mempry pointer */
1343 dwFunctionName
= pid
->dwRVAFunctionNameList
;
1344 dwFunctionAddress
= pid
->dwRVAFunctionAddressList
;
1345 while (dwFunctionName
&&
1346 *(pdw
= (DWORD
*) GetActualAddress (lpFile
, dwFunctionName
)))
1348 if ((*pdw
) & 0x80000000)
1350 *(int *) psz
= (int) (*(DWORD
*) GetActualAddress (lpFile
, dwFunctionAddress
));
1352 *(short *) psz
= *(short *) pdw
;
1354 sprintf (buff
, "%s:NoName%04d", name
, nnid
++);
1356 psz
+= strlen (buff
) + 1;
1360 *(int *) psz
= (int) (*(DWORD
*) GetActualAddress (lpFile
, dwFunctionAddress
));
1362 *(short *) psz
= (*(short *) GetActualAddress (lpFile
, *pdw
));
1364 strcpy (psz
, (char *) GetActualAddress (lpFile
, *pdw
+ 2));
1365 psz
+= strlen ((char *) GetActualAddress (lpFile
, *pdw
+ 2)) + 1;
1367 dwFunctionName
+= 4;
1368 dwFunctionAddress
+= 4;
1378 // This function is written by sang cho
1381 /* get numerically expressed string length */
1386 if (!isdigit (*psz
))
1388 if (isdigit (*(psz
+ 1)))
1389 return (*psz
- '0') * 10 + *(psz
+ 1) - '0';
1398 // This function is written by sang cho
1402 /* translate parameter part of condensed name */
1404 GetPreviousParamString (
1405 char *xpin
, // read-only source
1406 char *xpout
) // translated result
1419 printf ("\n **error PreviousParamString1 char = %c", *pin
);
1427 else if (*pin
== '<')
1429 else if (*pin
== ')')
1437 else if (strchr (",(", *pin
))
1442 //printf("\n ----- %s", pin);
1443 if (strchr (",(", *pin
))
1446 } // printf("\n %s", pin); }
1450 printf ("\n **error PreviousParamString2");
1455 strncpy (pout
, pin
, n
);
1463 // This function is written by sang cho
1467 /* translate parameter part of condensed name */
1469 TranslateParameters (
1470 char **ppin
, // read-only source
1471 char **ppout
, // translated result
1472 char **pps
) // parameter stack
1477 char *pin
, *pout
, *ps
;
1479 //printf(" %c ", **in);
1488 strcpy (pout
, "byte");
1493 strcpy (pout
, "char");
1498 strcpy (pout
, "double");
1503 strcpy (pout
, "float");
1508 strcpy (pout
, "long double");
1513 strcpy (pout
, "int");
1518 strcpy (pout
, "long");
1523 strcpy (pout
, "short");
1528 strcpy (pout
, "void");
1532 // postfix processing
1535 if (*(pin
+ 1) == 'p')
1558 if (*(pin
+ 1) == 'p')
1572 // repeat processing
1574 if (isdigit (*(pin
+ 1)))
1576 n
= *(pin
+ 1) - '0';
1579 GetPreviousParamString (pout
, name
);
1580 strcpy (pout
, name
);
1581 pout
+= strlen (name
);
1582 for (i
= 1; i
< n
; i
++)
1585 strcpy (pout
, name
);
1586 pout
+= strlen (name
);
1592 // prefix processing
1602 strcpy (pout
, "const ");
1610 strcpy (pout
, "static ");
1618 strcpy (pout
, "!1!");
1626 // need to process postfix finally
1628 if (strchr ("tqx", c
))
1630 if (*(pin
) && !strchr ("@$%", *(pin
)))
1640 strcpy (pout
, "*&");
1645 strcpy (pout
, "**");
1660 strcpy (pout
, "!2!");
1665 if (*(pin
) && !strchr ("@$%", *(pin
)))
1674 // This function is written by sang cho
1678 /* translate parameter part of condensed name */
1681 char **ppin
, // read-only source
1682 char **ppout
, // translated result
1683 char **pps
, // parameter stack
1684 Str_P
* pcstr
) // currently stored string
1688 char *pin
, *pout
, *ps
;
1690 BOOL stringMode
= TRUE
;
1697 if (strncmp (pin
, "bctr", 4) == 0)
1699 strncpy (pout
, c_str
.pos
, c_str
.length
);
1700 pout
+= c_str
.length
;
1703 else if (strncmp (pin
, "bdtr", 4) == 0)
1706 strncpy (pout
, c_str
.pos
, c_str
.length
);
1707 pout
+= c_str
.length
;
1710 else if (*pin
== 'o')
1712 strcpy (pout
, "const ");
1717 else if (*pin
== 'q')
1724 else if (*pin
== 't')
1726 //if (*(ps-1) == 't') { *pout++ = ','; pin++; } // this also got me...
1727 //else october 12 .. sang
1735 else if (strncmp (pin
, "xq", 2) == 0)
1743 else if (strncmp (pin
, "bcall", 5) == 0)
1745 strcpy (pout
, "operator ()");
1749 else if (strncmp (pin
, "bsubs", 5) == 0)
1751 strcpy (pout
, "operator []");
1755 else if (strncmp (pin
, "bnwa", 4) == 0)
1757 strcpy (pout
, "operator new[]");
1761 else if (strncmp (pin
, "bdla", 4) == 0)
1763 strcpy (pout
, "operator delete[]");
1767 else if (strncmp (pin
, "bnew", 4) == 0)
1769 strcpy (pout
, "operator new");
1773 else if (strncmp (pin
, "bdele", 5) == 0)
1775 strcpy (pout
, "operator delete");
1779 else if (strncmp (pin
, "blsh", 4) == 0)
1781 strcpy (pout
, "operator <<");
1785 else if (strncmp (pin
, "brsh", 4) == 0)
1787 strcpy (pout
, "operator >>");
1791 else if (strncmp (pin
, "binc", 4) == 0)
1793 strcpy (pout
, "operator ++");
1797 else if (strncmp (pin
, "bdec", 4) == 0)
1799 strcpy (pout
, "operator --");
1803 else if (strncmp (pin
, "badd", 4) == 0)
1805 strcpy (pout
, "operator +");
1809 else if (strncmp (pin
, "brplu", 5) == 0)
1811 strcpy (pout
, "operator +=");
1815 else if (strncmp (pin
, "bdiv", 4) == 0)
1817 strcpy (pout
, "operator /");
1821 else if (strncmp (pin
, "brdiv", 5) == 0)
1823 strcpy (pout
, "operator /=");
1827 else if (strncmp (pin
, "bmul", 4) == 0)
1829 strcpy (pout
, "operator *");
1833 else if (strncmp (pin
, "brmul", 5) == 0)
1835 strcpy (pout
, "operator *=");
1839 else if (strncmp (pin
, "basg", 4) == 0)
1841 strcpy (pout
, "operator =");
1845 else if (strncmp (pin
, "beql", 4) == 0)
1847 strcpy (pout
, "operator ==");
1851 else if (strncmp (pin
, "bneq", 4) == 0)
1853 strcpy (pout
, "operator !=");
1857 else if (strncmp (pin
, "bor", 3) == 0)
1859 strcpy (pout
, "operator |");
1863 else if (strncmp (pin
, "bror", 4) == 0)
1865 strcpy (pout
, "operator |=");
1869 else if (strncmp (pin
, "bcmp", 4) == 0)
1871 strcpy (pout
, "operator ~");
1875 else if (strncmp (pin
, "bnot", 4) == 0)
1877 strcpy (pout
, "operator !");
1881 else if (strncmp (pin
, "band", 4) == 0)
1883 strcpy (pout
, "operator &");
1887 else if (strncmp (pin
, "brand", 5) == 0)
1889 strcpy (pout
, "operator &=");
1893 else if (strncmp (pin
, "bxor", 4) == 0)
1895 strcpy (pout
, "operator ^");
1899 else if (strncmp (pin
, "brxor", 5) == 0)
1901 strcpy (pout
, "operator ^=");
1907 strcpy (pout
, "!$$$!");
1914 } // end of '$' processing
1918 //----------------------------------------------------------------------
1919 // structure to store string tokens
1920 //----------------------------------------------------------------------
1921 //typedef struct _Str_P {
1922 // char flag; // string_flag '@' or '%' or '#'
1923 // char *pos; // starting postion of string
1924 // int length; // length of string
1925 // BOOL wasString; // if it were stringMode or not
1927 //----------------------------------------------------------------------
1929 // I think I knocked it down finally. But who knows?
1930 // october 12, 1997 ... sang
1932 // well I have to rewrite whole part of TranslateFunctionName..
1933 // this time I am a little bit more experienced than 5 days ago.
1934 // or am i??? anyway i use stacks instead of recurcive calls
1935 // and i hope this will take care of every symptoms i have experienced..
1936 // october 10, 1997 .... sang
1937 // It took a lot of time for me to figure out what is all about....
1938 // but still some prefixes like z (static)
1939 // -- or some types like b (byte) ,g (long double) ,s (short) --
1940 // -- or postfix like M ( * )
1941 // -- or $or ( & ) which is pretty wierd. .. added.. october 12
1942 // -- also $t business is quite tricky too. (templates)
1943 // there may be a lot of things undiscovered yet....
1944 // I am not so sure my interpretation is correct or not
1945 // If I am wrong please let me know.
1946 // october 8, 1997 .... sang
1949 // This function is written by sang cho
1952 /* translate condesed import function name */
1954 TranslateFunctionName (
1963 static char buff
[512]; // result of translation
1966 char pStack
[32]; // parameter processing stack
1968 Str_P sStack
[32]; // String processing stack
1970 Str_P tok
; // String token
1972 Str_P c_str
; // current string
1975 char *endTab
[8]; // end of string position check
1979 BOOL stringMode
= TRUE
;
1987 //................................................................
1988 // serious users may need to run the following code.
1989 // so I may need to include some flag options...
1990 // If you want to know about how translation is done,
1991 // you can just revive following line and you can see it.
1992 // october 6, 1997 ... sang cho
1993 //printf ("\n................................... %s", psz); // for debugging...
2000 tok
.wasString
= stringMode
;
2001 sStack
[is
++] = tok
; // initialize sStack with dummy marker
2009 //---------------------------------------------
2010 // check for the end of number specified string
2011 //---------------------------------------------
2015 for (i
= 0; i
< iend
; i
++)
2016 if (pin
== endTab
[i
])
2020 // move the end of endTab to ith position
2021 endTab
[i
] = endTab
[iend
- 1];
2024 // get top of the string stack
2025 tok
= sStack
[is
- 1];
2027 // I am expecting '#' token from stack
2028 if (tok
.flag
!= '#')
2031 printf ("\n**some serious error1** %c is = %d char = %c",
2032 tok
.flag
, is
, *pin
);
2036 // pop '#' token I am happy now.
2039 //printf("\n pop # token ... current char = %c", c);
2040 //else printf("\n pop percent token..next char = NULL");
2045 stringMode
= tok
.wasString
;
2049 // need to process postfix finally
2051 if (strchr ("qtx", cc
))
2053 if (!strchr ("@$%", c
))
2061 strcpy (pout
, "*&");
2066 strcpy (pout
, "**");
2081 strcpy (pout
, "!3!");
2086 if (!strchr ("@$%", c
))
2090 // string mode restored...
2093 else; // do nothing..
2097 //------------------------------------------------
2098 // special control symbol processing:
2099 //------------------------------------------------
2101 if (strchr ("@$%", c
))
2104 //---------------------------------------------------------------
2105 // string part processing : no '$' met yet
2106 // or inside of '%' block
2107 // or inside of '#' block (numbered string)
2108 //---------------------------------------------------------------
2110 else if (stringMode
)
2112 //else if (is > 1) *pout++ = *pin++;
2114 //------------------------------------------------
2115 // parameter part processing: '$' met
2116 //------------------------------------------------
2118 else // parameter processing
2122 TranslateParameters (&pin
, &pout
, &ps
);
2123 else // number specified string processing
2126 n
= GetStringLength (pin
);
2134 //printf("\n push # token .. char = %c", *pin);
2135 //else printf("\n push percent token..next char = NULL");
2139 tok
.wasString
= stringMode
;
2142 // mark end of input string
2143 endTab
[iend
++] = pin
+ n
;
2147 } // end of inner while loop
2149 // beginning of new string or end of string ( quotation mark )
2154 pin
++; // anyway we have to proceed...
2156 tok
= sStack
[is
- 1]; // get top of the sStack
2158 if (tok
.flag
== '%')
2160 // pop '%' token and set c_str
2162 //printf("\n pop percent token..next char = %c", *pin);
2163 //else printf("\n pop percent token..next char = NULL");
2166 c_str
.length
= pout
- c_str
.pos
;
2167 if (*(ps
- 1) == 't')
2171 stringMode
= tok
.wasString
;
2175 printf ("\n**some string error3** stack = %c", *(ps
- 1));
2179 else if (tok
.flag
== 'A' || tok
.flag
== '#')
2183 //printf("\n push percent token..next char = %c", *pin);
2184 //else printf("\n push percent token..next char = NULL");
2188 tok
.wasString
= stringMode
;
2193 printf ("\n**some string error5**");
2198 // sometimes we need string to use as constructor name or destructor name
2200 else if (c
== '@') // get string from previous marker upto here.
2204 tok
= sStack
[is
- 1];
2206 c_str
.pos
= tok
.pos
;
2207 c_str
.length
= pout
- tok
.pos
;
2208 c_str
.wasString
= stringMode
;
2213 // we need to take care of parameter control sequence
2215 else if (c
== '$') // need to precess template or parameter part
2220 stringMode
= StringExpands (&pin
, &pout
, &ps
, &c_str
);
2222 { // template parameter mode I guess "$t"
2230 printf ("\nMYGOODNESS1 %c", *pin
);
2234 //if (*ps == 't') *pout++ = '>';
2235 //else { printf("\nMYGOODNESS2"); exit(0);}
2236 *pout
++ = ','; //pin++; ..this almost blowed me....
2239 // real parameter mode I guess
2240 // unexpected case is found ... humm what can I do...
2243 // this is newly found twist.. it really hurts.
2254 printf ("\n** I GIVEUP ***");
2264 else if (*ps
== '&')
2266 else if (*ps
== 'p')
2271 else if (*ps
== 'r')
2278 printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin
);
2289 else if (*ps
== '&')
2291 else if (*ps
== 'p')
2296 else if (*ps
== 'r')
2303 printf ("\n*** SOMETHING IS WRONG2***");
2312 } // end of '$' processing
2314 } // end of outer while loop
2316 // need to process remaining parameter stack
2331 strcpy (pout
, " const");
2335 strcpy (pout
, "*&");
2339 strcpy (pout
, "**");
2349 strcpy (pout
, "!4!");
2361 // This function is written by sang cho
2364 /* get exported function names separated by null terminators, return count of functions */
2366 GetExportFunctionNames (
2368 char **pszFunctions
)
2370 //PIMAGE_SECTION_HEADER psh;
2371 PIMAGE_EXPORT_DIRECTORY ped
;
2373 DWORD imageBase
; //===========================
2376 {NULL
,}; // maximum number of functions
2377 //=============================
2379 char buff
[256]; // enough for any string ??
2381 char *psz
= NULL
; //===============================
2387 int i
, nCnt
= 0, ntmp
= 0;
2388 int enid
= 0, ordBase
= 1; // usally ordBase is 1....
2392 /* get section header and pointer to data directory for .edata section */
2393 ped
= (PIMAGE_EXPORT_DIRECTORY
)
2394 ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_EXPORT
);
2400 // sometimes there may be no section for idata or edata
2401 // instead rdata or data section may contain these sections ..
2402 // or even module names or function names are in different section.
2403 // so that's why we need to get actual address each time.
2404 // ...................sang cho..................
2406 //psh = (PIMAGE_SECTION_HEADER)
2407 //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2409 //if (psh == NULL) return 0;
2411 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2414 /* determine the offset of the export function names */
2416 pdwAddress
= (DWORD
*) GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfFunctions
);
2418 imageBase
= (DWORD
) GetImageBase (lpFile
);
2420 ordBase
= ped
->Base
;
2422 if (ped
->NumberOfNames
> 0)
2424 pdwNames
= (DWORD
*)
2425 GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNames
);
2427 GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNameOrdinals
);
2430 /* figure out how much memory to allocate for all strings */
2431 for (i
= 0; i
< (int) ped
->NumberOfNames
; i
++)
2433 nCnt
+= strlen ((char *)
2434 GetActualAddress (lpFile
, *(DWORD
*) pdwNames
)) + 1 + 6;
2437 // get the number of unnamed functions
2438 for (i
= 0; i
< (int) ped
->NumberOfFunctions
; i
++)
2441 // add memory required to show unnamed functions.
2442 if (ntmp
> (int) ped
->NumberOfNames
)
2443 nCnt
+= 18 * (ntmp
- (int) ped
->NumberOfNames
);
2445 /* allocate memory for function names */
2447 *pszFunctions
= (char *) calloc (nCnt
, 1);
2448 pdwNames
= (DWORD
*) GetActualAddress (lpFile
, (DWORD
) ped
->AddressOfNames
);
2450 /* copy string pointer to buffer */
2452 for (i
= 0; i
< (int) ped
->NumberOfNames
; i
++)
2454 pfns
[(int) (*pwOrd
) + ordBase
] =
2455 (char *) GetActualAddress (lpFile
, *(DWORD
*) pdwNames
);
2460 psz
= *pszFunctions
;
2463 for (i
= ordBase
; i
< (int) ped
->NumberOfFunctions
+ ordBase
; i
++)
2465 if (*pdwAddress
> 0)
2467 *(DWORD
*) psz
= imageBase
+ *pdwAddress
;
2469 *(WORD
*) psz
= (WORD
) (i
);
2473 strcpy (psz
, pfns
[i
]);
2474 psz
+= strlen (psz
) + 1;
2478 sprintf (buff
, "ExpFn%04d()", enid
++);
2492 /* determine the total number of resources in the section */
2494 GetNumberOfResources (
2497 PIMAGE_RESOURCE_DIRECTORY prdRoot
, prdType
;
2498 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
;
2502 /* get root directory of resource tree */
2503 if ((prdRoot
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2504 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2507 /* set pointer to first resource type entry */
2508 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) ((DWORD
) prdRoot
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2510 /* loop through all resource directory entry types */
2511 for (i
= 0; i
< prdRoot
->NumberOfIdEntries
; i
++)
2513 /* locate directory or each resource type */
2514 prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ((int) prdRoot
+ (int) prde
->OffsetToData
);
2516 /* mask off most significant bit of the data offset */
2517 prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ((DWORD
) prdType
^ 0x80000000);
2519 /* increment count of name'd and ID'd resources in directory */
2520 nCnt
+= prdType
->NumberOfNamedEntries
+ prdType
->NumberOfIdEntries
;
2522 /* increment to next entry */
2532 // This function is rewritten by sang cho
2535 /* name each type of resource in the section */
2537 GetListOfResourceTypes (
2541 PIMAGE_RESOURCE_DIRECTORY prdRoot
;
2542 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
;
2549 /* get root directory of resource tree */
2550 if ((prdRoot
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2551 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2554 /* allocate enuff space to cover all types */
2555 nCnt
= prdRoot
->NumberOfIdEntries
* (MAXRESOURCENAME
+ 1);
2556 *pszResTypes
= (char *) calloc (nCnt
, 1);
2557 if ((pMem
= *pszResTypes
) == NULL
)
2560 /* set pointer to first resource type entry */
2561 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
) ((DWORD
) prdRoot
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2563 /* loop through all resource directory entry types */
2564 for (i
= 0; i
< prdRoot
->NumberOfIdEntries
; i
++)
2566 prdeName
= prde
->Name
;
2568 //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2569 // pMem += strlen (pMem) + 1;
2571 // modified by ...................................Sang Cho..
2572 // I can't user M/S provied funcitons here so I have to figure out
2573 // how to do above functions. But I can settle down with the following
2574 // code, which works pretty good for me.
2578 strcpy (pMem
, "RT_CURSOR");
2581 else if (prdeName
== 2)
2583 strcpy (pMem
, "RT_BITMAP");
2586 else if (prdeName
== 3)
2588 strcpy (pMem
, "RT_ICON ");
2591 else if (prdeName
== 4)
2593 strcpy (pMem
, "RT_MENU ");
2596 else if (prdeName
== 5)
2598 strcpy (pMem
, "RT_DIALOG");
2601 else if (prdeName
== 6)
2603 strcpy (pMem
, "RT_STRING");
2606 else if (prdeName
== 7)
2608 strcpy (pMem
, "RT_FONTDIR");
2611 else if (prdeName
== 8)
2613 strcpy (pMem
, "RT_FONT ");
2616 else if (prdeName
== 9)
2618 strcpy (pMem
, "RT_ACCELERATORS");
2621 else if (prdeName
== 10)
2623 strcpy (pMem
, "RT_RCDATA");
2626 else if (prdeName
== 11)
2628 strcpy (pMem
, "RT_MESSAGETABLE");
2631 else if (prdeName
== 12)
2633 strcpy (pMem
, "RT_GROUP_CURSOR");
2636 else if (prdeName
== 14)
2638 strcpy (pMem
, "RT_GROUP_ICON ");
2641 else if (prdeName
== 16)
2643 strcpy (pMem
, "RT_VERSION");
2646 else if (prdeName
== 17)
2648 strcpy (pMem
, "RT_DLGINCLUDE ");
2651 else if (prdeName
== 19)
2653 strcpy (pMem
, "RT_PLUGPLAY ");
2656 else if (prdeName
== 20)
2658 strcpy (pMem
, "RT_VXD ");
2661 else if (prdeName
== 21)
2663 strcpy (pMem
, "RT_ANICURSOR ");
2666 else if (prdeName
== 22)
2668 strcpy (pMem
, "RT_ANIICON");
2671 else if (prdeName
== 0x2002)
2673 strcpy (pMem
, "RT_NEWBITMAP");
2676 else if (prdeName
== 0x2004)
2678 strcpy (pMem
, "RT_NEWMENU");
2681 else if (prdeName
== 0x2005)
2683 strcpy (pMem
, "RT_NEWDIALOG");
2686 else if (prdeName
== 0x7fff)
2688 strcpy (pMem
, "RT_ERROR ");
2693 sprintf (buff
, "RT_UNKNOWN:%08lX", prdeName
);
2694 strcpy (pMem
, buff
);
2700 return prdRoot
->NumberOfIdEntries
;
2706 // This function is written by sang cho
2709 /* copy menu information */
2712 char **psz
, // results
2713 WORD
** pMenu
, // read-only
2720 pmax
= (WORD
*) ((DWORD
) pwd
+ size
);
2721 ptr
= (WORD
*) (*psz
);
2727 *psz
= (char *) ptr
;
2734 // This function is written by sang cho
2737 /* obtain menu information */
2752 flag
= *pwd
; // so difficult to correctly code this so let's try this
2755 (*len
) += 2; // flag store
2757 if ((flag
& 0x0010) == 0)
2762 (*len
) += 2; // id store
2775 (*len
)++; // name and null character
2777 pwd
++; // skip double null
2779 if ((flag
& 0x0010) == 0) // normal node: done
2785 // popup node: need to go on...
2789 flag1
= (WORD
) MenuScan (len
, pMenu
);
2794 // fill # of details to num above
2802 // This function is written by sang cho
2805 /* copy menu information */
2813 char *ptr
/*, *pTemp*/;
2816 WORD id
/*, ispopup*/;
2820 //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2821 flag
= *pwd
; // so difficult to correctly code this so let's try this
2824 if ((flag
& 0x0010) == 0)
2826 *(WORD
*) ptr
= flag
; // flag store
2829 *(WORD
*) ptr
= id
= *pwd
; // id store
2836 *(WORD
*) ptr
= flag
; // flag store
2841 while (*pwd
) // name extract
2844 *ptr
= *(char *) pwd
;
2847 } //name and null character
2851 pwd
++; // skip double null
2853 if ((flag
& 0x0010) == 0) // normal node: done
2862 // popup node: need to go on...
2868 flag1
= (WORD
) MenuFill (psz
, pMenu
);
2874 // fill # of details to num above
2875 //*(WORD *)pTemp = (WORD)num;
2883 //==============================================================================
2884 // The following program is based on preorder-tree-traversal.
2885 // once you understand how to traverse.....
2886 // the rest is pretty straight forward.
2887 // still we need to scan it first and fill it next time.
2888 // and finally we can print it.
2890 // This function is written by sang cho
2891 // September 29, 1997
2892 // revised october 2, 1997
2893 // revised october 12, 1997
2894 // ..............................................................................
2895 // ------------------------------------------------------------------------------
2896 // I use same structure - which is used in P.E. programs - for my reporting.
2897 // So, my structure is as follows:
2898 // # of menu name is stored else where ( in directory I suppose )
2899 // supermenuname null terminated string, only ascii is considered.
2900 // flag tells : node is a leaf or a internal node.
2901 // popupname null terminated string
2903 // flag normal menu flag (leaf node)
2904 // id normal menu id
2905 // name normal menu name
2907 // flag popup menu flag (internal node)
2908 // popupname popup menu name
2910 // flag it may folows
2911 // id normal menu id
2912 // name normal menu name
2915 // popupname popup menu name
2917 // it goes on like this,
2918 // but usually, it only goes a few steps,...
2919 // ------------------------------------------------------------------------------
2920 /* scan menu and copy menu */
2926 PIMAGE_RESOURCE_DIRECTORY prdType
, prdName
, prdLanguage
;
2927 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
, prde1
;
2928 PIMAGE_RESOURCE_DIR_STRING_U pMenuName
;
2929 PIMAGE_RESOURCE_DATA_ENTRY prData
;
2930 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
2931 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE);
2932 PIMAGE_MENU_HEADER pMenuHeader
;
2933 //PIMAGE_POPUP_MENU_ITEM pPopup;
2935 //PIMAGE_NORMAL_MENU_ITEM pNormal;
2937 int /*nCnt = 0,*/ i
, j
;
2940 int sLength
, nMenus
;
2944 //DWORD dwBase; obsolete
2945 char *pMem
/*, *pTemp*/;
2946 //BOOL isStrange = FALSE;
2949 /* get root directory of resource tree */
2950 if ((prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
2951 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
2954 /* set pointer to first resource type entry */
2955 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2956 ((DWORD
) prdType
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2958 for (i
= 0; i
< prdType
->NumberOfIdEntries
; i
++)
2960 if (prde
->Name
== RT_MENU
)
2964 if (prde
->Name
!= RT_MENU
)
2967 prdName
= (PIMAGE_RESOURCE_DIRECTORY
)
2968 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
2969 if (prdName
== NULL
)
2972 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2973 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2975 // sometimes previous code tells you lots of things hidden underneath
2976 // I wish I could save all the revisions I made ... but again .... sigh.
2977 // october 12, 1997 sang
2978 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2980 nMenus
= prdName
->NumberOfNamedEntries
+ prdName
->NumberOfIdEntries
;
2983 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
2985 pMenuName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
2986 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
2987 sLength
+= pMenuName
->Length
+ 1;
2989 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
2990 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
2991 if (prdLanguage
== NULL
)
2994 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
2995 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
2997 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
2998 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3002 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3003 GetActualAddress (lpFile
, prData
->OffsetToData
);
3006 // normally wVersion and cbHeaderSize should be zero
3007 // but if it is not then nothing is known to us...
3008 // so let's do our best ... namely guessing .... and trying ....
3009 // ... and suffering ...
3010 // it gave me many sleepless (not exactly but I like to say this) nights.
3014 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3017 pwd
= (WORD
*) ((DWORD
) pMenuHeader
+ 16);
3018 size
= prData
->Size
;
3019 // expect to return the length needed to report.
3020 // sixteen more bytes to do something
3021 sLength
+= 16 + size
;
3022 //StrangeMenuScan (&sLength, &pwd, size);
3028 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3031 flag
= (WORD
) MenuScan (&sLength
, (WORD
**) (&pPopup
));
3038 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3042 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3043 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3044 if (prdLanguage
== NULL
)
3047 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3048 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3050 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3051 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3055 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3056 GetActualAddress (lpFile
, prData
->OffsetToData
);
3058 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3060 pwd
= (WORD
*) ((DWORD
) pMenuHeader
+ 16);
3061 size
= prData
->Size
;
3062 // expect to return the length needed to report.
3063 // sixteen more bytes to do something
3064 sLength
+= 16 + size
;
3065 //StrangeMenuScan (&sLength, &pwd, size);
3071 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3074 flag
= (WORD
) MenuScan (&sLength
, (WORD
**) (&pPopup
));
3082 // allocate memory for menu names
3084 *pszResTypes
= (char *) calloc (sLength
, 1);
3086 pMem
= *pszResTypes
;
3088 // and start all over again
3090 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3091 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3093 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3095 pMenuName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3096 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3099 for (j
= 0; j
< pMenuName
->Length
; j
++)
3100 *pMem
++ = (char) (pMenuName
->NameString
[j
]);
3105 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3106 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3107 if (prdLanguage
== NULL
)
3110 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3111 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3113 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3114 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3118 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3119 GetActualAddress (lpFile
, prData
->OffsetToData
);
3121 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3123 pwd
= (WORD
*) ((DWORD
) pMenuHeader
);
3124 size
= prData
->Size
;
3125 strcpy (pMem
, ":::::::::::");
3127 *(int *) pMem
= size
;
3129 StrangeMenuFill (&pMem
, &pwd
, size
);
3135 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3138 flag
= (WORD
) MenuFill (&pMem
, (WORD
**) (&pPopup
));
3145 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3148 sprintf (buff
, "MenuId_%04lX", (prde
->Name
));
3149 strcpy (pMem
, buff
);
3150 pMem
+= strlen (buff
) + 1;
3152 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3153 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3154 if (prdLanguage
== NULL
)
3157 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3158 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3160 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3161 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3165 pMenuHeader
= (PIMAGE_MENU_HEADER
)
3166 GetActualAddress (lpFile
, prData
->OffsetToData
);
3168 if (pMenuHeader
->wVersion
| pMenuHeader
->cbHeaderSize
)
3170 pwd
= (WORD
*) ((DWORD
) pMenuHeader
);
3171 size
= prData
->Size
;
3172 strcpy (pMem
, ":::::::::::");
3174 *(int *) pMem
= size
;
3176 StrangeMenuFill (&pMem
, &pwd
, size
);
3182 ((DWORD
) pMenuHeader
+ sizeof (IMAGE_MENU_HEADER
));
3185 flag
= (WORD
) MenuFill (&pMem
, (WORD
**) (&pPopup
));
3198 // This function is written by sang cho
3201 /* print contents of menu */
3209 //WORD flag1, flag2;
3213 //return dumpMenu (psz, size);
3217 if (strncmp (ptr
, ":::::::::::", 11) != 0)
3219 printf ("\n#### I don't know why!!!");
3220 dumpMenu (psz
, 1024);
3230 return dumpMenu (psz
, num
);
3232 // I will write some code later...
3240 // This function is written by sang cho
3243 /* print contents of menu */
3250 int /*i, */ j
, k
, l
;
3251 WORD id
/*, num */ ;
3258 //num = *(WORD *)ptr;
3262 flag
= *(WORD
*) ptr
;
3263 if (flag
& 0x0010) // flag == popup
3267 for (j
= 0; j
< indent
; j
++)
3270 printf ("%s {Popup}\n", ptr
);
3271 ptr
+= strlen (ptr
) + 1;
3273 PrintMenu (indent
+ 5, psz
);
3276 else // ispopup == 0
3280 for (j
= 0; j
< indent
; j
++)
3288 if (strchr (buff
, 0x09) != NULL
)
3290 for (k
= 0; k
< l
; k
++)
3291 if (buff
[k
] == 0x09)
3293 for (j
= 0; j
< l
- k
; j
++)
3294 buff
[31 - j
] = buff
[l
- j
];
3295 for (j
= k
; j
< 32 + k
- l
; j
++)
3298 if (strchr (buff
, 0x08) != NULL
)
3300 for (k
= 0; k
< l
; k
++)
3301 if (buff
[k
] == 0x08)
3303 for (j
= 0; j
< l
- k
; j
++)
3304 buff
[31 - j
] = buff
[l
- j
];
3305 for (j
= k
; j
< 32 + k
- l
; j
++)
3308 printf ("%s", buff
);
3310 for (j
= l
; j
< 32; j
++)
3312 printf ("[ID=%04Xh]", id
);
3323 // This function is written by sang cho
3326 /* the format of menu is not known so I'll do my best */
3333 int i
, j
, k
, n
, l
, c
;
3339 for (i
= 0; i
< (size
/ 16) + 1; i
++)
3342 for (j
= 0; j
< 16; j
++)
3370 for (k
= 0; k
< l
; k
++)
3371 if (isprint (c
= buff
[k
]))
3388 // This function is written by sang cho
3391 /* scan dialog box and copy dialog box */
3393 GetContentsOfDialog (
3397 PIMAGE_RESOURCE_DIRECTORY prdType
, prdName
, prdLanguage
;
3398 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde
, prde1
;
3399 PIMAGE_RESOURCE_DIR_STRING_U pDialogName
;
3400 PIMAGE_RESOURCE_DATA_ENTRY prData
;
3401 PIMAGE_DIALOG_HEADER pDialogHeader
;
3402 //PIMAGE_CONTROL_DATA pControlData;
3404 int /*nCnt = 0,*/ i
, j
;
3407 int sLength
, nDialogs
;
3411 char *pMem
/*, *pTemp*/;
3412 //BOOL isStrange = FALSE;
3415 /* get root directory of resource tree */
3416 if ((prdType
= (PIMAGE_RESOURCE_DIRECTORY
) ImageDirectoryOffset
3417 (lpFile
, IMAGE_DIRECTORY_ENTRY_RESOURCE
)) == NULL
)
3420 /* set pointer to first resource type entry */
3421 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3422 ((DWORD
) prdType
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3424 for (i
= 0; i
< prdType
->NumberOfIdEntries
; i
++)
3426 if (prde
->Name
== RT_DIALOG
)
3430 if (prde
->Name
!= RT_DIALOG
)
3433 prdName
= (PIMAGE_RESOURCE_DIRECTORY
)
3434 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3435 if (prdName
== NULL
)
3438 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3439 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3442 nDialogs
= prdName
->NumberOfNamedEntries
+ prdName
->NumberOfIdEntries
;
3445 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3447 pDialogName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3448 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3449 sLength
+= pDialogName
->Length
+ 1;
3451 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3452 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3453 if (prdLanguage
== NULL
)
3456 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3457 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3459 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3460 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3464 size
= prData
->Size
;
3465 sLength
+= 4 + size
;
3468 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3472 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3473 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3474 if (prdLanguage
== NULL
)
3477 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3478 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3480 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3481 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3485 size
= prData
->Size
;
3486 sLength
+= 4 + size
;
3490 // allocate memory for menu names
3492 *pszResTypes
= (char *) calloc (sLength
, 1);
3494 pMem
= *pszResTypes
;
3496 // and start all over again
3498 prde
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3499 ((DWORD
) prdName
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3501 for (i
= 0; i
< prdName
->NumberOfNamedEntries
; i
++)
3503 pDialogName
= (PIMAGE_RESOURCE_DIR_STRING_U
)
3504 ((DWORD
) prdType
+ (prde
->Name
^ 0x80000000));
3507 for (j
= 0; j
< pDialogName
->Length
; j
++)
3508 *pMem
++ = (char) (pDialogName
->NameString
[j
]);
3513 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3514 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3515 if (prdLanguage
== NULL
)
3518 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3519 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3521 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3522 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3526 pDialogHeader
= (PIMAGE_DIALOG_HEADER
)
3527 GetActualAddress (lpFile
, prData
->OffsetToData
);
3531 pwd
= (WORD
*) ((DWORD
) pDialogHeader
);
3532 size
= prData
->Size
;
3533 *(int *) pMem
= size
;
3535 StrangeMenuFill (&pMem
, &pwd
, size
);
3539 for (i
= 0; i
< prdName
->NumberOfIdEntries
; i
++)
3542 sprintf (buff
, "DialogId_%04lX", (prde
->Name
));
3543 strcpy (pMem
, buff
);
3544 pMem
+= strlen (buff
) + 1;
3546 prdLanguage
= (PIMAGE_RESOURCE_DIRECTORY
)
3547 ((DWORD
) prdType
+ (prde
->OffsetToData
^ 0x80000000));
3548 if (prdLanguage
== NULL
)
3550 printf ("\nprdLanguage = NULL");
3554 prde1
= (PIMAGE_RESOURCE_DIRECTORY_ENTRY
)
3555 ((DWORD
) prdLanguage
+ sizeof (IMAGE_RESOURCE_DIRECTORY
));
3557 prData
= (PIMAGE_RESOURCE_DATA_ENTRY
)
3558 ((DWORD
) prdType
+ prde1
->OffsetToData
);
3561 printf ("\nprData = NULL");
3565 pDialogHeader
= (PIMAGE_DIALOG_HEADER
)
3566 GetActualAddress (lpFile
, prData
->OffsetToData
);
3569 pwd
= (WORD
*) ((DWORD
) pDialogHeader
);
3570 size
= prData
->Size
;
3571 *(int *) pMem
= size
;
3573 StrangeMenuFill (&pMem
, &pwd
, size
);
3583 // This function is written by sang cho
3586 /* print contents of dialog */
3588 PrintNameOrOrdinal (
3594 if (*(WORD
*) ptr
== 0xFFFF)
3597 printf ("%04X", *(WORD
*) ptr
);
3603 while (*(WORD
*) ptr
)
3605 printf ("%c", *ptr
);
3616 // This function is written by sang cho
3619 /* print contents of dialog */
3624 int i
/*, j, k, l, n, c*/;
3630 BOOL isStrange
= FALSE
;
3633 size
= *(int *) ptr
;
3637 // IStype of Dialog Header
3638 flag
= *(DWORD
*) ptr
;
3640 // check if flag is right or not
3641 // it has been observed that some dialog information is strange
3642 // and extra work is needed to fix that ... so let's try something
3645 if ((flag
& 0xFFFF0000) == 0xFFFF0000)
3647 flag
= *(DWORD
*) (ptr
+ 12);
3648 num
= *(short *) (ptr
+ 16);
3654 num
= *(short *) (ptr
+ 8);
3657 printf (", # of Controls=%03d, Caption:%c", num
, '"');
3660 if (*(WORD
*) ptr
== 0xFFFF)
3661 ptr
+= 4; // ordinal
3665 while (*(WORD
*) ptr
)
3671 if (*(WORD
*) ptr
== 0xFFFF)
3672 ptr
+= 4; // ordinal
3676 while (*(WORD
*) ptr
)
3682 while (*(WORD
*) ptr
)
3684 printf ("%c", *ptr
);
3691 if (flag
& 0x00000040)
3696 ptr
+= 2; // FONT size
3698 while (*(WORD
*) ptr
)
3701 ptr
+= 2; // double null
3705 // strange case adjust
3710 if ((ptr
- *psz
) % 4)
3711 ptr
+= 4 - ((ptr
- *psz
) % 4);
3713 // start reporting .. finally
3714 for (i
= 0; i
< num
; i
++)
3716 flag
= *(DWORD
*) ptr
;
3721 printf ("\n Control::%03d - ID:", i
+ 1);
3724 printf ("%04X, Class:", *(WORD
*) ptr
);
3728 if (*(WORD
*) ptr
== 0xFFFF)
3731 class = *(WORD
*) ptr
;
3745 printf ("LISTBOX ");
3748 printf ("SCROLLBAR");
3751 printf ("COMBOBOX ");
3754 printf ("%04X ", class);
3759 PrintNameOrOrdinal (&ptr
);
3764 PrintNameOrOrdinal (&ptr
);
3769 // strange case adjust
3774 if ((ptr
- *psz
) % 4)
3775 ptr
+= 4 - ((ptr
- *psz
) % 4);
3782 for (i=0; i<(size/16)+1; i++)
3785 for (j=0; j<16; j++)
3792 if (ptr >= pmax) break;
3794 if (n%4 == 0) printf (" ");
3796 n++; if (n%4 == 0) printf (" ");
3800 { n++; if (n%4 == 0) printf (" "); else printf (" "); }
3803 if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3805 if (ptr >= pmax) break;
3818 /* function indicates whether debug info has been stripped from file */
3820 IsDebugInfoStripped (
3823 PIMAGE_FILE_HEADER pfh
;
3825 pfh
= (PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
);
3827 return (pfh
->Characteristics
& IMAGE_FILE_DEBUG_STRIPPED
);
3833 /* retrieve the module name from the debug misc. structure */
3835 RetrieveModuleName (
3840 PIMAGE_DEBUG_DIRECTORY pdd
;
3841 PIMAGE_DEBUG_MISC pdm
= NULL
;
3844 if (!(pdd
= (PIMAGE_DEBUG_DIRECTORY
) ImageDirectoryOffset (lpFile
, IMAGE_DIRECTORY_ENTRY_DEBUG
)))
3847 while (pdd
->SizeOfData
)
3849 if (pdd
->Type
== IMAGE_DEBUG_TYPE_MISC
)
3851 pdm
= (PIMAGE_DEBUG_MISC
) ((DWORD
) pdd
->PointerToRawData
+ (DWORD
) lpFile
);
3852 *pszModule
= (char *) calloc ((nCnt
= (strlen ((char *)pdm
->Data
))) + 1, 1);
3853 // may need some unicode business here...above
3854 bcopy (pdm
->Data
, *pszModule
, nCnt
);
3872 /* determine if this is a valid debug file */
3877 PIMAGE_SEPARATE_DEBUG_HEADER psdh
;
3879 psdh
= (PIMAGE_SEPARATE_DEBUG_HEADER
) lpFile
;
3881 return (psdh
->Signature
== IMAGE_SEPARATE_DEBUG_SIGNATURE
);
3887 /* copy separate debug header structure from debug file */
3889 GetSeparateDebugHeader (
3891 PIMAGE_SEPARATE_DEBUG_HEADER psdh
)
3893 PIMAGE_SEPARATE_DEBUG_HEADER pdh
;
3895 pdh
= (PIMAGE_SEPARATE_DEBUG_HEADER
) lpFile
;
3897 if (pdh
->Signature
== IMAGE_SEPARATE_DEBUG_SIGNATURE
)
3899 bcopy ((LPVOID
) pdh
, (LPVOID
) psdh
, sizeof (IMAGE_SEPARATE_DEBUG_HEADER
));
3907 // I tried to immitate the output of w32dasm disassembler.
3908 // which is a pretty good program.
3909 // but I am disappointed with this program and I myself
3910 // am writting a disassembler.
3911 // This PEdump program is a byproduct of that project.
3912 // so enjoy this program and I hope we will have a little more
3913 // knowledge on windows programming world.
3916 #define MAXSECTIONNUMBER 16
3917 #define MAXNAMESTRNUMBER 40
3927 IMAGE_DOS_HEADER dosHdr
;
3928 PIMAGE_FILE_HEADER pfh
;
3929 PIMAGE_OPTIONAL_HEADER poh
;
3930 PIMAGE_SECTION_HEADER psh
;
3931 //IMAGE_SECTION_HEADER idsh;
3932 IMAGE_SECTION_HEADER shdr
[MAXSECTIONNUMBER
];
3933 //PIMAGE_IMPORT_MODULE_DIRECTORY pid;
3935 int nSections
; // number of sections
3937 int nResources
; // number of resources
3939 int nMenus
; // number of menus
3941 int nDialogs
; // number of dialogs
3943 int nImportedModules
; // number of imported modules
3945 int nFunctions
; // number of functions in the imported module
3947 int nExportedFunctions
; // number of exported funcions
3959 char *piNameBuff
; // import module name buffer
3961 char *pfNameBuff
; // import functions in the module name buffer
3963 char *peNameBuff
; // export function name buffer
3965 char *pmNameBuff
; // menu name buffer
3967 char *pdNameBuff
; // dialog name buffer
3970 * Check user arguments.
3974 my_fp
= fopen (argv
[1], "rb");
3978 "%s: can not open input file \"%s\".\n",
3988 "%s - PE/COFF file dumper\n"
3989 "Copyright (c) 1993 Randy Kath (MSDN Technology Group)\n"
3990 "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)\n"
3991 "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)\n\n",
3995 "usage: %s input_file_name\n",
4001 * Get input file's size.
4004 fseek (my_fp
, 0L, SEEK_END
);
4005 fsize
= ftell (my_fp
);
4008 * Buffer the file in memory.
4010 lpFile
= (void *) calloc (fsize
, 1);
4014 "%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
);
4029 "%s: failed to read the file \"%s\".\n",
4036 GetDosHeader (lpFile
, &dosHdr
);
4038 if ((WORD
) IMAGE_DOS_SIGNATURE
== dosHdr
.e_magic
)
4040 if ((dosHdr
.e_lfanew
> 4096)
4041 || (dosHdr
.e_lfanew
< 64)
4045 "%s: This file is not in PE format; it looks like in DOS format.\n",
4054 "%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4061 fileType
= ImageFileType (lpFile
);
4063 if (fileType
!= IMAGE_NT_SIGNATURE
)
4066 "%s: This file is not in PE format (magic = 0x%08lx).\n",
4073 //=====================================
4074 // now we can really start processing
4075 //=====================================
4077 pfh
= (PIMAGE_FILE_HEADER
) PEFHDROFFSET (lpFile
);
4079 poh
= (PIMAGE_OPTIONAL_HEADER
) OPTHDROFFSET (lpFile
);
4081 psh
= (PIMAGE_SECTION_HEADER
) SECHDROFFSET (lpFile
);
4083 nSections
= pfh
->NumberOfSections
;
4085 imageBase
= poh
->ImageBase
;
4087 entryPoint
= poh
->AddressOfEntryPoint
;
4092 /* store section headers */
4102 * Get Code offset and size,
4103 * Data offset and size.
4110 if (poh
->BaseOfCode
== shdr
[i
].VirtualAddress
)
4113 "Code Offset = %08lX, Code Size = %08lX \n",
4114 shdr
[i
].PointerToRawData
,
4115 shdr
[i
].SizeOfRawData
4118 if (((shdr
[i
].Characteristics
) & 0xC0000040) == 0xC0000040)
4121 "Data Offset = %08lX, Data Size = %08lX \n",
4122 shdr
[i
].PointerToRawData
,
4123 shdr
[i
].SizeOfRawData
4132 "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
4137 * Object name alignment.
4149 if (shdr
[i
].Name
[j
] == 0)
4151 shdr
[i
].Name
[j
] = 32;
4154 shdr
[i
].Name
[7] = 0;
4156 for (i
= 0; i
< nSections
; i
++)
4157 printf ("\n Object%02d: %8s RVA: %08lX Offset: %08lX Size: %08lX Flags: %08lX ",
4158 i
+ 1, shdr
[i
].Name
, shdr
[i
].VirtualAddress
, shdr
[i
].PointerToRawData
,
4159 shdr
[i
].SizeOfRawData
, shdr
[i
].Characteristics
);
4161 * Get List of Resources.
4163 nResources
= GetListOfResourceTypes (lpFile
, &pnstr
);
4166 printf ("\n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++");
4168 if (nResources
== 0)
4169 printf ("\n There are no Resources in This Application.\n");
4172 printf ("\nNumber of Resource Types = %4d (decimal)\n", nResources
);
4173 for (i
= 0; i
< nResources
; i
++)
4175 printf ("\n Resource Type %03d: %s", i
+ 1, pst
);
4176 pst
+= strlen ((char *) (pst
)) + 1;
4178 free ((void *) pnstr
);
4181 printf ("\n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++");
4184 nMenus
= GetContentsOfMenu (lpFile
, &pmNameBuff
);
4188 printf ("\n There are no Menus in This Application.\n");
4193 printf ("\nNumber of Menus = %4d (decimal)", nMenus
);
4195 //dumpMenu(&pst, 8096);
4196 for (i
= 0; i
< nMenus
; i
++)
4199 printf ("\n\n%s", pst
);
4200 pst
+= strlen (pst
) + 1;
4201 printf ("\n-------------");
4202 if (strncmp (pst
, ":::::::::::", 11) == 0)
4205 PrintStrangeMenu (&pst
);
4209 PrintMenu (6, &pst
);
4211 //else PrintStrangeMenu(&pst);
4213 free ((void *) pmNameBuff
);
4218 printf ("\n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++");
4221 nDialogs
= GetContentsOfDialog (lpFile
, &pdNameBuff
);
4225 printf ("\n There are no Dialogs in This Application.\n");
4230 printf ("\nNumber of Dialogs = %4d (decimal)", nDialogs
);
4234 for (i
= 0; i
< nDialogs
; i
++)
4237 printf ("\nName: %s", pst
);
4238 pst
+= strlen (pst
) + 1;
4241 free ((void *) pdNameBuff
);
4246 printf ("\n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++");
4248 nImportedModules
= GetImportModuleNames (lpFile
, &piNameBuff
);
4249 if (nImportedModules
== 0)
4251 printf ("\n There are no imported Functions in This Application.\n");
4256 printf ("\nNumber of Imported Modules = %4d (decimal)\n", nImportedModules
);
4257 for (i
= 0; i
< nImportedModules
; i
++)
4259 printf ("\n Import Module %03d: %s", i
+ 1, pnstr
);
4260 pnstr
+= strlen ((char *) (pnstr
)) + 1;
4264 printf ("\n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++");
4266 for (i
= 0; i
< nImportedModules
; i
++)
4268 printf ("\n\n Import Module %03d: %s \n", i
+ 1, pnstr
);
4269 nFunctions
= GetImportFunctionNamesByModule (lpFile
, pnstr
, &pfNameBuff
);
4270 pnstr
+= strlen ((char *) (pnstr
)) + 1;
4272 for (j
= 0; j
< nFunctions
; j
++)
4274 printf ("\nAddr:%08X hint(%04X) Name: %s",
4275 (*(int *) pst
), (*(short *) (pst
+ 4)),
4277 TranslateFunctionName (pst
+ 6));
4278 pst
+= strlen ((char *) (pst
+ 6)) + 1 + 6;
4280 free ((void *) pfNameBuff
);
4282 free ((void *) piNameBuff
);
4286 printf ("\n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++");
4288 nExportedFunctions
= GetExportFunctionNames (lpFile
, &peNameBuff
);
4289 printf ("\nNumber of Exported Functions = %4d (decimal)\n", nExportedFunctions
);
4291 if (nExportedFunctions
> 0)
4295 for (i
= 0; i
< nExportedFunctions
; i
++)
4297 printf ("\nAddr:%08X Ord:%4d (%04Xh) Name: %s",
4298 (*(int *) pst
), (*(WORD
*) (pst
+ 4)), (*(WORD
*) (pst
+ 4)),
4300 TranslateFunctionName (pst
+ 6));
4301 pst
+= strlen ((char *) (pst
+ 6)) + 6 + 1;
4303 free ((void *) peNameBuff
);
4306 free ((void *) lpFile
);