remove trailing whitespace at end of lines
[reactos.git] / rosapps / sysutils / pedump.c
1 // $Id$
2 //
3 // This program was written by Sang Cho, assistant professor at
4 // the department of
5 // computer science and engineering
6 // chongju university
7 // this program is based on the program pefile.c
8 // which is written by Randy Kath(Microsoft Developmer Network Technology Group)
9 // in june 12, 1993.
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.
13 //
14 //
15 //
16 // language used: djgpp
17 // date of creation: September 28, 1997
18 //
19 // date of first release: October 15, 1997
20 //
21 //
22 // you can contact me: e-mail address: sangcho@alpha94.chongju.ac.kr
23 // hitel id: chokhas
24 // phone number: (0431) 229-8491 +82-431-229-8491
25 //
26 //
27 //
28 // Copyright (C) 1997. by Sang Cho.
29 //
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.
33 //
34 //
35 // File: pedump.c ( I included header file into source file. )
36 //
37 // LICENSE
38 // Sources released under GNU General Public License version 2
39 // or later by Mr. Sang Cho permission.
40 //
41 // REVISIONS
42 // 2000-04-23 (ea) Initial adaptation to GCC/MinGW/ROS.
43 // 2000-08-05 (ea) Initial raw adaptation done.
44 //
45
46 #include <stdio.h>
47 #include <stdarg.h>
48 #include <string.h>
49 #include <setjmp.h>
50 #include <malloc.h>
51 #include <ctype.h>
52
53 #ifndef bcopy
54 #define bcopy(s,d,z) memcpy((d),(s),(z))
55 #endif
56
57 typedef char CHAR;
58 typedef short WCHAR;
59 typedef short SHORT;
60 typedef long LONG;
61 typedef unsigned short USHORT;
62 typedef unsigned long DWORD;
63 typedef int BOOL;
64 typedef unsigned char BYTE;
65 typedef unsigned short WORD;
66 typedef BYTE *PBYTE;
67 typedef WORD *PWORD;
68 typedef DWORD *PDWORD;
69 typedef void *LPVOID;
70 typedef int boolean;
71
72 #define VOID void
73 #define BOOLEAN boolean
74
75 #ifndef NULL
76 #define NULL 0
77 #endif
78
79 #define FALSE 0
80 #define TRUE 1
81 #define CONST const
82 #define LOWORD(l) ((WORD)(l))
83 #define WINAPI __stdcall
84
85 //
86 // Image Format
87 //
88
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
94
95 typedef struct _IMAGE_DOS_HEADER
96 { // DOS .EXE header
97
98 WORD e_magic; // Magic number
99
100 WORD e_cblp; // Bytes on last page of file
101
102 WORD e_cp; // Pages in file
103
104 WORD e_crlc; // Relocations
105
106 WORD e_cparhdr; // Size of header in paragraphs
107
108 WORD e_minalloc; // Minimum extra paragraphs needed
109
110 WORD e_maxalloc; // Maximum extra paragraphs needed
111
112 WORD e_ss; // Initial (relative) SS value
113
114 WORD e_sp; // Initial SP value
115
116 WORD e_csum; // Checksum
117
118 WORD e_ip; // Initial IP value
119
120 WORD e_cs; // Initial (relative) CS value
121
122 WORD e_lfarlc; // File address of relocation table
123
124 WORD e_ovno; // Overlay number
125
126 WORD e_res[4]; // Reserved words
127
128 WORD e_oemid; // OEM identifier (for e_oeminfo)
129
130 WORD e_oeminfo; // OEM information; e_oemid specific
131
132 WORD e_res2[10]; // Reserved words
133
134 LONG e_lfanew; // File address of new exe header
135
136 }
137 IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
138
139 //
140 // File header format.
141 //
142
143
144
145 typedef struct _IMAGE_FILE_HEADER
146 {
147 WORD Machine;
148 WORD NumberOfSections;
149 DWORD TimeDateStamp;
150 DWORD PointerToSymbolTable;
151 DWORD NumberOfSymbols;
152 WORD SizeOfOptionalHeader;
153 WORD Characteristics;
154 }
155 IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
156
157 #define IMAGE_SIZEOF_FILE_HEADER 20
158
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.
172
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
180
181
182
183 //
184 // Directory format.
185 //
186
187 typedef struct _IMAGE_DATA_DIRECTORY
188 {
189 DWORD VirtualAddress;
190 DWORD Size;
191
192 }
193 IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
194
195 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
196
197 //
198 // Optional header format.
199 //
200
201 typedef struct _IMAGE_OPTIONAL_HEADER
202 {
203 //
204 // Standard fields.
205 //
206 WORD Magic;
207 BYTE MajorLinkerVersion;
208 BYTE MinorLinkerVersion;
209 DWORD SizeOfCode;
210 DWORD SizeOfInitializedData;
211 DWORD SizeOfUninitializedData;
212 DWORD AddressOfEntryPoint;
213 DWORD BaseOfCode;
214 DWORD BaseOfData;
215
216 //
217 // NT additional fields.
218 //
219
220 DWORD ImageBase;
221 DWORD SectionAlignment;
222 DWORD FileAlignment;
223 WORD MajorOperatingSystemVersion;
224 WORD MinorOperatingSystemVersion;
225 WORD MajorImageVersion;
226 WORD MinorImageVersion;
227 WORD MajorSubsystemVersion;
228 WORD MinorSubsystemVersion;
229 DWORD Win32VersionValue;
230 DWORD SizeOfImage;
231 DWORD SizeOfHeaders;
232 DWORD CheckSum;
233 WORD Subsystem;
234 WORD DllCharacteristics;
235 DWORD SizeOfStackReserve;
236 DWORD SizeOfStackCommit;
237 DWORD SizeOfHeapReserve;
238 DWORD SizeOfHeapCommit;
239 DWORD LoaderFlags;
240 DWORD NumberOfRvaAndSizes;
241 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
242
243 }
244 IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
245
246
247 typedef struct _IMAGE_NT_HEADERS
248 {
249 DWORD Signature;
250 IMAGE_FILE_HEADER FileHeader;
251 IMAGE_OPTIONAL_HEADER OptionalHeader;
252
253 }
254 IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
255
256
257 // Directory Entries
258
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
272
273 //
274 // Section header format.
275 //
276
277 #define IMAGE_SIZEOF_SHORT_NAME 8
278
279 typedef struct _IMAGE_SECTION_HEADER
280 {
281 BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
282 union
283 {
284 DWORD PhysicalAddress;
285 DWORD VirtualSize;
286 }
287 Misc;
288 DWORD VirtualAddress;
289 DWORD SizeOfRawData;
290 DWORD PointerToRawData;
291 DWORD PointerToRelocations;
292 DWORD PointerToLinenumbers;
293 WORD NumberOfRelocations;
294 WORD NumberOfLinenumbers;
295 DWORD Characteristics;
296
297 }
298 IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
299
300 #define IMAGE_SIZEOF_SECTION_HEADER 40
301
302
303 //
304 // Export Format
305 //
306
307 typedef struct _IMAGE_EXPORT_DIRECTORY
308 {
309 DWORD Characteristics;
310 DWORD TimeDateStamp;
311 WORD MajorVersion;
312 WORD MinorVersion;
313 DWORD Name;
314 DWORD Base;
315 DWORD NumberOfFunctions;
316 DWORD NumberOfNames;
317 PDWORD *AddressOfFunctions;
318 PDWORD *AddressOfNames;
319 PWORD *AddressOfNameOrdinals;
320
321 }
322 IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
323
324 //
325 // Import Format
326 //
327
328 typedef struct _IMAGE_IMPORT_BY_NAME
329 {
330 WORD Hint;
331 BYTE Name[1];
332
333 }
334 IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
335
336 #define IMAGE_ORDINAL_FLAG 0x80000000
337 #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
338
339
340 //
341 // Resource Format.
342 //
343
344 //
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.
352 //
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.
356 //
357
358 // Predefined resource types ... there may be some more, but I don't have
359 // the information yet. .....sang cho.....
360
361 #define RT_NEWRESOURCE 0x2000
362 #define RT_ERROR 0x7fff
363 #define RT_CURSOR 1
364 #define RT_BITMAP 2
365 #define RT_ICON 3
366 #define RT_MENU 4
367 #define RT_DIALOG 5
368 #define RT_STRING 6
369 #define RT_FONTDIR 7
370 #define RT_FONT 8
371 #define RT_ACCELERATORS 9
372 #define RT_RCDATA 10
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)
380
381
382 typedef struct _IMAGE_RESOURCE_DIRECTORY
383 {
384 DWORD Characteristics;
385 DWORD TimeDateStamp;
386 WORD MajorVersion;
387 WORD MinorVersion;
388 WORD NumberOfNamedEntries;
389 WORD NumberOfIdEntries;
390 // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1];
391
392 }
393 IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
394
395 #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
396 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
397
398 //
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.
411 //
412
413 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
414 {
415 DWORD Name;
416 DWORD OffsetToData;
417
418 }
419 IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
420
421 //
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.
428 //
429
430 typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING
431 {
432 WORD Length;
433 CHAR NameString[1];
434
435 }
436 IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;
437
438
439 typedef struct _IMAGE_RESOURCE_DIR_STRING_U
440 {
441 WORD Length;
442 WCHAR NameString[1];
443
444 }
445 IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
446
447
448 //
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.
455 //
456
457 typedef struct _IMAGE_RESOURCE_DATA_ENTRY
458 {
459 DWORD OffsetToData;
460 DWORD Size;
461 DWORD CodePage;
462 DWORD Reserved;
463
464 }
465 IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
466
467
468 // Menu Resources ... added by .....sang cho....
469
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.
474
475 typedef struct _IMAGE_MENU_HEADER
476 {
477 WORD wVersion; // Currently zero
478
479 WORD cbHeaderSize; // Also zero
480
481 }
482 IMAGE_MENU_HEADER, *PIMAGE_MENU_HEADER;
483
484 typedef struct _IMAGE_POPUP_MENU_ITEM
485 {
486 WORD fItemFlags;
487 WCHAR szItemText[1];
488
489 }
490 IMAGE_POPUP_MENU_ITEM, *PIMAGE_POPUP_MENU_ITEM;
491
492 typedef struct _IMAGE_NORMAL_MENU_ITEM
493 {
494 WORD fItemFlags;
495 WORD wMenuID;
496 WCHAR szItemText[1];
497
498 }
499 IMAGE_NORMAL_MENU_ITEM, *PIMAGE_NORMAL_MENU_ITEM;
500
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
510
511
512 // Dialog Box Resources .................. added by sang cho.
513
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
517 // in WINDOWS.H.
518 // The default style for a dialog box is:
519 // WS_POPUP | WS_BORDER | WS_SYSMENU
520 //
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.
525 //
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.
530
531 typedef struct _IMAGE_DIALOG_BOX_HEADER1
532 {
533 DWORD IStyle;
534 DWORD IExtendedStyle; // New for Windows NT
535
536 WORD nControls; // Number of Controls
537
538 WORD x;
539 WORD y;
540 WORD cx;
541 WORD cy;
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
547 }
548 IMAGE_DIALOG_HEADER, *PIMAGE_DIALOG_HEADER;
549
550 typedef union _NAME_OR_ORDINAL
551 { // Name or Ordinal ID
552
553 struct _ORD_ID
554 {
555 WORD flgId;
556 WORD Id;
557 }
558 ORD_ID;
559 WCHAR szName[1];
560 }
561 NAME_OR_ORDINAL, *PNAME_OR_ORDINAL;
562
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:
565
566 typedef struct _IMAGE_CONTROL_DATA
567 {
568 DWORD IStyle;
569 DWORD IExtendedStyle;
570 WORD x;
571 WORD y;
572 WORD cx;
573 WORD cy;
574 WORD wId;
575 // N_OR_O ClassId;
576 // N_OR_O Text;
577 // WORD nExtraStuff;
578 }
579 IMAGE_CONTROL_DATA, *PIMAGE_CONTROL_DATA;
580
581 #define BUTTON 0x80
582 #define EDIT 0x81
583 #define STATIC 0x82
584 #define LISTBOX 0x83
585 #define SCROLLBAR 0x84
586 #define COMBOBOX 0x85
587
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:
592 //
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
613 ///
614
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
635
636 // other aliases
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
644
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
650
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
663
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
677
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
691
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
705
706 //
707 // Debug Format
708 //
709
710 typedef struct _IMAGE_DEBUG_DIRECTORY
711 {
712 DWORD Characteristics;
713 DWORD TimeDateStamp;
714 WORD MajorVersion;
715 WORD MinorVersion;
716 DWORD Type;
717 DWORD SizeOfData;
718 DWORD AddressOfRawData;
719 DWORD PointerToRawData;
720 }
721 IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
722
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
732
733
734 typedef struct _IMAGE_DEBUG_MISC
735 {
736 DWORD DataType; // type of misc data, see defines
737
738 DWORD Length; // total length of record, rounded to four
739 // byte multiple.
740
741 BOOLEAN Unicode; // TRUE if data is unicode string
742
743 BYTE Reserved[3];
744 BYTE Data[1]; // Actual data
745
746 }
747 IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC;
748
749
750 //
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
762 // .DBG file.
763 //
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.
768 //
769
770 typedef struct _IMAGE_SEPARATE_DEBUG_HEADER
771 {
772 WORD Signature;
773 WORD Flags;
774 WORD Machine;
775 WORD Characteristics;
776 DWORD TimeDateStamp;
777 DWORD CheckSum;
778 DWORD ImageBase;
779 DWORD SizeOfImage;
780 DWORD NumberOfSections;
781 DWORD ExportedNamesSize;
782 DWORD DebugDirectorySize;
783 DWORD SectionAlignment;
784 DWORD Reserved[2];
785 }
786 IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER;
787
788 #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
789
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.
793
794
795 //
796 // End Image Format
797 //
798
799
800 #define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
801 #define MAXRESOURCENAME 13
802
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))
807
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))
813
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)))
819
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)))
826
827
828 typedef struct tagImportDirectory
829 {
830 DWORD dwRVAFunctionNameList;
831 DWORD dwUseless1;
832 DWORD dwUseless2;
833 DWORD dwRVAModuleName;
834 DWORD dwRVAFunctionAddressList;
835 }
836 IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;
837
838
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);
844
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);
852
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 *);
857
858 //
859 // structur to store string tokens
860 //
861 typedef struct _Str_P
862 {
863 char flag; // string_flag '@' or '%' or '#'
864
865 char *pos; // starting postion of string
866
867 int length; // length of string
868
869 BOOL wasString; // if it were stringMode or not
870
871 }
872 Str_P;
873
874 /* import section info */
875 int WINAPI GetImportModuleNames (LPVOID, char **);
876 int WINAPI GetImportFunctionNamesByModule (LPVOID, char *, char **);
877
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 LPVOID WINAPI TranslateFunctionName (char *);
884
885 /* export section info */
886 int WINAPI GetExportFunctionNames (LPVOID, char **);
887
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);
898
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);
904
905
906 /**********************************************************************
907 * NAME
908 *
909 * DESCRIPTION
910 * Copy DOS header information to structure.
911 *
912 * ARGUMENTS
913 */
914 BOOL WINAPI
915 GetDosHeader (
916 LPVOID lpFile,
917 PIMAGE_DOS_HEADER pHeader
918 )
919 {
920 /*
921 * DOS header represents first structure
922 * of bytes in PE image file.
923 */
924 if ((WORD) IMAGE_DOS_SIGNATURE == *(WORD *) lpFile)
925 {
926 bcopy (
927 lpFile,
928 (LPVOID) pHeader,
929 sizeof (IMAGE_DOS_HEADER)
930 );
931 return TRUE;
932 }
933 return FALSE;
934 }
935
936
937
938
939 /* return file signature */
940 DWORD WINAPI
941 ImageFileType (
942 LPVOID lpFile)
943 {
944 /* dos file signature comes first */
945 if (*(USHORT *) lpFile == IMAGE_DOS_SIGNATURE)
946 {
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));
951
952 else if (*(DWORD *) NTSIGNATURE (lpFile) == IMAGE_NT_SIGNATURE)
953 return IMAGE_NT_SIGNATURE;
954
955 else
956 return IMAGE_DOS_SIGNATURE;
957 }
958
959 else
960 /* unknown file type */
961 return 0;
962 }
963
964
965
966
967 /* copy file header information to structure */
968 BOOL WINAPI
969 GetPEFileHeader (
970 LPVOID lpFile,
971 PIMAGE_FILE_HEADER pHeader)
972 {
973 /* file header follows dos header */
974 if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE)
975 bcopy (PEFHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_FILE_HEADER));
976 else
977 return FALSE;
978
979 return TRUE;
980 }
981
982
983
984
985
986 /* copy optional header info to structure */
987 BOOL WINAPI
988 GetPEOptionalHeader (
989 LPVOID lpFile,
990 PIMAGE_OPTIONAL_HEADER pHeader)
991 {
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));
995 else
996 return FALSE;
997
998 return TRUE;
999 }
1000
1001
1002
1003
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 */
1006 LPVOID WINAPI
1007 GetModuleEntryPoint (
1008 LPVOID lpFile)
1009 {
1010 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1011
1012 if (poh != NULL)
1013 return (LPVOID) (poh->AddressOfEntryPoint);
1014 else
1015 return NULL;
1016 }
1017
1018
1019
1020
1021 /* return the total number of sections in the module */
1022 int WINAPI
1023 NumOfSections (
1024 LPVOID lpFile)
1025 {
1026 /* number os sections is indicated in file header */
1027 return ((int) ((PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile))->NumberOfSections);
1028 }
1029
1030
1031
1032
1033 /* retrieve entry point */
1034 LPVOID WINAPI
1035 GetImageBase (
1036 LPVOID lpFile)
1037 {
1038 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1039
1040 if (poh != NULL)
1041 return (LPVOID) (poh->ImageBase);
1042 else
1043 return NULL;
1044 }
1045
1046
1047
1048 //
1049 // This function is written by sang cho
1050 // .. october 5, 1997
1051 //
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 */
1054 LPVOID WINAPI
1055 GetActualAddress (
1056 LPVOID lpFile,
1057 DWORD dwRVA)
1058 {
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);
1062 int i = 0;
1063
1064 if (dwRVA == 0)
1065 return NULL;
1066 if (dwRVA & 0x80000000)
1067 {
1068 //return (LPVOID)dwRVA;
1069 printf ("\n$$ what is going on $$");
1070 exit (0);
1071 }
1072
1073 /* locate section containing image directory */
1074 while (i++ < nSections)
1075 {
1076 if (psh->VirtualAddress <= (DWORD) dwRVA &&
1077 psh->VirtualAddress + psh->SizeOfRawData > (DWORD) dwRVA)
1078 break;
1079 psh++;
1080 }
1081
1082 if (i > nSections)
1083 return NULL;
1084
1085 /* return image import directory offset */
1086 return (LPVOID) (((int) lpFile + (int) dwRVA - psh->VirtualAddress) +
1087 (int) psh->PointerToRawData);
1088 }
1089
1090
1091 //
1092 // This function is modified by sang cho
1093 //
1094 //
1095 /* return offset to specified IMAGE_DIRECTORY entry */
1096 LPVOID WINAPI
1097 ImageDirectoryOffset (
1098 LPVOID lpFile,
1099 DWORD dwIMAGE_DIRECTORY)
1100 {
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);
1104 int i = 0;
1105 LPVOID VAImageDir;
1106
1107 /* must be 0 thru (NumberOfRvaAndSizes-1) */
1108 if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
1109 return NULL;
1110
1111 /* locate specific image directory's relative virtual address */
1112 VAImageDir = (LPVOID) poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress;
1113
1114 if (VAImageDir == NULL)
1115 return NULL;
1116 /* locate section containing image directory */
1117 while (i++ < nSections)
1118 {
1119 if (psh->VirtualAddress <= (DWORD) VAImageDir &&
1120 psh->VirtualAddress + psh->SizeOfRawData > (DWORD) VAImageDir)
1121 break;
1122 psh++;
1123 }
1124
1125 if (i > nSections)
1126 return NULL;
1127
1128 /* return image import directory offset */
1129 return (LPVOID) (((int) lpFile + (int) VAImageDir - psh->VirtualAddress) +
1130 (int) psh->PointerToRawData);
1131 }
1132
1133
1134 /* function retrieve names of all the sections in the file */
1135 int WINAPI
1136 GetSectionNames (
1137 LPVOID lpFile,
1138 char **pszSections)
1139 {
1140 int nSections = NumOfSections (lpFile);
1141 int i, nCnt = 0;
1142 PIMAGE_SECTION_HEADER psh;
1143 char *ps;
1144
1145
1146 if (ImageFileType (lpFile) != IMAGE_NT_SIGNATURE ||
1147 (psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) == NULL)
1148 return 0;
1149
1150 /* count the number of chars used in the section names */
1151 for (i = 0; i < nSections; i++)
1152 nCnt += strlen (psh[i].Name) + 1;
1153
1154 /* allocate space for all section names from heap */
1155 ps = *pszSections = (char *) calloc (nCnt, 1);
1156
1157
1158 for (i = 0; i < nSections; i++)
1159 {
1160 strcpy (ps, psh[i].Name);
1161 ps += strlen (psh[i].Name) + 1;
1162 }
1163
1164 return nCnt;
1165 }
1166
1167
1168
1169
1170 /* function gets the function header for a section identified by name */
1171 BOOL WINAPI
1172 GetSectionHdrByName (
1173 LPVOID lpFile,
1174 IMAGE_SECTION_HEADER * sh,
1175 char *szSection)
1176 {
1177 PIMAGE_SECTION_HEADER psh;
1178 int nSections = NumOfSections (lpFile);
1179 int i;
1180
1181
1182 if ((psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) != NULL)
1183 {
1184 /* find the section by name */
1185 for (i = 0; i < nSections; i++)
1186 {
1187 if (!strcmp (psh->Name, szSection))
1188 {
1189 /* copy data to header */
1190 bcopy ((LPVOID) psh, (LPVOID) sh, sizeof (IMAGE_SECTION_HEADER));
1191 return TRUE;
1192 }
1193 else
1194 psh++;
1195 }
1196 }
1197 return FALSE;
1198 }
1199
1200
1201
1202 //
1203 // This function is modified by sang cho
1204 //
1205 //
1206 /* get import modules names separated by null terminators, return module count */
1207 int WINAPI
1208 GetImportModuleNames (
1209 LPVOID lpFile,
1210 char **pszModules)
1211 {
1212 PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)
1213 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1214 //
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..................
1220 //
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?? */
1227 char *psz;
1228
1229 if (pid == NULL)
1230 return 0;
1231
1232 // pData = (BYTE *)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1233
1234 /* extract all import modules */
1235 while (pid->dwRVAModuleName)
1236 {
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;
1241
1242 /* increment to the next import directory entry */
1243 pid++;
1244 nCnt++;
1245 }
1246
1247 /* copy all strings to one chunk of memory */
1248 *pszModules = (char *) calloc (nSize, 1);
1249 psz = *pszModules;
1250 for (i = 0; i < nCnt; i++)
1251 {
1252 strcpy (psz, pModule[i]);
1253 psz += strlen (psz) + 1;
1254 }
1255 return nCnt;
1256 }
1257
1258
1259 //
1260 // This function is rewritten by sang cho
1261 //
1262 //
1263 /* get import module function names separated by null terminators, return function count */
1264 int WINAPI
1265 GetImportFunctionNamesByModule (
1266 LPVOID lpFile,
1267 char *pszModule,
1268 char **pszFunctions)
1269 {
1270 PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)
1271 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1272 //
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..................
1278 //
1279 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1280 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1281 //DWORD dwBase;
1282 int nCnt = 0, nSize = 0;
1283 int nnid = 0;
1284 int mnlength, i;
1285 DWORD dwFunctionName;
1286 DWORD dwFunctionAddress;
1287 char name[128];
1288 char buff[256]; // enough for any string ??
1289
1290 char *psz;
1291 DWORD *pdw;
1292
1293 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1294
1295 /* find module's pid */
1296 while (pid->dwRVAModuleName &&
1297 strcmp (pszModule, (char *) GetActualAddress (lpFile, pid->dwRVAModuleName)))
1298 pid++;
1299
1300 /* exit if the module is not found */
1301 if (!pid->dwRVAModuleName)
1302 return 0;
1303
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++)
1308 if (name[i] == '.')
1309 break;
1310 name[i] = 0;
1311 mnlength = i;
1312
1313 /* count number of function names and length of strings */
1314 dwFunctionName = pid->dwRVAFunctionNameList;
1315
1316 // IMAGE_IMPORT_BY_NAME OR IMAGE_THUNK_DATA
1317 // modified by Sang Cho
1318 while (dwFunctionName &&
1319 *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName)))
1320 {
1321 if ((*pdw) & 0x80000000)
1322 nSize += mnlength + 10 + 1 + 6;
1323 else
1324 nSize += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1 + 6;
1325 dwFunctionName += 4;
1326 nCnt++;
1327 }
1328
1329 /* allocate memory for function names */
1330 *pszFunctions = (char *) calloc (nSize, 1);
1331 psz = *pszFunctions;
1332
1333 //
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..................
1340 //
1341 /* copy function names to mempry pointer */
1342 dwFunctionName = pid->dwRVAFunctionNameList;
1343 dwFunctionAddress = pid->dwRVAFunctionAddressList;
1344 while (dwFunctionName &&
1345 *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName)))
1346 {
1347 if ((*pdw) & 0x80000000)
1348 {
1349 *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress));
1350 psz += 4;
1351 *(short *) psz = *(short *) pdw;
1352 psz += 2;
1353 sprintf (buff, "%s:NoName%04d", name, nnid++);
1354 strcpy (psz, buff);
1355 psz += strlen (buff) + 1;
1356 }
1357 else
1358 {
1359 *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress));
1360 psz += 4;
1361 *(short *) psz = (*(short *) GetActualAddress (lpFile, *pdw));
1362 psz += 2;
1363 strcpy (psz, (char *) GetActualAddress (lpFile, *pdw + 2));
1364 psz += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1;
1365 }
1366 dwFunctionName += 4;
1367 dwFunctionAddress += 4;
1368 }
1369
1370 return nCnt;
1371 }
1372
1373
1374
1375
1376 //
1377 // This function is written by sang cho
1378 // October 6, 1997
1379 //
1380 /* get numerically expressed string length */
1381 int WINAPI
1382 GetStringLength (
1383 char *psz)
1384 {
1385 if (!isdigit (*psz))
1386 return 0;
1387 if (isdigit (*(psz + 1)))
1388 return (*psz - '0') * 10 + *(psz + 1) - '0';
1389 else
1390 return *psz - '0';
1391 }
1392
1393
1394
1395
1396 //
1397 // This function is written by sang cho
1398 // October 12, 1997
1399 //
1400
1401 /* translate parameter part of condensed name */
1402 void WINAPI
1403 GetPreviousParamString (
1404 char *xpin, // read-only source
1405 char *xpout) // translated result
1406 {
1407 int n = 0;
1408 char *pin, *pout;
1409
1410 pin = xpin;
1411 pout = xpout;
1412
1413 pin--;
1414 if (*pin == ',')
1415 pin--;
1416 else
1417 {
1418 printf ("\n **error PreviousParamString1 char = %c", *pin);
1419 exit (0);
1420 }
1421
1422 while (*pin)
1423 {
1424 if (*pin == '>')
1425 n++;
1426 else if (*pin == '<')
1427 n--;
1428 else if (*pin == ')')
1429 n++;
1430
1431 if (n > 0)
1432 {
1433 if (*pin == '(')
1434 n--;
1435 }
1436 else if (strchr (",(", *pin))
1437 break;
1438 pin--;
1439 }
1440
1441 //printf("\n ----- %s", pin);
1442 if (strchr (",(", *pin))
1443 {
1444 pin++;
1445 } // printf("\n %s", pin); }
1446
1447 else
1448 {
1449 printf ("\n **error PreviousParamString2");
1450 exit (0);
1451 }
1452
1453 n = xpin - pin - 1;
1454 strncpy (pout, pin, n);
1455 *(pout + n) = 0;
1456 }
1457
1458
1459
1460
1461 //
1462 // This function is written by sang cho
1463 // October 10, 1997
1464 //
1465
1466 /* translate parameter part of condensed name */
1467 void WINAPI
1468 TranslateParameters (
1469 char **ppin, // read-only source
1470 char **ppout, // translated result
1471 char **pps) // parameter stack
1472 {
1473 int i, n;
1474 char c;
1475 char name[128];
1476 char *pin, *pout, *ps;
1477
1478 //printf(" %c ", **in);
1479 pin = *ppin;
1480 pout = *ppout;
1481 ps = *pps;
1482 c = *pin;
1483 switch (c)
1484 {
1485 // types processing
1486 case 'b':
1487 strcpy (pout, "byte");
1488 pout += 4;
1489 pin++;
1490 break;
1491 case 'c':
1492 strcpy (pout, "char");
1493 pout += 4;
1494 pin++;
1495 break;
1496 case 'd':
1497 strcpy (pout, "double");
1498 pout += 6;
1499 pin++;
1500 break;
1501 case 'f':
1502 strcpy (pout, "float");
1503 pout += 5;
1504 pin++;
1505 break;
1506 case 'g':
1507 strcpy (pout, "long double");
1508 pout += 11;
1509 pin++;
1510 break;
1511 case 'i':
1512 strcpy (pout, "int");
1513 pout += 3;
1514 pin++;
1515 break;
1516 case 'l':
1517 strcpy (pout, "long");
1518 pout += 4;
1519 pin++;
1520 break;
1521 case 's':
1522 strcpy (pout, "short");
1523 pout += 5;
1524 pin++;
1525 break;
1526 case 'v':
1527 strcpy (pout, "void");
1528 pout += 4;
1529 pin++;
1530 break;
1531 // postfix processing
1532 case 'M':
1533 case 'p':
1534 if (*(pin + 1) == 'p')
1535 {
1536 *ps++ = 'p';
1537 pin += 2;
1538 }
1539 else
1540 {
1541 *ps++ = '*';
1542 pin++;
1543 }
1544 *ppin = pin;
1545 *ppout = pout;
1546 *pps = ps;
1547 return;
1548 case 'q':
1549 *pout++ = '(';
1550 pin++;
1551 *ps++ = 'q';
1552 *ppin = pin;
1553 *ppout = pout;
1554 *pps = ps;
1555 return;
1556 case 'r':
1557 if (*(pin + 1) == 'p')
1558 {
1559 *ps++ = 'r';
1560 pin += 2;
1561 }
1562 else
1563 {
1564 *ps++ = '&';
1565 pin++;
1566 }
1567 *ppin = pin;
1568 *ppout = pout;
1569 *pps = ps;
1570 return;
1571 // repeat processing
1572 case 't':
1573 if (isdigit (*(pin + 1)))
1574 {
1575 n = *(pin + 1) - '0';
1576 pin++;
1577 pin++;
1578 GetPreviousParamString (pout, name);
1579 strcpy (pout, name);
1580 pout += strlen (name);
1581 for (i = 1; i < n; i++)
1582 {
1583 *pout++ = ',';
1584 strcpy (pout, name);
1585 pout += strlen (name);
1586 }
1587 }
1588 else
1589 pin++;
1590 break;
1591 // prefix processing
1592 case 'u':
1593 strcpy (pout, "u");
1594 pout += 1;
1595 pin++;
1596 *ppin = pin;
1597 *ppout = pout;
1598 *pps = ps;
1599 return;
1600 case 'x':
1601 strcpy (pout, "const ");
1602 pout += 6;
1603 pin++;
1604 *ppin = pin;
1605 *ppout = pout;
1606 *pps = ps;
1607 return;
1608 case 'z':
1609 strcpy (pout, "static ");
1610 pout += 7;
1611 pin++;
1612 *ppin = pin;
1613 *ppout = pout;
1614 *pps = ps;
1615 return;
1616 default:
1617 strcpy (pout, "!1!");
1618 pout += 3;
1619 *pout++ = *pin++;
1620 *ppin = pin;
1621 *ppout = pout;
1622 *pps = ps;
1623 return;
1624 }
1625 // need to process postfix finally
1626 c = *(ps - 1);
1627 if (strchr ("tqx", c))
1628 {
1629 if (*(pin) && !strchr ("@$%", *(pin)))
1630 *pout++ = ',';
1631 *ppin = pin;
1632 *ppout = pout;
1633 *pps = ps;
1634 return;
1635 }
1636 switch (c)
1637 {
1638 case 'r':
1639 strcpy (pout, "*&");
1640 pout += 2;
1641 ps--;
1642 break;
1643 case 'p':
1644 strcpy (pout, "**");
1645 pout += 2;
1646 ps--;
1647 break;
1648 case '&':
1649 strcpy (pout, "&");
1650 pout += 1;
1651 ps--;
1652 break;
1653 case '*':
1654 strcpy (pout, "*");
1655 pout += 1;
1656 ps--;
1657 break;
1658 default:
1659 strcpy (pout, "!2!");
1660 pout += 3;
1661 ps--;
1662 break;
1663 }
1664 if (*(pin) && !strchr ("@$%", *(pin)))
1665 *pout++ = ',';
1666 *ppin = pin;
1667 *ppout = pout;
1668 *pps = ps;
1669 }
1670
1671
1672 //
1673 // This function is written by sang cho
1674 // October 11, 1997
1675 //
1676
1677 /* translate parameter part of condensed name */
1678 BOOL WINAPI
1679 StringExpands (
1680 char **ppin, // read-only source
1681 char **ppout, // translated result
1682 char **pps, // parameter stack
1683 Str_P * pcstr) // currently stored string
1684 {
1685 // int n;
1686 // char c;
1687 char *pin, *pout, *ps;
1688 Str_P c_str;
1689 BOOL stringMode = TRUE;
1690
1691 pin = *ppin;
1692 pout = *ppout;
1693 ps = *pps;
1694 c_str = *pcstr;
1695
1696 if (strncmp (pin, "bctr", 4) == 0)
1697 {
1698 strncpy (pout, c_str.pos, c_str.length);
1699 pout += c_str.length;
1700 pin += 4;
1701 }
1702 else if (strncmp (pin, "bdtr", 4) == 0)
1703 {
1704 *pout++ = '~';
1705 strncpy (pout, c_str.pos, c_str.length);
1706 pout += c_str.length;
1707 pin += 4;
1708 }
1709 else if (*pin == 'o')
1710 {
1711 strcpy (pout, "const ");
1712 pout += 6;
1713 pin++;
1714 stringMode = FALSE;
1715 }
1716 else if (*pin == 'q')
1717 {
1718 *pout++ = '(';
1719 pin++;
1720 *ps++ = 'q';
1721 stringMode = FALSE;
1722 }
1723 else if (*pin == 't')
1724 {
1725 //if (*(ps-1) == 't') { *pout++ = ','; pin++; } // this also got me...
1726 //else october 12 .. sang
1727 {
1728 *pout++ = '<';
1729 pin++;
1730 *ps++ = 't';
1731 }
1732 stringMode = FALSE;
1733 }
1734 else if (strncmp (pin, "xq", 2) == 0)
1735 {
1736 *pout++ = '(';
1737 pin += 2;
1738 *ps++ = 'x';
1739 *ps++ = 'q';
1740 stringMode = FALSE;
1741 }
1742 else if (strncmp (pin, "bcall", 5) == 0)
1743 {
1744 strcpy (pout, "operator ()");
1745 pout += 11;
1746 pin += 5;
1747 }
1748 else if (strncmp (pin, "bsubs", 5) == 0)
1749 {
1750 strcpy (pout, "operator []");
1751 pout += 11;
1752 pin += 5;
1753 }
1754 else if (strncmp (pin, "bnwa", 4) == 0)
1755 {
1756 strcpy (pout, "operator new[]");
1757 pout += 14;
1758 pin += 4;
1759 }
1760 else if (strncmp (pin, "bdla", 4) == 0)
1761 {
1762 strcpy (pout, "operator delete[]");
1763 pout += 17;
1764 pin += 4;
1765 }
1766 else if (strncmp (pin, "bnew", 4) == 0)
1767 {
1768 strcpy (pout, "operator new");
1769 pout += 12;
1770 pin += 4;
1771 }
1772 else if (strncmp (pin, "bdele", 5) == 0)
1773 {
1774 strcpy (pout, "operator delete");
1775 pout += 15;
1776 pin += 5;
1777 }
1778 else if (strncmp (pin, "blsh", 4) == 0)
1779 {
1780 strcpy (pout, "operator <<");
1781 pout += 11;
1782 pin += 4;
1783 }
1784 else if (strncmp (pin, "brsh", 4) == 0)
1785 {
1786 strcpy (pout, "operator >>");
1787 pout += 11;
1788 pin += 4;
1789 }
1790 else if (strncmp (pin, "binc", 4) == 0)
1791 {
1792 strcpy (pout, "operator ++");
1793 pout += 11;
1794 pin += 4;
1795 }
1796 else if (strncmp (pin, "bdec", 4) == 0)
1797 {
1798 strcpy (pout, "operator --");
1799 pout += 11;
1800 pin += 4;
1801 }
1802 else if (strncmp (pin, "badd", 4) == 0)
1803 {
1804 strcpy (pout, "operator +");
1805 pout += 10;
1806 pin += 4;
1807 }
1808 else if (strncmp (pin, "brplu", 5) == 0)
1809 {
1810 strcpy (pout, "operator +=");
1811 pout += 11;
1812 pin += 5;
1813 }
1814 else if (strncmp (pin, "bdiv", 4) == 0)
1815 {
1816 strcpy (pout, "operator /");
1817 pout += 10;
1818 pin += 4;
1819 }
1820 else if (strncmp (pin, "brdiv", 5) == 0)
1821 {
1822 strcpy (pout, "operator /=");
1823 pout += 11;
1824 pin += 5;
1825 }
1826 else if (strncmp (pin, "bmul", 4) == 0)
1827 {
1828 strcpy (pout, "operator *");
1829 pout += 10;
1830 pin += 4;
1831 }
1832 else if (strncmp (pin, "brmul", 5) == 0)
1833 {
1834 strcpy (pout, "operator *=");
1835 pout += 11;
1836 pin += 5;
1837 }
1838 else if (strncmp (pin, "basg", 4) == 0)
1839 {
1840 strcpy (pout, "operator =");
1841 pout += 10;
1842 pin += 4;
1843 }
1844 else if (strncmp (pin, "beql", 4) == 0)
1845 {
1846 strcpy (pout, "operator ==");
1847 pout += 11;
1848 pin += 4;
1849 }
1850 else if (strncmp (pin, "bneq", 4) == 0)
1851 {
1852 strcpy (pout, "operator !=");
1853 pout += 11;
1854 pin += 4;
1855 }
1856 else if (strncmp (pin, "bor", 3) == 0)
1857 {
1858 strcpy (pout, "operator |");
1859 pout += 10;
1860 pin += 3;
1861 }
1862 else if (strncmp (pin, "bror", 4) == 0)
1863 {
1864 strcpy (pout, "operator |=");
1865 pout += 11;
1866 pin += 4;
1867 }
1868 else if (strncmp (pin, "bcmp", 4) == 0)
1869 {
1870 strcpy (pout, "operator ~");
1871 pout += 10;
1872 pin += 4;
1873 }
1874 else if (strncmp (pin, "bnot", 4) == 0)
1875 {
1876 strcpy (pout, "operator !");
1877 pout += 10;
1878 pin += 4;
1879 }
1880 else if (strncmp (pin, "band", 4) == 0)
1881 {
1882 strcpy (pout, "operator &");
1883 pout += 10;
1884 pin += 4;
1885 }
1886 else if (strncmp (pin, "brand", 5) == 0)
1887 {
1888 strcpy (pout, "operator &=");
1889 pout += 11;
1890 pin += 5;
1891 }
1892 else if (strncmp (pin, "bxor", 4) == 0)
1893 {
1894 strcpy (pout, "operator ^");
1895 pout += 10;
1896 pin += 4;
1897 }
1898 else if (strncmp (pin, "brxor", 5) == 0)
1899 {
1900 strcpy (pout, "operator ^=");
1901 pout += 11;
1902 pin += 5;
1903 }
1904 else
1905 {
1906 strcpy (pout, "!$$$!");
1907 pout += 5;
1908 }
1909 *ppin = pin;
1910 *ppout = pout;
1911 *pps = ps;
1912 return stringMode;
1913 } // end of '$' processing
1914
1915
1916
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
1925 //} Str_P;
1926 //----------------------------------------------------------------------
1927 //
1928 // I think I knocked it down finally. But who knows?
1929 // october 12, 1997 ... sang
1930 //
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
1946 //
1947 //
1948 // This function is written by sang cho
1949 // October 5, 1997
1950 //
1951 /* translate condesed import function name */
1952 LPVOID WINAPI
1953 TranslateFunctionName (
1954 char *psz)
1955 {
1956
1957
1958 int i, /*j,*/ n;
1959 char c, cc;
1960
1961 static char buff[512]; // result of translation
1962
1963 int is = 0;
1964 char pStack[32]; // parameter processing stack
1965
1966 Str_P sStack[32]; // String processing stack
1967
1968 Str_P tok; // String token
1969
1970 Str_P c_str; // current string
1971
1972 int iend = 0;
1973 char *endTab[8]; // end of string position check
1974
1975 char *ps;
1976 char *pin, *pout;
1977 BOOL stringMode = TRUE;
1978
1979 if (*psz != '@')
1980 return psz;
1981 pin = psz;
1982 pout = buff;
1983 ps = pStack;
1984
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...
1992
1993 //pa = pb = pout;
1994 pin++;
1995 tok.flag = 'A';
1996 tok.pos = pout;
1997 tok.length = 0;
1998 tok.wasString = stringMode;
1999 sStack[is++] = tok; // initialize sStack with dummy marker
2000
2001 while (*pin)
2002 {
2003 while (*pin)
2004 {
2005 c = *pin;
2006
2007 //---------------------------------------------
2008 // check for the end of number specified string
2009 //---------------------------------------------
2010
2011 if (iend > 0)
2012 {
2013 for (i = 0; i < iend; i++)
2014 if (pin == endTab[i])
2015 break;
2016 if (i < iend)
2017 {
2018 // move the end of endTab to ith position
2019 endTab[i] = endTab[iend - 1];
2020 iend--;
2021
2022 // get top of the string stack
2023 tok = sStack[is - 1];
2024
2025 // I am expecting '#' token from stack
2026 if (tok.flag != '#')
2027
2028 {
2029 printf ("\n**some serious error1** %c is = %d char = %c",
2030 tok.flag, is, *pin);
2031 exit (0);
2032 }
2033
2034 // pop '#' token I am happy now.
2035 else
2036 { //if (c)
2037 //printf("\n pop # token ... current char = %c", c);
2038 //else printf("\n pop percent token..next char = NULL");
2039
2040 is--;
2041 }
2042
2043 stringMode = tok.wasString;
2044
2045 if (!stringMode)
2046 {
2047 // need to process postfix finally
2048 cc = *(ps - 1);
2049 if (strchr ("qtx", cc))
2050 {
2051 if (!strchr ("@$%", c))
2052 *pout++ = ',';
2053 }
2054 else
2055 {
2056 switch (cc)
2057 {
2058 case 'r':
2059 strcpy (pout, "*&");
2060 pout += 2;
2061 ps--;
2062 break;
2063 case 'p':
2064 strcpy (pout, "**");
2065 pout += 2;
2066 ps--;
2067 break;
2068 case '&':
2069 strcpy (pout, "&");
2070 pout += 1;
2071 ps--;
2072 break;
2073 case '*':
2074 strcpy (pout, "*");
2075 pout += 1;
2076 ps--;
2077 break;
2078 default:
2079 strcpy (pout, "!3!");
2080 pout += 3;
2081 ps--;
2082 break;
2083 }
2084 if (!strchr ("@$%", c))
2085 *pout++ = ',';
2086 }
2087 }
2088 // string mode restored...
2089 else;
2090 }
2091 else; // do nothing..
2092
2093 }
2094
2095 //------------------------------------------------
2096 // special control symbol processing:
2097 //------------------------------------------------
2098
2099 if (strchr ("@$%", c))
2100 break;
2101
2102 //---------------------------------------------------------------
2103 // string part processing : no '$' met yet
2104 // or inside of '%' block
2105 // or inside of '#' block (numbered string)
2106 //---------------------------------------------------------------
2107
2108 else if (stringMode)
2109 *pout++ = *pin++;
2110 //else if (is > 1) *pout++ = *pin++;
2111
2112 //------------------------------------------------
2113 // parameter part processing: '$' met
2114 //------------------------------------------------
2115
2116 else // parameter processing
2117
2118 {
2119 if (!isdigit (c))
2120 TranslateParameters (&pin, &pout, &ps);
2121 else // number specified string processing
2122
2123 {
2124 n = GetStringLength (pin);
2125 if (n < 10)
2126 pin++;
2127 else
2128 pin += 2;
2129
2130 // push '#' token
2131 //if (*pin)
2132 //printf("\n push # token .. char = %c", *pin);
2133 //else printf("\n push percent token..next char = NULL");
2134 tok.flag = '#';
2135 tok.pos = pout;
2136 tok.length = 0;
2137 tok.wasString = stringMode;
2138 sStack[is++] = tok;
2139
2140 // mark end of input string
2141 endTab[iend++] = pin + n;
2142 stringMode = TRUE;
2143 }
2144 }
2145 } // end of inner while loop
2146 //
2147 // beginning of new string or end of string ( quotation mark )
2148 //
2149
2150 if (c == '%')
2151 {
2152 pin++; // anyway we have to proceed...
2153
2154 tok = sStack[is - 1]; // get top of the sStack
2155
2156 if (tok.flag == '%')
2157 {
2158 // pop '%' token and set c_str
2159 //if (*pin)
2160 //printf("\n pop percent token..next char = %c", *pin);
2161 //else printf("\n pop percent token..next char = NULL");
2162 is--;
2163 c_str = tok;
2164 c_str.length = pout - c_str.pos;
2165 if (*(ps - 1) == 't')
2166 {
2167 *pout++ = '>';
2168 ps--;
2169 stringMode = tok.wasString;
2170 }
2171 else
2172 {
2173 printf ("\n**some string error3** stack = %c", *(ps - 1));
2174 exit (0);
2175 }
2176 }
2177 else if (tok.flag == 'A' || tok.flag == '#')
2178 {
2179 // push '%' token
2180 //if (*pin)
2181 //printf("\n push percent token..next char = %c", *pin);
2182 //else printf("\n push percent token..next char = NULL");
2183 tok.flag = '%';
2184 tok.pos = pout;
2185 tok.length = 0;
2186 tok.wasString = stringMode;
2187 sStack[is++] = tok;
2188 }
2189 else
2190 {
2191 printf ("\n**some string error5**");
2192 exit (0);
2193 }
2194 }
2195 //
2196 // sometimes we need string to use as constructor name or destructor name
2197 //
2198 else if (c == '@') // get string from previous marker upto here.
2199
2200 {
2201 pin++;
2202 tok = sStack[is - 1];
2203 c_str.flag = 'S';
2204 c_str.pos = tok.pos;
2205 c_str.length = pout - tok.pos;
2206 c_str.wasString = stringMode;
2207 *pout++ = ':';
2208 *pout++ = ':';
2209 }
2210 //
2211 // we need to take care of parameter control sequence
2212 //
2213 else if (c == '$') // need to precess template or parameter part
2214
2215 {
2216 pin++;
2217 if (stringMode)
2218 stringMode = StringExpands (&pin, &pout, &ps, &c_str);
2219 else
2220 { // template parameter mode I guess "$t"
2221
2222 if (is > 1)
2223 {
2224 if (*pin == 't')
2225 pin++;
2226 else
2227 {
2228 printf ("\nMYGOODNESS1 %c", *pin);
2229 exit (0);
2230 }
2231 //ps--;
2232 //if (*ps == 't') *pout++ = '>';
2233 //else { printf("\nMYGOODNESS2"); exit(0);}
2234 *pout++ = ','; //pin++; ..this almost blowed me....
2235
2236 }
2237 // real parameter mode I guess
2238 // unexpected case is found ... humm what can I do...
2239 else
2240 {
2241 // this is newly found twist.. it really hurts.
2242 if (ps <= pStack)
2243 {
2244 if (*pin == 'q')
2245 {
2246 *ps++ = 'q';
2247 *pout++ = '(';
2248 pin++;
2249 }
2250 else
2251 {
2252 printf ("\n** I GIVEUP ***");
2253 exit (0);
2254 }
2255 continue;
2256 }
2257 ps--;
2258 while (*ps != 'q')
2259 {
2260 if (*ps == '*')
2261 *pout++ = '*';
2262 else if (*ps == '&')
2263 *pout++ = '&';
2264 else if (*ps == 'p')
2265 {
2266 *pout++ = '*';
2267 *pout++ = '*';
2268 }
2269 else if (*ps == 'r')
2270 {
2271 *pout++ = '*';
2272 *pout++ = '&';
2273 }
2274 else
2275 {
2276 printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin);
2277 exit (0);
2278 }
2279 ps--;
2280 }
2281 *pout++ = ')';
2282 ps--;
2283 while (*ps != 'q')
2284 {
2285 if (*ps == '*')
2286 *pout++ = '*';
2287 else if (*ps == '&')
2288 *pout++ = '&';
2289 else if (*ps == 'p')
2290 {
2291 *pout++ = '*';
2292 *pout++ = '*';
2293 }
2294 else if (*ps == 'r')
2295 {
2296 *pout++ = '*';
2297 *pout++ = '&';
2298 }
2299 else
2300 {
2301 printf ("\n*** SOMETHING IS WRONG2***");
2302 exit (0);
2303 }
2304 ps--;
2305 }
2306 ps++;
2307 *pout++ = ',';
2308 }
2309 }
2310 } // end of '$' processing
2311
2312 } // end of outer while loop
2313 //
2314 // need to process remaining parameter stack
2315 //
2316
2317 while (ps > pStack)
2318 {
2319 ps--;
2320 switch (*ps)
2321 {
2322 case 't':
2323 *pout++ = '>';
2324 break;
2325 case 'q':
2326 *pout++ = ')';
2327 break;
2328 case 'x':
2329 strcpy (pout, " const");
2330 pout += 6;
2331 break;
2332 case 'r':
2333 strcpy (pout, "*&");
2334 pout += 2;
2335 break;
2336 case 'p':
2337 strcpy (pout, "**");
2338 pout += 2;
2339 break;
2340 case '&':
2341 *pout++ = '&';
2342 break;
2343 case '*':
2344 *pout++ = '*';
2345 break;
2346 default:
2347 strcpy (pout, "!4!");
2348 pout += 3;
2349 *pout++ = *ps;
2350 }
2351 }
2352 *pout = 0;
2353 return buff;
2354 }
2355
2356
2357
2358 //
2359 // This function is written by sang cho
2360 //
2361 //
2362 /* get exported function names separated by null terminators, return count of functions */
2363 int WINAPI
2364 GetExportFunctionNames (
2365 LPVOID lpFile,
2366 char **pszFunctions)
2367 {
2368 //PIMAGE_SECTION_HEADER psh;
2369 PIMAGE_EXPORT_DIRECTORY ped;
2370 //DWORD dwBase;
2371 DWORD imageBase; //===========================
2372
2373 char *pfns[8192] =
2374 {NULL,}; // maximum number of functions
2375 //=============================
2376
2377 char buff[256]; // enough for any string ??
2378
2379 char *psz = NULL; //===============================
2380
2381 DWORD *pdwAddress;
2382 DWORD *pdw1;
2383 DWORD *pdwNames;
2384 WORD *pwOrd;
2385 int i, nCnt = 0, ntmp = 0;
2386 int enid = 0, ordBase = 1; // usally ordBase is 1....
2387
2388 int enames = 0;
2389
2390 /* get section header and pointer to data directory for .edata section */
2391 ped = (PIMAGE_EXPORT_DIRECTORY)
2392 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2393
2394 if (ped == NULL)
2395 return 0;
2396
2397 //
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..................
2403 //
2404 //psh = (PIMAGE_SECTION_HEADER)
2405 //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2406
2407 //if (psh == NULL) return 0;
2408
2409 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2410
2411
2412 /* determine the offset of the export function names */
2413
2414 pdwAddress = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfFunctions);
2415
2416 imageBase = (DWORD) GetImageBase (lpFile);
2417
2418 ordBase = ped->Base;
2419
2420 if (ped->NumberOfNames > 0)
2421 {
2422 pdwNames = (DWORD *)
2423 GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2424 pwOrd = (WORD *)
2425 GetActualAddress (lpFile, (DWORD) ped->AddressOfNameOrdinals);
2426 pdw1 = pdwAddress;
2427
2428 /* figure out how much memory to allocate for all strings */
2429 for (i = 0; i < (int) ped->NumberOfNames; i++)
2430 {
2431 nCnt += strlen ((char *)
2432 GetActualAddress (lpFile, *(DWORD *) pdwNames)) + 1 + 6;
2433 pdwNames++;
2434 }
2435 // get the number of unnamed functions
2436 for (i = 0; i < (int) ped->NumberOfFunctions; i++)
2437 if (*pdw1++)
2438 ntmp++;
2439 // add memory required to show unnamed functions.
2440 if (ntmp > (int) ped->NumberOfNames)
2441 nCnt += 18 * (ntmp - (int) ped->NumberOfNames);
2442
2443 /* allocate memory for function names */
2444
2445 *pszFunctions = (char *) calloc (nCnt, 1);
2446 pdwNames = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2447
2448 /* copy string pointer to buffer */
2449
2450 for (i = 0; i < (int) ped->NumberOfNames; i++)
2451 {
2452 pfns[(int) (*pwOrd) + ordBase] =
2453 (char *) GetActualAddress (lpFile, *(DWORD *) pdwNames);
2454 pdwNames++;
2455 pwOrd++;
2456 }
2457
2458 psz = *pszFunctions;
2459 }
2460
2461 for (i = ordBase; i < (int) ped->NumberOfFunctions + ordBase; i++)
2462 {
2463 if (*pdwAddress > 0)
2464 {
2465 *(DWORD *) psz = imageBase + *pdwAddress;
2466 psz += 4;
2467 *(WORD *) psz = (WORD) (i);
2468 psz += 2;
2469 if (pfns[i])
2470 {
2471 strcpy (psz, pfns[i]);
2472 psz += strlen (psz) + 1;
2473 }
2474 else
2475 {
2476 sprintf (buff, "ExpFn%04d()", enid++);
2477 strcpy (psz, buff);
2478 psz += 12;
2479 }
2480 enames++;
2481 }
2482 pdwAddress++;
2483 }
2484
2485 return enames;
2486
2487 }
2488
2489
2490 /* determine the total number of resources in the section */
2491 int WINAPI
2492 GetNumberOfResources (
2493 LPVOID lpFile)
2494 {
2495 PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType;
2496 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2497 int nCnt = 0, i;
2498
2499
2500 /* get root directory of resource tree */
2501 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2502 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2503 return 0;
2504
2505 /* set pointer to first resource type entry */
2506 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2507
2508 /* loop through all resource directory entry types */
2509 for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2510 {
2511 /* locate directory or each resource type */
2512 prdType = (PIMAGE_RESOURCE_DIRECTORY) ((int) prdRoot + (int) prde->OffsetToData);
2513
2514 /* mask off most significant bit of the data offset */
2515 prdType = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType ^ 0x80000000);
2516
2517 /* increment count of name'd and ID'd resources in directory */
2518 nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
2519
2520 /* increment to next entry */
2521 prde++;
2522 }
2523
2524 return nCnt;
2525 }
2526
2527
2528
2529 //
2530 // This function is rewritten by sang cho
2531 //
2532 //
2533 /* name each type of resource in the section */
2534 int WINAPI
2535 GetListOfResourceTypes (
2536 LPVOID lpFile,
2537 char **pszResTypes)
2538 {
2539 PIMAGE_RESOURCE_DIRECTORY prdRoot;
2540 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2541 char *pMem;
2542 char buff[32];
2543 int nCnt, i;
2544 DWORD prdeName;
2545
2546
2547 /* get root directory of resource tree */
2548 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2549 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2550 return 0;
2551
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)
2556 return 0;
2557
2558 /* set pointer to first resource type entry */
2559 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2560
2561 /* loop through all resource directory entry types */
2562 for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2563 {
2564 prdeName = prde->Name;
2565
2566 //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2567 // pMem += strlen (pMem) + 1;
2568 //
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.
2573 //
2574 if (prdeName == 1)
2575 {
2576 strcpy (pMem, "RT_CURSOR");
2577 pMem += 10;
2578 }
2579 else if (prdeName == 2)
2580 {
2581 strcpy (pMem, "RT_BITMAP");
2582 pMem += 10;
2583 }
2584 else if (prdeName == 3)
2585 {
2586 strcpy (pMem, "RT_ICON ");
2587 pMem += 10;
2588 }
2589 else if (prdeName == 4)
2590 {
2591 strcpy (pMem, "RT_MENU ");
2592 pMem += 10;
2593 }
2594 else if (prdeName == 5)
2595 {
2596 strcpy (pMem, "RT_DIALOG");
2597 pMem += 10;
2598 }
2599 else if (prdeName == 6)
2600 {
2601 strcpy (pMem, "RT_STRING");
2602 pMem += 10;
2603 }
2604 else if (prdeName == 7)
2605 {
2606 strcpy (pMem, "RT_FONTDIR");
2607 pMem += 11;
2608 }
2609 else if (prdeName == 8)
2610 {
2611 strcpy (pMem, "RT_FONT ");
2612 pMem += 10;
2613 }
2614 else if (prdeName == 9)
2615 {
2616 strcpy (pMem, "RT_ACCELERATORS");
2617 pMem += 16;
2618 }
2619 else if (prdeName == 10)
2620 {
2621 strcpy (pMem, "RT_RCDATA");
2622 pMem += 10;
2623 }
2624 else if (prdeName == 11)
2625 {
2626 strcpy (pMem, "RT_MESSAGETABLE");
2627 pMem += 16;
2628 }
2629 else if (prdeName == 12)
2630 {
2631 strcpy (pMem, "RT_GROUP_CURSOR");
2632 pMem += 16;
2633 }
2634 else if (prdeName == 14)
2635 {
2636 strcpy (pMem, "RT_GROUP_ICON ");
2637 pMem += 16;
2638 }
2639 else if (prdeName == 16)
2640 {
2641 strcpy (pMem, "RT_VERSION");
2642 pMem += 11;
2643 }
2644 else if (prdeName == 17)
2645 {
2646 strcpy (pMem, "RT_DLGINCLUDE ");
2647 pMem += 16;
2648 }
2649 else if (prdeName == 19)
2650 {
2651 strcpy (pMem, "RT_PLUGPLAY ");
2652 pMem += 16;
2653 }
2654 else if (prdeName == 20)
2655 {
2656 strcpy (pMem, "RT_VXD ");
2657 pMem += 10;
2658 }
2659 else if (prdeName == 21)
2660 {
2661 strcpy (pMem, "RT_ANICURSOR ");
2662 pMem += 16;
2663 }
2664 else if (prdeName == 22)
2665 {
2666 strcpy (pMem, "RT_ANIICON");
2667 pMem += 11;
2668 }
2669 else if (prdeName == 0x2002)
2670 {
2671 strcpy (pMem, "RT_NEWBITMAP");
2672 pMem += 13;
2673 }
2674 else if (prdeName == 0x2004)
2675 {
2676 strcpy (pMem, "RT_NEWMENU");
2677 pMem += 11;
2678 }
2679 else if (prdeName == 0x2005)
2680 {
2681 strcpy (pMem, "RT_NEWDIALOG");
2682 pMem += 13;
2683 }
2684 else if (prdeName == 0x7fff)
2685 {
2686 strcpy (pMem, "RT_ERROR ");
2687 pMem += 10;
2688 }
2689 else
2690 {
2691 sprintf (buff, "RT_UNKNOWN:%08X", prdeName);
2692 strcpy (pMem, buff);
2693 pMem += 20;
2694 }
2695 prde++;
2696 }
2697
2698 return prdRoot->NumberOfIdEntries;
2699 }
2700
2701
2702
2703 //
2704 // This function is written by sang cho
2705 // October 12, 1997
2706 //
2707 /* copy menu information */
2708 void WINAPI
2709 StrangeMenuFill (
2710 char **psz, // results
2711 WORD ** pMenu, // read-only
2712 int size)
2713 {
2714 WORD *pwd;
2715 WORD *ptr, *pmax;
2716
2717 pwd = *pMenu;
2718 pmax = (WORD *) ((DWORD) pwd + size);
2719 ptr = (WORD *) (*psz);
2720
2721 while (pwd < pmax)
2722 {
2723 *ptr++ = *pwd++;
2724 }
2725 *psz = (char *) ptr;
2726 *pMenu = pwd;
2727 }
2728
2729
2730
2731 //
2732 // This function is written by sang cho
2733 // October 1, 1997
2734 //
2735 /* obtain menu information */
2736 int WINAPI
2737 MenuScan (
2738 int *len,
2739 WORD ** pMenu)
2740 {
2741 //int num = 0;
2742 //int ndetails;
2743 WORD *pwd;
2744 WORD flag, flag1;
2745 WORD id, ispopup;
2746
2747
2748 pwd = *pMenu;
2749
2750 flag = *pwd; // so difficult to correctly code this so let's try this
2751
2752 pwd++;
2753 (*len) += 2; // flag store
2754
2755 if ((flag & 0x0010) == 0)
2756 {
2757 ispopup = flag;
2758 id = *pwd;
2759 pwd++;
2760 (*len) += 2; // id store
2761
2762 }
2763 else
2764 {
2765 ispopup = flag;
2766 }
2767
2768 while (*pwd)
2769 {
2770 (*len)++;
2771 pwd++;
2772 }
2773 (*len)++; // name and null character
2774
2775 pwd++; // skip double null
2776
2777 if ((flag & 0x0010) == 0) // normal node: done
2778
2779 {
2780 *pMenu = pwd;
2781 return (int) flag;
2782 }
2783 // popup node: need to go on...
2784 while (1)
2785 {
2786 *pMenu = pwd;
2787 flag1 = (WORD) MenuScan (len, pMenu);
2788 pwd = *pMenu;
2789 if (flag1 & 0x0080)
2790 break;
2791 }
2792 // fill # of details to num above
2793 //(*len) += 2;
2794 *pMenu = pwd;
2795 return flag;
2796 }
2797
2798
2799 //
2800 // This function is written by sang cho
2801 // October 2, 1997
2802 //
2803 /* copy menu information */
2804 int WINAPI
2805 MenuFill (
2806 char **psz,
2807 WORD ** pMenu)
2808 {
2809 //int num = 0;
2810 //int ndetails;
2811 char *ptr/*, *pTemp*/;
2812 WORD *pwd;
2813 WORD flag, flag1;
2814 WORD id/*, ispopup*/;
2815
2816 ptr = *psz;
2817 pwd = *pMenu;
2818 //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2819 flag = *pwd; // so difficult to correctly code this so let's try this
2820
2821 pwd++;
2822 if ((flag & 0x0010) == 0)
2823 {
2824 *(WORD *) ptr = flag; // flag store
2825
2826 ptr += 2;
2827 *(WORD *) ptr = id = *pwd; // id store
2828
2829 ptr += 2;
2830 pwd++;
2831 }
2832 else
2833 {
2834 *(WORD *) ptr = flag; // flag store
2835
2836 ptr += 2;
2837 }
2838
2839 while (*pwd) // name extract
2840
2841 {
2842 *ptr = *(char *) pwd;
2843 ptr++;
2844 pwd++;
2845 } //name and null character
2846
2847 *ptr = 0;
2848 ptr++;
2849 pwd++; // skip double null
2850
2851 if ((flag & 0x0010) == 0) // normal node: done
2852
2853 {
2854 *pMenu = pwd;
2855 *psz = ptr;
2856 return (int) flag;
2857 }
2858 //pTemp = ptr;
2859 //ptr += 2;
2860 // popup node: need to go on...
2861 while (1)
2862 {
2863 //num++;
2864 *pMenu = pwd;
2865 *psz = ptr;
2866 flag1 = (WORD) MenuFill (psz, pMenu);
2867 pwd = *pMenu;
2868 ptr = *psz;
2869 if (flag1 & 0x0080)
2870 break;
2871 }
2872 // fill # of details to num above
2873 //*(WORD *)pTemp = (WORD)num;
2874 *pMenu = pwd;
2875 *psz = ptr;
2876 return flag;
2877 }
2878
2879
2880 //
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.
2887 //
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
2900 //
2901 // flag normal menu flag (leaf node)
2902 // id normal menu id
2903 // name normal menu name
2904 // or or
2905 // flag popup menu flag (internal node)
2906 // popupname popup menu name
2907 //
2908 // flag it may folows
2909 // id normal menu id
2910 // name normal menu name
2911 // or or
2912 // flag popup menu
2913 // popupname popup menu name
2914 // .........
2915 // it goes on like this,
2916 // but usually, it only goes a few steps,...
2917 // ------------------------------------------------------------------------------
2918 /* scan menu and copy menu */
2919 int WINAPI
2920 GetContentsOfMenu (
2921 LPVOID lpFile,
2922 char **pszResTypes)
2923 {
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;
2932 WORD* pPopup;
2933 //PIMAGE_NORMAL_MENU_ITEM pNormal;
2934 char buff[32];
2935 int /*nCnt = 0,*/ i, j;
2936 //int num = 0;
2937 int size;
2938 int sLength, nMenus;
2939 WORD flag;
2940 WORD *pwd;
2941 //DWORD prdeName;
2942 //DWORD dwBase; obsolete
2943 char *pMem/*, *pTemp*/;
2944 //BOOL isStrange = FALSE;
2945
2946
2947 /* get root directory of resource tree */
2948 if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2949 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2950 return 0;
2951
2952 /* set pointer to first resource type entry */
2953 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2954 ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
2955
2956 for (i = 0; i < prdType->NumberOfIdEntries; i++)
2957 {
2958 if (prde->Name == RT_MENU)
2959 break;
2960 prde++;
2961 }
2962 if (prde->Name != RT_MENU)
2963 return 0;
2964
2965 prdName = (PIMAGE_RESOURCE_DIRECTORY)
2966 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2967 if (prdName == NULL)
2968 return 0;
2969
2970 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2971 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
2972
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);
2977
2978 nMenus = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
2979 sLength = 0;
2980
2981 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
2982 {
2983 pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
2984 ((DWORD) prdType + (prde->Name ^ 0x80000000));
2985 sLength += pMenuName->Length + 1;
2986
2987 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
2988 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2989 if (prdLanguage == NULL)
2990 continue;
2991
2992 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2993 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
2994
2995 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
2996 ((DWORD) prdType + prde1->OffsetToData);
2997 if (prData == NULL)
2998 continue;
2999
3000 pMenuHeader = (PIMAGE_MENU_HEADER)
3001 GetActualAddress (lpFile, prData->OffsetToData);
3002
3003 //
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.
3009 //
3010
3011 // strange case
3012 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3013 {
3014 //isStrange = TRUE;
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);
3021 }
3022 // normal case
3023 else
3024 {
3025 pPopup = (WORD*)
3026 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3027 while (1)
3028 {
3029 flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3030 if (flag & 0x0080)
3031 break;
3032 }
3033 }
3034 prde++;
3035 }
3036 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3037 {
3038 sLength += 12;
3039
3040 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3041 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3042 if (prdLanguage == NULL)
3043 continue;
3044
3045 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3046 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3047
3048 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3049 ((DWORD) prdType + prde1->OffsetToData);
3050 if (prData == NULL)
3051 continue;
3052
3053 pMenuHeader = (PIMAGE_MENU_HEADER)
3054 GetActualAddress (lpFile, prData->OffsetToData);
3055 // strange case
3056 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3057 {
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);
3064 }
3065 // normal case
3066 else
3067 {
3068 pPopup = (WORD*)
3069 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3070 while (1)
3071 {
3072 flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3073 if (flag & 0x0080)
3074 break;
3075 }
3076 }
3077 prde++;
3078 }
3079 //
3080 // allocate memory for menu names
3081 //
3082 *pszResTypes = (char *) calloc (sLength, 1);
3083
3084 pMem = *pszResTypes;
3085 //
3086 // and start all over again
3087 //
3088 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3089 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3090
3091 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3092 {
3093 pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
3094 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3095
3096
3097 for (j = 0; j < pMenuName->Length; j++)
3098 *pMem++ = (char) (pMenuName->NameString[j]);
3099 *pMem = 0;
3100 pMem++;
3101
3102
3103 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3104 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3105 if (prdLanguage == NULL)
3106 continue;
3107
3108 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3109 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3110
3111 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3112 ((DWORD) prdType + prde1->OffsetToData);
3113 if (prData == NULL)
3114 continue;
3115
3116 pMenuHeader = (PIMAGE_MENU_HEADER)
3117 GetActualAddress (lpFile, prData->OffsetToData);
3118 // strange case
3119 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3120 {
3121 pwd = (WORD *) ((DWORD) pMenuHeader);
3122 size = prData->Size;
3123 strcpy (pMem, ":::::::::::");
3124 pMem += 12;
3125 *(int *) pMem = size;
3126 pMem += 4;
3127 StrangeMenuFill (&pMem, &pwd, size);
3128 }
3129 // normal case
3130 else
3131 {
3132 pPopup = (WORD*)
3133 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3134 while (1)
3135 {
3136 flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3137 if (flag & 0x0080)
3138 break;
3139 }
3140 }
3141 prde++;
3142 }
3143 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3144 {
3145
3146 sprintf (buff, "MenuId_%04X", (prde->Name));
3147 strcpy (pMem, buff);
3148 pMem += strlen (buff) + 1;
3149
3150 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3151 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3152 if (prdLanguage == NULL)
3153 continue;
3154
3155 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3156 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3157
3158 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3159 ((DWORD) prdType + prde1->OffsetToData);
3160 if (prData == NULL)
3161 continue;
3162
3163 pMenuHeader = (PIMAGE_MENU_HEADER)
3164 GetActualAddress (lpFile, prData->OffsetToData);
3165 // strange case
3166 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3167 {
3168 pwd = (WORD *) ((DWORD) pMenuHeader);
3169 size = prData->Size;
3170 strcpy (pMem, ":::::::::::");
3171 pMem += 12;
3172 *(int *) pMem = size;
3173 pMem += 4;
3174 StrangeMenuFill (&pMem, &pwd, size);
3175 }
3176 // normal case
3177 else
3178 {
3179 pPopup = (WORD*)
3180 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3181 while (1)
3182 {
3183 flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3184 if (flag & 0x0080)
3185 break;
3186 }
3187 }
3188 prde++;
3189 }
3190
3191 return nMenus;
3192 }
3193
3194
3195 //
3196 // This function is written by sang cho
3197 // October 12, 1997
3198 //
3199 /* print contents of menu */
3200 int WINAPI
3201 PrintStrangeMenu (
3202 char **psz)
3203 {
3204
3205 //int i, j, k, l;
3206 int num;
3207 //WORD flag1, flag2;
3208 //char buff[128];
3209 char *ptr, *pmax;
3210
3211 //return dumpMenu (psz, size);
3212
3213 ptr = *psz;
3214
3215 if (strncmp (ptr, ":::::::::::", 11) != 0)
3216 {
3217 printf ("\n#### I don't know why!!!");
3218 dumpMenu (psz, 1024);
3219 exit (0);
3220 }
3221
3222 ptr += 12;
3223 num = *(int *) ptr;
3224 ptr += 4;
3225 pmax = ptr + num;
3226
3227 *psz = ptr;
3228 return dumpMenu (psz, num);
3229
3230 // I will write some code later...
3231
3232 }
3233
3234
3235
3236
3237 //
3238 // This function is written by sang cho
3239 // October 2, 1997
3240 //
3241 /* print contents of menu */
3242 int WINAPI
3243 PrintMenu (
3244 int indent,
3245 char **psz)
3246 {
3247
3248 int /*i, */ j, k, l;
3249 WORD id /*, num */ ;
3250 WORD flag;
3251 char buff[128];
3252 char *ptr;
3253
3254
3255 ptr = *psz;
3256 //num = *(WORD *)ptr;
3257 //ptr += 2;
3258 while (1)
3259 {
3260 flag = *(WORD *) ptr;
3261 if (flag & 0x0010) // flag == popup
3262
3263 {
3264 printf ("\n\n");
3265 for (j = 0; j < indent; j++)
3266 printf (" ");
3267 ptr += 2;
3268 printf ("%s {Popup}\n", ptr);
3269 ptr += strlen (ptr) + 1;
3270 *psz = ptr;
3271 PrintMenu (indent + 5, psz);
3272 ptr = *psz;
3273 }
3274 else // ispopup == 0
3275
3276 {
3277 printf ("\n");
3278 for (j = 0; j < indent; j++)
3279 printf (" ");
3280 ptr += 2;
3281 id = *(WORD *) ptr;
3282 ptr += 2;
3283 strcpy (buff, ptr);
3284 l = strlen (ptr);
3285 ptr += l + 1;
3286 if (strchr (buff, 0x09) != NULL)
3287 {
3288 for (k = 0; k < l; k++)
3289 if (buff[k] == 0x09)
3290 break;
3291 for (j = 0; j < l - k; j++)
3292 buff[31 - j] = buff[l - j];
3293 for (j = k; j < 32 + k - l; j++)
3294 buff[j] = 32;
3295 }
3296 if (strchr (buff, 0x08) != NULL)
3297 {
3298 for (k = 0; k < l; k++)
3299 if (buff[k] == 0x08)
3300 break;
3301 for (j = 0; j < l - k; j++)
3302 buff[31 - j] = buff[l - j];
3303 for (j = k; j < 32 + k - l; j++)
3304 buff[j] = 32;
3305 }
3306 printf ("%s", buff);
3307 l = strlen (buff);
3308 for (j = l; j < 32; j++)
3309 printf (" ");
3310 printf ("[ID=%04Xh]", id);
3311 *psz = ptr;
3312 }
3313 if (flag & 0x0080)
3314 break;
3315 }
3316 return 0;
3317 }
3318
3319
3320 //
3321 // This function is written by sang cho
3322 // October 2, 1997
3323 //
3324 /* the format of menu is not known so I'll do my best */
3325 int WINAPI
3326 dumpMenu (
3327 char **psz,
3328 int size)
3329 {
3330
3331 int i, j, k, n, l, c;
3332 char buff[32];
3333 char *ptr, *pmax;
3334
3335 ptr = *psz;
3336 pmax = ptr + size;
3337 for (i = 0; i < (size / 16) + 1; i++)
3338 {
3339 n = 0;
3340 for (j = 0; j < 16; j++)
3341 {
3342 c = (int) (*ptr);
3343 if (c < 0)
3344 c += 256;
3345 buff[j] = c;
3346 printf ("%02X", c);
3347 ptr++;
3348 if (ptr >= pmax)
3349 break;
3350 n++;
3351 if (n % 4 == 0)
3352 printf (" ");
3353 }
3354 n++;
3355 if (n % 4 == 0)
3356 printf (" ");
3357 l = j;
3358 j++;
3359 for (; j < 16; j++)
3360 {
3361 n++;
3362 if (n % 4 == 0)
3363 printf (" ");
3364 else
3365 printf (" ");
3366 }
3367 printf (" ");
3368 for (k = 0; k < l; k++)
3369 if (isprint (c = buff[k]))
3370 printf ("%c", c);
3371 else
3372 printf (".");
3373 printf ("\n");
3374 if (ptr >= pmax)
3375 break;
3376 }
3377
3378 *psz = ptr;
3379 return 0;
3380 }
3381
3382
3383
3384
3385 //
3386 // This function is written by sang cho
3387 // October 13, 1997
3388 //
3389 /* scan dialog box and copy dialog box */
3390 int WINAPI
3391 GetContentsOfDialog (
3392 LPVOID lpFile,
3393 char **pszResTypes)
3394 {
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;
3401 char buff[32];
3402 int /*nCnt = 0,*/ i, j;
3403 //int num = 0;
3404 int size;
3405 int sLength, nDialogs;
3406 //WORD flag;
3407 WORD *pwd;
3408 //DWORD prdeName;
3409 char *pMem/*, *pTemp*/;
3410 //BOOL isStrange = FALSE;
3411
3412
3413 /* get root directory of resource tree */
3414 if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
3415 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
3416 return 0;
3417
3418 /* set pointer to first resource type entry */
3419 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3420 ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
3421
3422 for (i = 0; i < prdType->NumberOfIdEntries; i++)
3423 {
3424 if (prde->Name == RT_DIALOG)
3425 break;
3426 prde++;
3427 }
3428 if (prde->Name != RT_DIALOG)
3429 return 0;
3430
3431 prdName = (PIMAGE_RESOURCE_DIRECTORY)
3432 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3433 if (prdName == NULL)
3434 return 0;
3435
3436 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3437 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3438
3439
3440 nDialogs = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
3441 sLength = 0;
3442
3443 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3444 {
3445 pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3446 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3447 sLength += pDialogName->Length + 1;
3448
3449 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3450 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3451 if (prdLanguage == NULL)
3452 continue;
3453
3454 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3455 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3456
3457 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3458 ((DWORD) prdType + prde1->OffsetToData);
3459 if (prData == NULL)
3460 continue;
3461
3462 size = prData->Size;
3463 sLength += 4 + size;
3464 prde++;
3465 }
3466 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3467 {
3468 sLength += 14;
3469
3470 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3471 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3472 if (prdLanguage == NULL)
3473 continue;
3474
3475 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3476 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3477
3478 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3479 ((DWORD) prdType + prde1->OffsetToData);
3480 if (prData == NULL)
3481 continue;
3482
3483 size = prData->Size;
3484 sLength += 4 + size;
3485 prde++;
3486 }
3487 //
3488 // allocate memory for menu names
3489 //
3490 *pszResTypes = (char *) calloc (sLength, 1);
3491
3492 pMem = *pszResTypes;
3493 //
3494 // and start all over again
3495 //
3496 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3497 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3498
3499 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3500 {
3501 pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3502 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3503
3504
3505 for (j = 0; j < pDialogName->Length; j++)
3506 *pMem++ = (char) (pDialogName->NameString[j]);
3507 *pMem = 0;
3508 pMem++;
3509
3510
3511 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3512 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3513 if (prdLanguage == NULL)
3514 continue;
3515
3516 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3517 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3518
3519 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3520 ((DWORD) prdType + prde1->OffsetToData);
3521 if (prData == NULL)
3522 continue;
3523
3524 pDialogHeader = (PIMAGE_DIALOG_HEADER)
3525 GetActualAddress (lpFile, prData->OffsetToData);
3526
3527
3528
3529 pwd = (WORD *) ((DWORD) pDialogHeader);
3530 size = prData->Size;
3531 *(int *) pMem = size;
3532 pMem += 4;
3533 StrangeMenuFill (&pMem, &pwd, size);
3534
3535 prde++;
3536 }
3537 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3538 {
3539
3540 sprintf (buff, "DialogId_%04X", (prde->Name));
3541 strcpy (pMem, buff);
3542 pMem += strlen (buff) + 1;
3543
3544 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3545 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3546 if (prdLanguage == NULL)
3547 {
3548 printf ("\nprdLanguage = NULL");
3549 exit (0);
3550 }
3551
3552 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3553 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3554
3555 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3556 ((DWORD) prdType + prde1->OffsetToData);
3557 if (prData == NULL)
3558 {
3559 printf ("\nprData = NULL");
3560 exit (0);
3561 }
3562
3563 pDialogHeader = (PIMAGE_DIALOG_HEADER)
3564 GetActualAddress (lpFile, prData->OffsetToData);
3565
3566
3567 pwd = (WORD *) ((DWORD) pDialogHeader);
3568 size = prData->Size;
3569 *(int *) pMem = size;
3570 pMem += 4;
3571 StrangeMenuFill (&pMem, &pwd, size);
3572
3573 prde++;
3574 }
3575
3576 return nDialogs;
3577 }
3578
3579
3580 //
3581 // This function is written by sang cho
3582 // October 14, 1997
3583 //
3584 /* print contents of dialog */
3585 void WINAPI
3586 PrintNameOrOrdinal (
3587 char **psz)
3588 {
3589 char *ptr;
3590
3591 ptr = *psz;
3592 if (*(WORD *) ptr == 0xFFFF)
3593 {
3594 ptr += 2;
3595 printf ("%04X", *(WORD *) ptr);
3596 ptr += 2;
3597 }
3598 else
3599 {
3600 printf ("%c", '"');
3601 while (*(WORD *) ptr)
3602 {
3603 printf ("%c", *ptr);
3604 ptr += 2;
3605 }
3606 ptr += 2;
3607 printf ("%c", '"');
3608 }
3609 *psz = ptr;
3610 }
3611
3612
3613 //
3614 // This function is written by sang cho
3615 // October 14, 1997
3616 //
3617 /* print contents of dialog */
3618 void WINAPI
3619 PrintDialog (
3620 char **psz)
3621 {
3622 int i/*, j, k, l, n, c*/;
3623 int num, size;
3624 DWORD flag;
3625 WORD class;
3626 //char buff[32];
3627 char *ptr, *pmax;
3628 BOOL isStrange = FALSE;
3629
3630 ptr = *psz;
3631 size = *(int *) ptr;
3632 ptr += 4;
3633 pmax = ptr + size;
3634
3635 // IStype of Dialog Header
3636 flag = *(DWORD *) ptr;
3637 //
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
3641 //
3642
3643 if ((flag & 0xFFFF0000) == 0xFFFF0000)
3644 {
3645 flag = *(DWORD *) (ptr + 12);
3646 num = *(short *) (ptr + 16);
3647 isStrange = TRUE;
3648 ptr += 26;
3649 }
3650 else
3651 {
3652 num = *(short *) (ptr + 8);
3653 ptr += 18;
3654 }
3655 printf (", # of Controls=%03d, Caption:%c", num, '"');
3656
3657 // Menu name
3658 if (*(WORD *) ptr == 0xFFFF)
3659 ptr += 4; // ordinal
3660
3661 else
3662 {
3663 while (*(WORD *) ptr)
3664 ptr += 2;
3665 ptr += 2;
3666 } // name
3667
3668 // Class name
3669 if (*(WORD *) ptr == 0xFFFF)
3670 ptr += 4; // ordinal
3671
3672 else
3673 {
3674 while (*(WORD *) ptr)
3675 ptr += 2;
3676 ptr += 2;
3677 } // name
3678
3679 // Caption
3680 while (*(WORD *) ptr)
3681 {
3682 printf ("%c", *ptr);
3683 ptr += 2;
3684 }
3685 ptr += 2;
3686 printf ("%c", '"');
3687
3688 // FONT present
3689 if (flag & 0x00000040)
3690 {
3691 if (isStrange)
3692 ptr += 6;
3693 else
3694 ptr += 2; // FONT size
3695
3696 while (*(WORD *) ptr)
3697 ptr += 2; // WCHARs
3698
3699 ptr += 2; // double null
3700
3701 }
3702
3703 // strange case adjust
3704 if (isStrange)
3705 ptr += 8;
3706
3707 // DWORD padding
3708 if ((ptr - *psz) % 4)
3709 ptr += 4 - ((ptr - *psz) % 4);
3710
3711 // start reporting .. finally
3712 for (i = 0; i < num; i++)
3713 {
3714 flag = *(DWORD *) ptr;
3715 if (isStrange)
3716 ptr += 14;
3717 else
3718 ptr += 16;
3719 printf ("\n Control::%03d - ID:", i + 1);
3720
3721 // Control ID
3722 printf ("%04X, Class:", *(WORD *) ptr);
3723 ptr += 2;
3724
3725 // Control Class
3726 if (*(WORD *) ptr == 0xFFFF)
3727 {
3728 ptr += 2;
3729 class = *(WORD *) ptr;
3730 ptr += 2;
3731 switch (class)
3732 {
3733 case 0x80:
3734 printf ("BUTTON ");
3735 break;
3736 case 0x81:
3737 printf ("EDIT ");
3738 break;
3739 case 0x82:
3740 printf ("STATIC ");
3741 break;
3742 case 0x83:
3743 printf ("LISTBOX ");
3744 break;
3745 case 0x84:
3746 printf ("SCROLLBAR");
3747 break;
3748 case 0x85:
3749 printf ("COMBOBOX ");
3750 break;
3751 default:
3752 printf ("%04X ", class);
3753 break;
3754 }
3755 }
3756 else
3757 PrintNameOrOrdinal (&ptr);
3758
3759 printf (" Text:");
3760
3761 // Text
3762 PrintNameOrOrdinal (&ptr);
3763
3764 // nExtraStuff
3765 ptr += 2;
3766
3767 // strange case adjust
3768 if (isStrange)
3769 ptr += 8;
3770
3771 // DWORD padding
3772 if ((ptr - *psz) % 4)
3773 ptr += 4 - ((ptr - *psz) % 4);
3774 }
3775
3776 /*
3777 ptr = *psz;
3778 printf("\n");
3779
3780 for (i=0; i<(size/16)+1; i++)
3781 {
3782 n = 0;
3783 for (j=0; j<16; j++)
3784 {
3785 c = (int)(*ptr);
3786 if (c<0) c+=256;
3787 buff[j] = c;
3788 printf ("%02X",c);
3789 ptr++;
3790 if (ptr >= pmax) break;
3791 n++;
3792 if (n%4 == 0) printf (" ");
3793 }
3794 n++; if (n%4 == 0) printf (" ");
3795 l = j;
3796 j++;
3797 for (; j<16; j++)
3798 { n++; if (n%4 == 0) printf (" "); else printf (" "); }
3799 printf (" ");
3800 for (k=0; k<l; k++)
3801 if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3802 printf ("\n");
3803 if (ptr >= pmax) break;
3804 }
3805 */
3806
3807 *psz = pmax;
3808
3809 }
3810
3811
3812
3813
3814
3815
3816 /* function indicates whether debug info has been stripped from file */
3817 BOOL WINAPI
3818 IsDebugInfoStripped (
3819 LPVOID lpFile)
3820 {
3821 PIMAGE_FILE_HEADER pfh;
3822
3823 pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
3824
3825 return (pfh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
3826 }
3827
3828
3829
3830
3831 /* retrieve the module name from the debug misc. structure */
3832 int WINAPI
3833 RetrieveModuleName (
3834 LPVOID lpFile,
3835 char **pszModule)
3836 {
3837
3838 PIMAGE_DEBUG_DIRECTORY pdd;
3839 PIMAGE_DEBUG_MISC pdm = NULL;
3840 int nCnt;
3841
3842 if (!(pdd = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_DEBUG)))
3843 return 0;
3844
3845 while (pdd->SizeOfData)
3846 {
3847 if (pdd->Type == IMAGE_DEBUG_TYPE_MISC)
3848 {
3849 pdm = (PIMAGE_DEBUG_MISC) ((DWORD) pdd->PointerToRawData + (DWORD) lpFile);
3850 *pszModule = (char *) calloc ((nCnt = (strlen (pdm->Data))) + 1, 1);
3851 // may need some unicode business here...above
3852 bcopy (pdm->Data, *pszModule, nCnt);
3853
3854 break;
3855 }
3856
3857 pdd++;
3858 }
3859
3860 if (pdm != NULL)
3861 return nCnt;
3862 else
3863 return 0;
3864 }
3865
3866
3867
3868
3869
3870 /* determine if this is a valid debug file */
3871 BOOL WINAPI
3872 IsDebugFile (
3873 LPVOID lpFile)
3874 {
3875 PIMAGE_SEPARATE_DEBUG_HEADER psdh;
3876
3877 psdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3878
3879 return (psdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE);
3880 }
3881
3882
3883
3884
3885 /* copy separate debug header structure from debug file */
3886 BOOL WINAPI
3887 GetSeparateDebugHeader (
3888 LPVOID lpFile,
3889 PIMAGE_SEPARATE_DEBUG_HEADER psdh)
3890 {
3891 PIMAGE_SEPARATE_DEBUG_HEADER pdh;
3892
3893 pdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3894
3895 if (pdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
3896 {
3897 bcopy ((LPVOID) pdh, (LPVOID) psdh, sizeof (IMAGE_SEPARATE_DEBUG_HEADER));
3898 return TRUE;
3899 }
3900
3901 return FALSE;
3902 }
3903
3904 //
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.
3912 // .... sang cho
3913
3914 #define MAXSECTIONNUMBER 16
3915 #define MAXNAMESTRNUMBER 40
3916 int
3917 main (
3918 int argc,
3919 char **argv
3920 )
3921 {
3922 DWORD fileType;
3923 LPVOID lpFile;
3924 FILE *my_fp;
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;
3932
3933 int nSections; // number of sections
3934
3935 int nResources; // number of resources
3936
3937 int nMenus; // number of menus
3938
3939 int nDialogs; // number of dialogs
3940
3941 int nImportedModules; // number of imported modules
3942
3943 int nFunctions; // number of functions in the imported module
3944
3945 int nExportedFunctions; // number of exported funcions
3946
3947 int imageBase;
3948 int entryPoint;
3949
3950 int i, j, /*k,*/ n;
3951 //int mnsize;
3952 //int nCnt;
3953 //int nSize;
3954 int fsize;
3955 char *pnstr;
3956 char *pst;
3957 char *piNameBuff; // import module name buffer
3958
3959 char *pfNameBuff; // import functions in the module name buffer
3960
3961 char *peNameBuff; // export function name buffer
3962
3963 char *pmNameBuff; // menu name buffer
3964
3965 char *pdNameBuff; // dialog name buffer
3966
3967 /*
3968 * Check user arguments.
3969 */
3970 if (2 == argc)
3971 {
3972 my_fp = fopen (argv[1], "rb");
3973 if (my_fp == NULL)
3974 {
3975 printf (
3976 "%s: can not open input file \"%s\".\n",
3977 argv[0],
3978 argv[1]
3979 );
3980 exit (0);
3981 }
3982 }
3983 else
3984 {
3985 printf (
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",
3990 argv[0]
3991 );
3992 printf (
3993 "usage: %s input_file_name\n",
3994 argv[0]
3995 );
3996 exit (0);
3997 }
3998 /*
3999 * Get input file's size.
4000 */
4001 /* argv [0], */
4002 fseek (my_fp, 0L, SEEK_END);
4003 fsize = ftell (my_fp);
4004 rewind (my_fp);
4005 /*
4006 * Buffer the file in memory.
4007 */
4008 lpFile = (void *) calloc (fsize, 1);
4009 if (lpFile == NULL)
4010 {
4011 printf (
4012 "%s: can not allocate memory.\n",
4013 argv[0]
4014 );
4015 exit (0);
4016 }
4017 /*
4018 * --- Start of report ---
4019 */
4020 printf ("\n\nDump of file: %s\n\n", argv[1]);
4021
4022 n = fread (lpFile, fsize, 1, my_fp);
4023
4024 if (n == -1)
4025 {
4026 printf (
4027 "%s: failed to read the file \"%s\".\n",
4028 argv[0],
4029 argv[1]
4030 );
4031 exit (0);
4032 }
4033
4034 GetDosHeader (lpFile, &dosHdr);
4035
4036 if ((WORD) IMAGE_DOS_SIGNATURE == dosHdr.e_magic)
4037 {
4038 if ((dosHdr.e_lfanew > 4096)
4039 || (dosHdr.e_lfanew < 64)
4040 )
4041 {
4042 printf (
4043 "%s: This file is not in PE format; it looks like in DOS format.\n",
4044 argv[0]
4045 );
4046 exit (0);
4047 }
4048 }
4049 else
4050 {
4051 printf (
4052 "%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4053 argv[0],
4054 dosHdr.e_magic
4055 );
4056 exit (0);
4057 }
4058
4059 fileType = ImageFileType (lpFile);
4060
4061 if (fileType != IMAGE_NT_SIGNATURE)
4062 {
4063 printf (
4064 "%s: This file is not in PE format (magic = 0x%08x).\n",
4065 argv[0],
4066 fileType
4067 );
4068 exit (0);
4069 }
4070
4071 //=====================================
4072 // now we can really start processing
4073 //=====================================
4074
4075 pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
4076
4077 poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
4078
4079 psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
4080
4081 nSections = pfh->NumberOfSections;
4082
4083 imageBase = poh->ImageBase;
4084
4085 entryPoint = poh->AddressOfEntryPoint;
4086
4087 if (psh == NULL)
4088 return 0;
4089
4090 /* store section headers */
4091
4092 for (i = 0;
4093 i < nSections;
4094 i++
4095 )
4096 {
4097 shdr[i] = *psh++;
4098 }
4099 /*
4100 * Get Code offset and size,
4101 * Data offset and size.
4102 */
4103 for (i = 0;
4104 i < nSections;
4105 i++
4106 )
4107 {
4108 if (poh->BaseOfCode == shdr[i].VirtualAddress)
4109 {
4110 printf (
4111 "Code Offset = %08X, Code Size = %08X \n",
4112 shdr[i].PointerToRawData,
4113 shdr[i].SizeOfRawData
4114 );
4115 }
4116 if (((shdr[i].Characteristics) & 0xC0000040) == 0xC0000040)
4117 {
4118 printf (
4119 "Data Offset = %08X, Data Size = %08X \n",
4120 shdr[i].PointerToRawData,
4121 shdr[i].SizeOfRawData
4122 );
4123 break;
4124 }
4125 }
4126
4127 printf ("\n");
4128
4129 printf (
4130 "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
4131 nSections,
4132 imageBase
4133 );
4134 /*
4135 * Object name alignment.
4136 */
4137 for (i = 0;
4138 i < nSections;
4139 i++
4140 )
4141 {
4142 for (j = 0;
4143 j < 7;
4144 j++
4145 )
4146 {
4147 if (shdr[i].Name[j] == 0)
4148 {
4149 shdr[i].Name[j] = 32;
4150 }
4151 }
4152 shdr[i].Name[7] = 0;
4153 }
4154 for (i = 0; i < nSections; i++)
4155 printf ("\n Object%02d: %8s RVA: %08X Offset: %08X Size: %08X Flags: %08X ",
4156 i + 1, shdr[i].Name, shdr[i].VirtualAddress, shdr[i].PointerToRawData,
4157 shdr[i].SizeOfRawData, shdr[i].Characteristics);
4158 /*
4159 * Get List of Resources.
4160 */
4161 nResources = GetListOfResourceTypes (lpFile, &pnstr);
4162 pst = pnstr;
4163 printf ("\n");
4164 printf ("\n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++");
4165 printf ("\n");
4166 if (nResources == 0)
4167 printf ("\n There are no Resources in This Application.\n");
4168 else
4169 {
4170 printf ("\nNumber of Resource Types = %4d (decimal)\n", nResources);
4171 for (i = 0; i < nResources; i++)
4172 {
4173 printf ("\n Resource Type %03d: %s", i + 1, pst);
4174 pst += strlen ((char *) (pst)) + 1;
4175 }
4176 free ((void *) pnstr);
4177
4178 printf ("\n");
4179 printf ("\n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++");
4180 printf ("\n");
4181
4182 nMenus = GetContentsOfMenu (lpFile, &pmNameBuff);
4183
4184 if (nMenus == 0)
4185 {
4186 printf ("\n There are no Menus in This Application.\n");
4187 }
4188 else
4189 {
4190 pst = pmNameBuff;
4191 printf ("\nNumber of Menus = %4d (decimal)", nMenus);
4192
4193 //dumpMenu(&pst, 8096);
4194 for (i = 0; i < nMenus; i++)
4195 {
4196 // menu ID print
4197 printf ("\n\n%s", pst);
4198 pst += strlen (pst) + 1;
4199 printf ("\n-------------");
4200 if (strncmp (pst, ":::::::::::", 11) == 0)
4201 {
4202 printf ("\n");
4203 PrintStrangeMenu (&pst);
4204 }
4205 else
4206 {
4207 PrintMenu (6, &pst);
4208 }
4209 //else PrintStrangeMenu(&pst);
4210 }
4211 free ((void *) pmNameBuff);
4212 printf ("\n");
4213 }
4214
4215 printf ("\n");
4216 printf ("\n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++");
4217 printf ("\n");
4218
4219 nDialogs = GetContentsOfDialog (lpFile, &pdNameBuff);
4220
4221 if (nDialogs == 0)
4222 {
4223 printf ("\n There are no Dialogs in This Application.\n");
4224 }
4225 else
4226 {
4227 pst = pdNameBuff;
4228 printf ("\nNumber of Dialogs = %4d (decimal)", nDialogs);
4229
4230 printf ("\n");
4231
4232 for (i = 0; i < nDialogs; i++)
4233 {
4234 // Dialog ID print
4235 printf ("\nName: %s", pst);
4236 pst += strlen (pst) + 1;
4237 PrintDialog (&pst);
4238 }
4239 free ((void *) pdNameBuff);
4240 printf ("\n");
4241 }
4242 }
4243
4244 printf ("\n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++");
4245
4246 nImportedModules = GetImportModuleNames (lpFile, &piNameBuff);
4247 if (nImportedModules == 0)
4248 {
4249 printf ("\n There are no imported Functions in This Application.\n");
4250 }
4251 else
4252 {
4253 pnstr = piNameBuff;
4254 printf ("\nNumber of Imported Modules = %4d (decimal)\n", nImportedModules);
4255 for (i = 0; i < nImportedModules; i++)
4256 {
4257 printf ("\n Import Module %03d: %s", i + 1, pnstr);
4258 pnstr += strlen ((char *) (pnstr)) + 1;
4259 }
4260
4261 printf ("\n");
4262 printf ("\n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++");
4263 pnstr = piNameBuff;
4264 for (i = 0; i < nImportedModules; i++)
4265 {
4266 printf ("\n\n Import Module %03d: %s \n", i + 1, pnstr);
4267 nFunctions = GetImportFunctionNamesByModule (lpFile, pnstr, &pfNameBuff);
4268 pnstr += strlen ((char *) (pnstr)) + 1;
4269 pst = pfNameBuff;
4270 for (j = 0; j < nFunctions; j++)
4271 {
4272 printf ("\nAddr:%08X hint(%04X) Name: %s",
4273 (*(int *) pst), (*(short *) (pst + 4)),
4274 //(pst+6));
4275 TranslateFunctionName (pst + 6));
4276 pst += strlen ((char *) (pst + 6)) + 1 + 6;
4277 }
4278 free ((void *) pfNameBuff);
4279 }
4280 free ((void *) piNameBuff);
4281 }
4282
4283 printf ("\n");
4284 printf ("\n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++");
4285
4286 nExportedFunctions = GetExportFunctionNames (lpFile, &peNameBuff);
4287 printf ("\nNumber of Exported Functions = %4d (decimal)\n", nExportedFunctions);
4288
4289 if (nExportedFunctions > 0)
4290 {
4291 pst = peNameBuff;
4292
4293 for (i = 0; i < nExportedFunctions; i++)
4294 {
4295 printf ("\nAddr:%08X Ord:%4d (%04Xh) Name: %s",
4296 (*(int *) pst), (*(WORD *) (pst + 4)), (*(WORD *) (pst + 4)),
4297 //(pst+6));
4298 TranslateFunctionName (pst + 6));
4299 pst += strlen ((char *) (pst + 6)) + 6 + 1;
4300 }
4301 free ((void *) peNameBuff);
4302 }
4303
4304 free ((void *) lpFile);
4305
4306 return 0;
4307 }
4308
4309
4310 /* EOF */