Sync to trunk head(r38096)
[reactos.git] / rosapps / applications / sysutils / pedump / 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 char * 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 ((char *)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, (char *)psh[i].Name);
1161 ps += strlen ((char *)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 ((char *)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 char * WINAPI
1953 TranslateFunctionName (
1954 char *psz)
1955 {
1956
1957
1958 int i, /*j,*/ n;
1959 char c = 0;
1960 char cc;
1961
1962 static char buff[512]; // result of translation
1963
1964 int is = 0;
1965 char pStack[32]; // parameter processing stack
1966
1967 Str_P sStack[32]; // String processing stack
1968
1969 Str_P tok; // String token
1970
1971 Str_P c_str; // current string
1972
1973 int iend = 0;
1974 char *endTab[8]; // end of string position check
1975
1976 char *ps;
1977 char *pin, *pout;
1978 BOOL stringMode = TRUE;
1979
1980 if (*psz != '@')
1981 return psz;
1982 pin = psz;
1983 pout = buff;
1984 ps = pStack;
1985
1986 //................................................................
1987 // serious users may need to run the following code.
1988 // so I may need to include some flag options...
1989 // If you want to know about how translation is done,
1990 // you can just revive following line and you can see it.
1991 // october 6, 1997 ... sang cho
1992 //printf ("\n................................... %s", psz); // for debugging...
1993
1994 //pa = pb = pout;
1995 pin++;
1996 tok.flag = 'A';
1997 tok.pos = pout;
1998 tok.length = 0;
1999 tok.wasString = stringMode;
2000 sStack[is++] = tok; // initialize sStack with dummy marker
2001
2002 while (*pin)
2003 {
2004 while (*pin)
2005 {
2006 c = *pin;
2007
2008 //---------------------------------------------
2009 // check for the end of number specified string
2010 //---------------------------------------------
2011
2012 if (iend > 0)
2013 {
2014 for (i = 0; i < iend; i++)
2015 if (pin == endTab[i])
2016 break;
2017 if (i < iend)
2018 {
2019 // move the end of endTab to ith position
2020 endTab[i] = endTab[iend - 1];
2021 iend--;
2022
2023 // get top of the string stack
2024 tok = sStack[is - 1];
2025
2026 // I am expecting '#' token from stack
2027 if (tok.flag != '#')
2028
2029 {
2030 printf ("\n**some serious error1** %c is = %d char = %c",
2031 tok.flag, is, *pin);
2032 exit (0);
2033 }
2034
2035 // pop '#' token I am happy now.
2036 else
2037 { //if (c)
2038 //printf("\n pop # token ... current char = %c", c);
2039 //else printf("\n pop percent token..next char = NULL");
2040
2041 is--;
2042 }
2043
2044 stringMode = tok.wasString;
2045
2046 if (!stringMode)
2047 {
2048 // need to process postfix finally
2049 cc = *(ps - 1);
2050 if (strchr ("qtx", cc))
2051 {
2052 if (!strchr ("@$%", c))
2053 *pout++ = ',';
2054 }
2055 else
2056 {
2057 switch (cc)
2058 {
2059 case 'r':
2060 strcpy (pout, "*&");
2061 pout += 2;
2062 ps--;
2063 break;
2064 case 'p':
2065 strcpy (pout, "**");
2066 pout += 2;
2067 ps--;
2068 break;
2069 case '&':
2070 strcpy (pout, "&");
2071 pout += 1;
2072 ps--;
2073 break;
2074 case '*':
2075 strcpy (pout, "*");
2076 pout += 1;
2077 ps--;
2078 break;
2079 default:
2080 strcpy (pout, "!3!");
2081 pout += 3;
2082 ps--;
2083 break;
2084 }
2085 if (!strchr ("@$%", c))
2086 *pout++ = ',';
2087 }
2088 }
2089 // string mode restored...
2090 else;
2091 }
2092 else; // do nothing..
2093
2094 }
2095
2096 //------------------------------------------------
2097 // special control symbol processing:
2098 //------------------------------------------------
2099
2100 if (strchr ("@$%", c))
2101 break;
2102
2103 //---------------------------------------------------------------
2104 // string part processing : no '$' met yet
2105 // or inside of '%' block
2106 // or inside of '#' block (numbered string)
2107 //---------------------------------------------------------------
2108
2109 else if (stringMode)
2110 *pout++ = *pin++;
2111 //else if (is > 1) *pout++ = *pin++;
2112
2113 //------------------------------------------------
2114 // parameter part processing: '$' met
2115 //------------------------------------------------
2116
2117 else // parameter processing
2118
2119 {
2120 if (!isdigit (c))
2121 TranslateParameters (&pin, &pout, &ps);
2122 else // number specified string processing
2123
2124 {
2125 n = GetStringLength (pin);
2126 if (n < 10)
2127 pin++;
2128 else
2129 pin += 2;
2130
2131 // push '#' token
2132 //if (*pin)
2133 //printf("\n push # token .. char = %c", *pin);
2134 //else printf("\n push percent token..next char = NULL");
2135 tok.flag = '#';
2136 tok.pos = pout;
2137 tok.length = 0;
2138 tok.wasString = stringMode;
2139 sStack[is++] = tok;
2140
2141 // mark end of input string
2142 endTab[iend++] = pin + n;
2143 stringMode = TRUE;
2144 }
2145 }
2146 } // end of inner while loop
2147 //
2148 // beginning of new string or end of string ( quotation mark )
2149 //
2150
2151 if (c == '%')
2152 {
2153 pin++; // anyway we have to proceed...
2154
2155 tok = sStack[is - 1]; // get top of the sStack
2156
2157 if (tok.flag == '%')
2158 {
2159 // pop '%' token and set c_str
2160 //if (*pin)
2161 //printf("\n pop percent token..next char = %c", *pin);
2162 //else printf("\n pop percent token..next char = NULL");
2163 is--;
2164 c_str = tok;
2165 c_str.length = pout - c_str.pos;
2166 if (*(ps - 1) == 't')
2167 {
2168 *pout++ = '>';
2169 ps--;
2170 stringMode = tok.wasString;
2171 }
2172 else
2173 {
2174 printf ("\n**some string error3** stack = %c", *(ps - 1));
2175 exit (0);
2176 }
2177 }
2178 else if (tok.flag == 'A' || tok.flag == '#')
2179 {
2180 // push '%' token
2181 //if (*pin)
2182 //printf("\n push percent token..next char = %c", *pin);
2183 //else printf("\n push percent token..next char = NULL");
2184 tok.flag = '%';
2185 tok.pos = pout;
2186 tok.length = 0;
2187 tok.wasString = stringMode;
2188 sStack[is++] = tok;
2189 }
2190 else
2191 {
2192 printf ("\n**some string error5**");
2193 exit (0);
2194 }
2195 }
2196 //
2197 // sometimes we need string to use as constructor name or destructor name
2198 //
2199 else if (c == '@') // get string from previous marker upto here.
2200
2201 {
2202 pin++;
2203 tok = sStack[is - 1];
2204 c_str.flag = 'S';
2205 c_str.pos = tok.pos;
2206 c_str.length = pout - tok.pos;
2207 c_str.wasString = stringMode;
2208 *pout++ = ':';
2209 *pout++ = ':';
2210 }
2211 //
2212 // we need to take care of parameter control sequence
2213 //
2214 else if (c == '$') // need to precess template or parameter part
2215
2216 {
2217 pin++;
2218 if (stringMode)
2219 stringMode = StringExpands (&pin, &pout, &ps, &c_str);
2220 else
2221 { // template parameter mode I guess "$t"
2222
2223 if (is > 1)
2224 {
2225 if (*pin == 't')
2226 pin++;
2227 else
2228 {
2229 printf ("\nMYGOODNESS1 %c", *pin);
2230 exit (0);
2231 }
2232 //ps--;
2233 //if (*ps == 't') *pout++ = '>';
2234 //else { printf("\nMYGOODNESS2"); exit(0);}
2235 *pout++ = ','; //pin++; ..this almost blowed me....
2236
2237 }
2238 // real parameter mode I guess
2239 // unexpected case is found ... humm what can I do...
2240 else
2241 {
2242 // this is newly found twist.. it really hurts.
2243 if (ps <= pStack)
2244 {
2245 if (*pin == 'q')
2246 {
2247 *ps++ = 'q';
2248 *pout++ = '(';
2249 pin++;
2250 }
2251 else
2252 {
2253 printf ("\n** I GIVEUP ***");
2254 exit (0);
2255 }
2256 continue;
2257 }
2258 ps--;
2259 while (*ps != 'q')
2260 {
2261 if (*ps == '*')
2262 *pout++ = '*';
2263 else if (*ps == '&')
2264 *pout++ = '&';
2265 else if (*ps == 'p')
2266 {
2267 *pout++ = '*';
2268 *pout++ = '*';
2269 }
2270 else if (*ps == 'r')
2271 {
2272 *pout++ = '*';
2273 *pout++ = '&';
2274 }
2275 else
2276 {
2277 printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin);
2278 exit (0);
2279 }
2280 ps--;
2281 }
2282 *pout++ = ')';
2283 ps--;
2284 while (*ps != 'q')
2285 {
2286 if (*ps == '*')
2287 *pout++ = '*';
2288 else if (*ps == '&')
2289 *pout++ = '&';
2290 else if (*ps == 'p')
2291 {
2292 *pout++ = '*';
2293 *pout++ = '*';
2294 }
2295 else if (*ps == 'r')
2296 {
2297 *pout++ = '*';
2298 *pout++ = '&';
2299 }
2300 else
2301 {
2302 printf ("\n*** SOMETHING IS WRONG2***");
2303 exit (0);
2304 }
2305 ps--;
2306 }
2307 ps++;
2308 *pout++ = ',';
2309 }
2310 }
2311 } // end of '$' processing
2312
2313 } // end of outer while loop
2314 //
2315 // need to process remaining parameter stack
2316 //
2317
2318 while (ps > pStack)
2319 {
2320 ps--;
2321 switch (*ps)
2322 {
2323 case 't':
2324 *pout++ = '>';
2325 break;
2326 case 'q':
2327 *pout++ = ')';
2328 break;
2329 case 'x':
2330 strcpy (pout, " const");
2331 pout += 6;
2332 break;
2333 case 'r':
2334 strcpy (pout, "*&");
2335 pout += 2;
2336 break;
2337 case 'p':
2338 strcpy (pout, "**");
2339 pout += 2;
2340 break;
2341 case '&':
2342 *pout++ = '&';
2343 break;
2344 case '*':
2345 *pout++ = '*';
2346 break;
2347 default:
2348 strcpy (pout, "!4!");
2349 pout += 3;
2350 *pout++ = *ps;
2351 }
2352 }
2353 *pout = 0;
2354 return buff;
2355 }
2356
2357
2358
2359 //
2360 // This function is written by sang cho
2361 //
2362 //
2363 /* get exported function names separated by null terminators, return count of functions */
2364 int WINAPI
2365 GetExportFunctionNames (
2366 LPVOID lpFile,
2367 char **pszFunctions)
2368 {
2369 //PIMAGE_SECTION_HEADER psh;
2370 PIMAGE_EXPORT_DIRECTORY ped;
2371 //DWORD dwBase;
2372 DWORD imageBase; //===========================
2373
2374 char *pfns[8192] =
2375 {NULL,}; // maximum number of functions
2376 //=============================
2377
2378 char buff[256]; // enough for any string ??
2379
2380 char *psz = NULL; //===============================
2381
2382 DWORD *pdwAddress;
2383 DWORD *pdw1;
2384 DWORD *pdwNames;
2385 WORD *pwOrd;
2386 int i, nCnt = 0, ntmp = 0;
2387 int enid = 0, ordBase = 1; // usally ordBase is 1....
2388
2389 int enames = 0;
2390
2391 /* get section header and pointer to data directory for .edata section */
2392 ped = (PIMAGE_EXPORT_DIRECTORY)
2393 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2394
2395 if (ped == NULL)
2396 return 0;
2397
2398 //
2399 // sometimes there may be no section for idata or edata
2400 // instead rdata or data section may contain these sections ..
2401 // or even module names or function names are in different section.
2402 // so that's why we need to get actual address each time.
2403 // ...................sang cho..................
2404 //
2405 //psh = (PIMAGE_SECTION_HEADER)
2406 //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2407
2408 //if (psh == NULL) return 0;
2409
2410 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2411
2412
2413 /* determine the offset of the export function names */
2414
2415 pdwAddress = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfFunctions);
2416
2417 imageBase = (DWORD) GetImageBase (lpFile);
2418
2419 ordBase = ped->Base;
2420
2421 if (ped->NumberOfNames > 0)
2422 {
2423 pdwNames = (DWORD *)
2424 GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2425 pwOrd = (WORD *)
2426 GetActualAddress (lpFile, (DWORD) ped->AddressOfNameOrdinals);
2427 pdw1 = pdwAddress;
2428
2429 /* figure out how much memory to allocate for all strings */
2430 for (i = 0; i < (int) ped->NumberOfNames; i++)
2431 {
2432 nCnt += strlen ((char *)
2433 GetActualAddress (lpFile, *(DWORD *) pdwNames)) + 1 + 6;
2434 pdwNames++;
2435 }
2436 // get the number of unnamed functions
2437 for (i = 0; i < (int) ped->NumberOfFunctions; i++)
2438 if (*pdw1++)
2439 ntmp++;
2440 // add memory required to show unnamed functions.
2441 if (ntmp > (int) ped->NumberOfNames)
2442 nCnt += 18 * (ntmp - (int) ped->NumberOfNames);
2443
2444 /* allocate memory for function names */
2445
2446 *pszFunctions = (char *) calloc (nCnt, 1);
2447 pdwNames = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2448
2449 /* copy string pointer to buffer */
2450
2451 for (i = 0; i < (int) ped->NumberOfNames; i++)
2452 {
2453 pfns[(int) (*pwOrd) + ordBase] =
2454 (char *) GetActualAddress (lpFile, *(DWORD *) pdwNames);
2455 pdwNames++;
2456 pwOrd++;
2457 }
2458
2459 psz = *pszFunctions;
2460 }
2461
2462 for (i = ordBase; i < (int) ped->NumberOfFunctions + ordBase; i++)
2463 {
2464 if (*pdwAddress > 0)
2465 {
2466 *(DWORD *) psz = imageBase + *pdwAddress;
2467 psz += 4;
2468 *(WORD *) psz = (WORD) (i);
2469 psz += 2;
2470 if (pfns[i])
2471 {
2472 strcpy (psz, pfns[i]);
2473 psz += strlen (psz) + 1;
2474 }
2475 else
2476 {
2477 sprintf (buff, "ExpFn%04d()", enid++);
2478 strcpy (psz, buff);
2479 psz += 12;
2480 }
2481 enames++;
2482 }
2483 pdwAddress++;
2484 }
2485
2486 return enames;
2487
2488 }
2489
2490
2491 /* determine the total number of resources in the section */
2492 int WINAPI
2493 GetNumberOfResources (
2494 LPVOID lpFile)
2495 {
2496 PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType;
2497 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2498 int nCnt = 0, i;
2499
2500
2501 /* get root directory of resource tree */
2502 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2503 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2504 return 0;
2505
2506 /* set pointer to first resource type entry */
2507 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2508
2509 /* loop through all resource directory entry types */
2510 for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2511 {
2512 /* locate directory or each resource type */
2513 prdType = (PIMAGE_RESOURCE_DIRECTORY) ((int) prdRoot + (int) prde->OffsetToData);
2514
2515 /* mask off most significant bit of the data offset */
2516 prdType = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType ^ 0x80000000);
2517
2518 /* increment count of name'd and ID'd resources in directory */
2519 nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
2520
2521 /* increment to next entry */
2522 prde++;
2523 }
2524
2525 return nCnt;
2526 }
2527
2528
2529
2530 //
2531 // This function is rewritten by sang cho
2532 //
2533 //
2534 /* name each type of resource in the section */
2535 int WINAPI
2536 GetListOfResourceTypes (
2537 LPVOID lpFile,
2538 char **pszResTypes)
2539 {
2540 PIMAGE_RESOURCE_DIRECTORY prdRoot;
2541 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2542 char *pMem;
2543 char buff[32];
2544 int nCnt, i;
2545 DWORD prdeName;
2546
2547
2548 /* get root directory of resource tree */
2549 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2550 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2551 return 0;
2552
2553 /* allocate enuff space to cover all types */
2554 nCnt = prdRoot->NumberOfIdEntries * (MAXRESOURCENAME + 1);
2555 *pszResTypes = (char *) calloc (nCnt, 1);
2556 if ((pMem = *pszResTypes) == NULL)
2557 return 0;
2558
2559 /* set pointer to first resource type entry */
2560 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2561
2562 /* loop through all resource directory entry types */
2563 for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2564 {
2565 prdeName = prde->Name;
2566
2567 //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2568 // pMem += strlen (pMem) + 1;
2569 //
2570 // modified by ...................................Sang Cho..
2571 // I can't user M/S provied funcitons here so I have to figure out
2572 // how to do above functions. But I can settle down with the following
2573 // code, which works pretty good for me.
2574 //
2575 if (prdeName == 1)
2576 {
2577 strcpy (pMem, "RT_CURSOR");
2578 pMem += 10;
2579 }
2580 else if (prdeName == 2)
2581 {
2582 strcpy (pMem, "RT_BITMAP");
2583 pMem += 10;
2584 }
2585 else if (prdeName == 3)
2586 {
2587 strcpy (pMem, "RT_ICON ");
2588 pMem += 10;
2589 }
2590 else if (prdeName == 4)
2591 {
2592 strcpy (pMem, "RT_MENU ");
2593 pMem += 10;
2594 }
2595 else if (prdeName == 5)
2596 {
2597 strcpy (pMem, "RT_DIALOG");
2598 pMem += 10;
2599 }
2600 else if (prdeName == 6)
2601 {
2602 strcpy (pMem, "RT_STRING");
2603 pMem += 10;
2604 }
2605 else if (prdeName == 7)
2606 {
2607 strcpy (pMem, "RT_FONTDIR");
2608 pMem += 11;
2609 }
2610 else if (prdeName == 8)
2611 {
2612 strcpy (pMem, "RT_FONT ");
2613 pMem += 10;
2614 }
2615 else if (prdeName == 9)
2616 {
2617 strcpy (pMem, "RT_ACCELERATORS");
2618 pMem += 16;
2619 }
2620 else if (prdeName == 10)
2621 {
2622 strcpy (pMem, "RT_RCDATA");
2623 pMem += 10;
2624 }
2625 else if (prdeName == 11)
2626 {
2627 strcpy (pMem, "RT_MESSAGETABLE");
2628 pMem += 16;
2629 }
2630 else if (prdeName == 12)
2631 {
2632 strcpy (pMem, "RT_GROUP_CURSOR");
2633 pMem += 16;
2634 }
2635 else if (prdeName == 14)
2636 {
2637 strcpy (pMem, "RT_GROUP_ICON ");
2638 pMem += 16;
2639 }
2640 else if (prdeName == 16)
2641 {
2642 strcpy (pMem, "RT_VERSION");
2643 pMem += 11;
2644 }
2645 else if (prdeName == 17)
2646 {
2647 strcpy (pMem, "RT_DLGINCLUDE ");
2648 pMem += 16;
2649 }
2650 else if (prdeName == 19)
2651 {
2652 strcpy (pMem, "RT_PLUGPLAY ");
2653 pMem += 16;
2654 }
2655 else if (prdeName == 20)
2656 {
2657 strcpy (pMem, "RT_VXD ");
2658 pMem += 10;
2659 }
2660 else if (prdeName == 21)
2661 {
2662 strcpy (pMem, "RT_ANICURSOR ");
2663 pMem += 16;
2664 }
2665 else if (prdeName == 22)
2666 {
2667 strcpy (pMem, "RT_ANIICON");
2668 pMem += 11;
2669 }
2670 else if (prdeName == 0x2002)
2671 {
2672 strcpy (pMem, "RT_NEWBITMAP");
2673 pMem += 13;
2674 }
2675 else if (prdeName == 0x2004)
2676 {
2677 strcpy (pMem, "RT_NEWMENU");
2678 pMem += 11;
2679 }
2680 else if (prdeName == 0x2005)
2681 {
2682 strcpy (pMem, "RT_NEWDIALOG");
2683 pMem += 13;
2684 }
2685 else if (prdeName == 0x7fff)
2686 {
2687 strcpy (pMem, "RT_ERROR ");
2688 pMem += 10;
2689 }
2690 else
2691 {
2692 sprintf (buff, "RT_UNKNOWN:%08lX", prdeName);
2693 strcpy (pMem, buff);
2694 pMem += 20;
2695 }
2696 prde++;
2697 }
2698
2699 return prdRoot->NumberOfIdEntries;
2700 }
2701
2702
2703
2704 //
2705 // This function is written by sang cho
2706 // October 12, 1997
2707 //
2708 /* copy menu information */
2709 void WINAPI
2710 StrangeMenuFill (
2711 char **psz, // results
2712 WORD ** pMenu, // read-only
2713 int size)
2714 {
2715 WORD *pwd;
2716 WORD *ptr, *pmax;
2717
2718 pwd = *pMenu;
2719 pmax = (WORD *) ((DWORD) pwd + size);
2720 ptr = (WORD *) (*psz);
2721
2722 while (pwd < pmax)
2723 {
2724 *ptr++ = *pwd++;
2725 }
2726 *psz = (char *) ptr;
2727 *pMenu = pwd;
2728 }
2729
2730
2731
2732 //
2733 // This function is written by sang cho
2734 // October 1, 1997
2735 //
2736 /* obtain menu information */
2737 int WINAPI
2738 MenuScan (
2739 int *len,
2740 WORD ** pMenu)
2741 {
2742 //int num = 0;
2743 //int ndetails;
2744 WORD *pwd;
2745 WORD flag, flag1;
2746 WORD id, ispopup;
2747
2748
2749 pwd = *pMenu;
2750
2751 flag = *pwd; // so difficult to correctly code this so let's try this
2752
2753 pwd++;
2754 (*len) += 2; // flag store
2755
2756 if ((flag & 0x0010) == 0)
2757 {
2758 ispopup = flag;
2759 id = *pwd;
2760 pwd++;
2761 (*len) += 2; // id store
2762
2763 }
2764 else
2765 {
2766 ispopup = flag;
2767 }
2768
2769 while (*pwd)
2770 {
2771 (*len)++;
2772 pwd++;
2773 }
2774 (*len)++; // name and null character
2775
2776 pwd++; // skip double null
2777
2778 if ((flag & 0x0010) == 0) // normal node: done
2779
2780 {
2781 *pMenu = pwd;
2782 return (int) flag;
2783 }
2784 // popup node: need to go on...
2785 while (1)
2786 {
2787 *pMenu = pwd;
2788 flag1 = (WORD) MenuScan (len, pMenu);
2789 pwd = *pMenu;
2790 if (flag1 & 0x0080)
2791 break;
2792 }
2793 // fill # of details to num above
2794 //(*len) += 2;
2795 *pMenu = pwd;
2796 return flag;
2797 }
2798
2799
2800 //
2801 // This function is written by sang cho
2802 // October 2, 1997
2803 //
2804 /* copy menu information */
2805 int WINAPI
2806 MenuFill (
2807 char **psz,
2808 WORD ** pMenu)
2809 {
2810 //int num = 0;
2811 //int ndetails;
2812 char *ptr/*, *pTemp*/;
2813 WORD *pwd;
2814 WORD flag, flag1;
2815 WORD id/*, ispopup*/;
2816
2817 ptr = *psz;
2818 pwd = *pMenu;
2819 //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2820 flag = *pwd; // so difficult to correctly code this so let's try this
2821
2822 pwd++;
2823 if ((flag & 0x0010) == 0)
2824 {
2825 *(WORD *) ptr = flag; // flag store
2826
2827 ptr += 2;
2828 *(WORD *) ptr = id = *pwd; // id store
2829
2830 ptr += 2;
2831 pwd++;
2832 }
2833 else
2834 {
2835 *(WORD *) ptr = flag; // flag store
2836
2837 ptr += 2;
2838 }
2839
2840 while (*pwd) // name extract
2841
2842 {
2843 *ptr = *(char *) pwd;
2844 ptr++;
2845 pwd++;
2846 } //name and null character
2847
2848 *ptr = 0;
2849 ptr++;
2850 pwd++; // skip double null
2851
2852 if ((flag & 0x0010) == 0) // normal node: done
2853
2854 {
2855 *pMenu = pwd;
2856 *psz = ptr;
2857 return (int) flag;
2858 }
2859 //pTemp = ptr;
2860 //ptr += 2;
2861 // popup node: need to go on...
2862 while (1)
2863 {
2864 //num++;
2865 *pMenu = pwd;
2866 *psz = ptr;
2867 flag1 = (WORD) MenuFill (psz, pMenu);
2868 pwd = *pMenu;
2869 ptr = *psz;
2870 if (flag1 & 0x0080)
2871 break;
2872 }
2873 // fill # of details to num above
2874 //*(WORD *)pTemp = (WORD)num;
2875 *pMenu = pwd;
2876 *psz = ptr;
2877 return flag;
2878 }
2879
2880
2881 //
2882 //==============================================================================
2883 // The following program is based on preorder-tree-traversal.
2884 // once you understand how to traverse.....
2885 // the rest is pretty straight forward.
2886 // still we need to scan it first and fill it next time.
2887 // and finally we can print it.
2888 //
2889 // This function is written by sang cho
2890 // September 29, 1997
2891 // revised october 2, 1997
2892 // revised october 12, 1997
2893 // ..............................................................................
2894 // ------------------------------------------------------------------------------
2895 // I use same structure - which is used in P.E. programs - for my reporting.
2896 // So, my structure is as follows:
2897 // # of menu name is stored else where ( in directory I suppose )
2898 // supermenuname null terminated string, only ascii is considered.
2899 // flag tells : node is a leaf or a internal node.
2900 // popupname null terminated string
2901 //
2902 // flag normal menu flag (leaf node)
2903 // id normal menu id
2904 // name normal menu name
2905 // or or
2906 // flag popup menu flag (internal node)
2907 // popupname popup menu name
2908 //
2909 // flag it may folows
2910 // id normal menu id
2911 // name normal menu name
2912 // or or
2913 // flag popup menu
2914 // popupname popup menu name
2915 // .........
2916 // it goes on like this,
2917 // but usually, it only goes a few steps,...
2918 // ------------------------------------------------------------------------------
2919 /* scan menu and copy menu */
2920 int WINAPI
2921 GetContentsOfMenu (
2922 LPVOID lpFile,
2923 char **pszResTypes)
2924 {
2925 PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage;
2926 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1;
2927 PIMAGE_RESOURCE_DIR_STRING_U pMenuName;
2928 PIMAGE_RESOURCE_DATA_ENTRY prData;
2929 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
2930 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE);
2931 PIMAGE_MENU_HEADER pMenuHeader;
2932 //PIMAGE_POPUP_MENU_ITEM pPopup;
2933 WORD* pPopup;
2934 //PIMAGE_NORMAL_MENU_ITEM pNormal;
2935 char buff[32];
2936 int /*nCnt = 0,*/ i, j;
2937 //int num = 0;
2938 int size;
2939 int sLength, nMenus;
2940 WORD flag;
2941 WORD *pwd;
2942 //DWORD prdeName;
2943 //DWORD dwBase; obsolete
2944 char *pMem/*, *pTemp*/;
2945 //BOOL isStrange = FALSE;
2946
2947
2948 /* get root directory of resource tree */
2949 if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2950 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2951 return 0;
2952
2953 /* set pointer to first resource type entry */
2954 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2955 ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
2956
2957 for (i = 0; i < prdType->NumberOfIdEntries; i++)
2958 {
2959 if (prde->Name == RT_MENU)
2960 break;
2961 prde++;
2962 }
2963 if (prde->Name != RT_MENU)
2964 return 0;
2965
2966 prdName = (PIMAGE_RESOURCE_DIRECTORY)
2967 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2968 if (prdName == NULL)
2969 return 0;
2970
2971 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2972 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
2973
2974 // sometimes previous code tells you lots of things hidden underneath
2975 // I wish I could save all the revisions I made ... but again .... sigh.
2976 // october 12, 1997 sang
2977 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2978
2979 nMenus = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
2980 sLength = 0;
2981
2982 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
2983 {
2984 pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
2985 ((DWORD) prdType + (prde->Name ^ 0x80000000));
2986 sLength += pMenuName->Length + 1;
2987
2988 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
2989 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2990 if (prdLanguage == NULL)
2991 continue;
2992
2993 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2994 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
2995
2996 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
2997 ((DWORD) prdType + prde1->OffsetToData);
2998 if (prData == NULL)
2999 continue;
3000
3001 pMenuHeader = (PIMAGE_MENU_HEADER)
3002 GetActualAddress (lpFile, prData->OffsetToData);
3003
3004 //
3005 // normally wVersion and cbHeaderSize should be zero
3006 // but if it is not then nothing is known to us...
3007 // so let's do our best ... namely guessing .... and trying ....
3008 // ... and suffering ...
3009 // it gave me many sleepless (not exactly but I like to say this) nights.
3010 //
3011
3012 // strange case
3013 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3014 {
3015 //isStrange = TRUE;
3016 pwd = (WORD *) ((DWORD) pMenuHeader + 16);
3017 size = prData->Size;
3018 // expect to return the length needed to report.
3019 // sixteen more bytes to do something
3020 sLength += 16 + size;
3021 //StrangeMenuScan (&sLength, &pwd, size);
3022 }
3023 // normal case
3024 else
3025 {
3026 pPopup = (WORD*)
3027 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3028 while (1)
3029 {
3030 flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3031 if (flag & 0x0080)
3032 break;
3033 }
3034 }
3035 prde++;
3036 }
3037 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3038 {
3039 sLength += 12;
3040
3041 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3042 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3043 if (prdLanguage == NULL)
3044 continue;
3045
3046 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3047 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3048
3049 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3050 ((DWORD) prdType + prde1->OffsetToData);
3051 if (prData == NULL)
3052 continue;
3053
3054 pMenuHeader = (PIMAGE_MENU_HEADER)
3055 GetActualAddress (lpFile, prData->OffsetToData);
3056 // strange case
3057 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3058 {
3059 pwd = (WORD *) ((DWORD) pMenuHeader + 16);
3060 size = prData->Size;
3061 // expect to return the length needed to report.
3062 // sixteen more bytes to do something
3063 sLength += 16 + size;
3064 //StrangeMenuScan (&sLength, &pwd, size);
3065 }
3066 // normal case
3067 else
3068 {
3069 pPopup = (WORD*)
3070 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3071 while (1)
3072 {
3073 flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3074 if (flag & 0x0080)
3075 break;
3076 }
3077 }
3078 prde++;
3079 }
3080 //
3081 // allocate memory for menu names
3082 //
3083 *pszResTypes = (char *) calloc (sLength, 1);
3084
3085 pMem = *pszResTypes;
3086 //
3087 // and start all over again
3088 //
3089 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3090 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3091
3092 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3093 {
3094 pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
3095 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3096
3097
3098 for (j = 0; j < pMenuName->Length; j++)
3099 *pMem++ = (char) (pMenuName->NameString[j]);
3100 *pMem = 0;
3101 pMem++;
3102
3103
3104 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3105 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3106 if (prdLanguage == NULL)
3107 continue;
3108
3109 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3110 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3111
3112 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3113 ((DWORD) prdType + prde1->OffsetToData);
3114 if (prData == NULL)
3115 continue;
3116
3117 pMenuHeader = (PIMAGE_MENU_HEADER)
3118 GetActualAddress (lpFile, prData->OffsetToData);
3119 // strange case
3120 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3121 {
3122 pwd = (WORD *) ((DWORD) pMenuHeader);
3123 size = prData->Size;
3124 strcpy (pMem, ":::::::::::");
3125 pMem += 12;
3126 *(int *) pMem = size;
3127 pMem += 4;
3128 StrangeMenuFill (&pMem, &pwd, size);
3129 }
3130 // normal case
3131 else
3132 {
3133 pPopup = (WORD*)
3134 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3135 while (1)
3136 {
3137 flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3138 if (flag & 0x0080)
3139 break;
3140 }
3141 }
3142 prde++;
3143 }
3144 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3145 {
3146
3147 sprintf (buff, "MenuId_%04lX", (prde->Name));
3148 strcpy (pMem, buff);
3149 pMem += strlen (buff) + 1;
3150
3151 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3152 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3153 if (prdLanguage == NULL)
3154 continue;
3155
3156 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3157 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3158
3159 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3160 ((DWORD) prdType + prde1->OffsetToData);
3161 if (prData == NULL)
3162 continue;
3163
3164 pMenuHeader = (PIMAGE_MENU_HEADER)
3165 GetActualAddress (lpFile, prData->OffsetToData);
3166 // strange case
3167 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3168 {
3169 pwd = (WORD *) ((DWORD) pMenuHeader);
3170 size = prData->Size;
3171 strcpy (pMem, ":::::::::::");
3172 pMem += 12;
3173 *(int *) pMem = size;
3174 pMem += 4;
3175 StrangeMenuFill (&pMem, &pwd, size);
3176 }
3177 // normal case
3178 else
3179 {
3180 pPopup = (WORD*)
3181 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3182 while (1)
3183 {
3184 flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3185 if (flag & 0x0080)
3186 break;
3187 }
3188 }
3189 prde++;
3190 }
3191
3192 return nMenus;
3193 }
3194
3195
3196 //
3197 // This function is written by sang cho
3198 // October 12, 1997
3199 //
3200 /* print contents of menu */
3201 int WINAPI
3202 PrintStrangeMenu (
3203 char **psz)
3204 {
3205
3206 //int i, j, k, l;
3207 int num;
3208 //WORD flag1, flag2;
3209 //char buff[128];
3210 char *ptr, *pmax;
3211
3212 //return dumpMenu (psz, size);
3213
3214 ptr = *psz;
3215
3216 if (strncmp (ptr, ":::::::::::", 11) != 0)
3217 {
3218 printf ("\n#### I don't know why!!!");
3219 dumpMenu (psz, 1024);
3220 exit (0);
3221 }
3222
3223 ptr += 12;
3224 num = *(int *) ptr;
3225 ptr += 4;
3226 pmax = ptr + num;
3227
3228 *psz = ptr;
3229 return dumpMenu (psz, num);
3230
3231 // I will write some code later...
3232
3233 }
3234
3235
3236
3237
3238 //
3239 // This function is written by sang cho
3240 // October 2, 1997
3241 //
3242 /* print contents of menu */
3243 int WINAPI
3244 PrintMenu (
3245 int indent,
3246 char **psz)
3247 {
3248
3249 int /*i, */ j, k, l;
3250 WORD id /*, num */ ;
3251 WORD flag;
3252 char buff[128];
3253 char *ptr;
3254
3255
3256 ptr = *psz;
3257 //num = *(WORD *)ptr;
3258 //ptr += 2;
3259 while (1)
3260 {
3261 flag = *(WORD *) ptr;
3262 if (flag & 0x0010) // flag == popup
3263
3264 {
3265 printf ("\n\n");
3266 for (j = 0; j < indent; j++)
3267 printf (" ");
3268 ptr += 2;
3269 printf ("%s {Popup}\n", ptr);
3270 ptr += strlen (ptr) + 1;
3271 *psz = ptr;
3272 PrintMenu (indent + 5, psz);
3273 ptr = *psz;
3274 }
3275 else // ispopup == 0
3276
3277 {
3278 printf ("\n");
3279 for (j = 0; j < indent; j++)
3280 printf (" ");
3281 ptr += 2;
3282 id = *(WORD *) ptr;
3283 ptr += 2;
3284 strcpy (buff, ptr);
3285 l = strlen (ptr);
3286 ptr += l + 1;
3287 if (strchr (buff, 0x09) != NULL)
3288 {
3289 for (k = 0; k < l; k++)
3290 if (buff[k] == 0x09)
3291 break;
3292 for (j = 0; j < l - k; j++)
3293 buff[31 - j] = buff[l - j];
3294 for (j = k; j < 32 + k - l; j++)
3295 buff[j] = 32;
3296 }
3297 if (strchr (buff, 0x08) != NULL)
3298 {
3299 for (k = 0; k < l; k++)
3300 if (buff[k] == 0x08)
3301 break;
3302 for (j = 0; j < l - k; j++)
3303 buff[31 - j] = buff[l - j];
3304 for (j = k; j < 32 + k - l; j++)
3305 buff[j] = 32;
3306 }
3307 printf ("%s", buff);
3308 l = strlen (buff);
3309 for (j = l; j < 32; j++)
3310 printf (" ");
3311 printf ("[ID=%04Xh]", id);
3312 *psz = ptr;
3313 }
3314 if (flag & 0x0080)
3315 break;
3316 }
3317 return 0;
3318 }
3319
3320
3321 //
3322 // This function is written by sang cho
3323 // October 2, 1997
3324 //
3325 /* the format of menu is not known so I'll do my best */
3326 int WINAPI
3327 dumpMenu (
3328 char **psz,
3329 int size)
3330 {
3331
3332 int i, j, k, n, l, c;
3333 char buff[32];
3334 char *ptr, *pmax;
3335
3336 ptr = *psz;
3337 pmax = ptr + size;
3338 for (i = 0; i < (size / 16) + 1; i++)
3339 {
3340 n = 0;
3341 for (j = 0; j < 16; j++)
3342 {
3343 c = (int) (*ptr);
3344 if (c < 0)
3345 c += 256;
3346 buff[j] = c;
3347 printf ("%02X", c);
3348 ptr++;
3349 if (ptr >= pmax)
3350 break;
3351 n++;
3352 if (n % 4 == 0)
3353 printf (" ");
3354 }
3355 n++;
3356 if (n % 4 == 0)
3357 printf (" ");
3358 l = j;
3359 j++;
3360 for (; j < 16; j++)
3361 {
3362 n++;
3363 if (n % 4 == 0)
3364 printf (" ");
3365 else
3366 printf (" ");
3367 }
3368 printf (" ");
3369 for (k = 0; k < l; k++)
3370 if (isprint (c = buff[k]))
3371 printf ("%c", c);
3372 else
3373 printf (".");
3374 printf ("\n");
3375 if (ptr >= pmax)
3376 break;
3377 }
3378
3379 *psz = ptr;
3380 return 0;
3381 }
3382
3383
3384
3385
3386 //
3387 // This function is written by sang cho
3388 // October 13, 1997
3389 //
3390 /* scan dialog box and copy dialog box */
3391 int WINAPI
3392 GetContentsOfDialog (
3393 LPVOID lpFile,
3394 char **pszResTypes)
3395 {
3396 PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage;
3397 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1;
3398 PIMAGE_RESOURCE_DIR_STRING_U pDialogName;
3399 PIMAGE_RESOURCE_DATA_ENTRY prData;
3400 PIMAGE_DIALOG_HEADER pDialogHeader;
3401 //PIMAGE_CONTROL_DATA pControlData;
3402 char buff[32];
3403 int /*nCnt = 0,*/ i, j;
3404 //int num = 0;
3405 int size;
3406 int sLength, nDialogs;
3407 //WORD flag;
3408 WORD *pwd;
3409 //DWORD prdeName;
3410 char *pMem/*, *pTemp*/;
3411 //BOOL isStrange = FALSE;
3412
3413
3414 /* get root directory of resource tree */
3415 if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
3416 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
3417 return 0;
3418
3419 /* set pointer to first resource type entry */
3420 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3421 ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
3422
3423 for (i = 0; i < prdType->NumberOfIdEntries; i++)
3424 {
3425 if (prde->Name == RT_DIALOG)
3426 break;
3427 prde++;
3428 }
3429 if (prde->Name != RT_DIALOG)
3430 return 0;
3431
3432 prdName = (PIMAGE_RESOURCE_DIRECTORY)
3433 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3434 if (prdName == NULL)
3435 return 0;
3436
3437 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3438 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3439
3440
3441 nDialogs = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
3442 sLength = 0;
3443
3444 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3445 {
3446 pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3447 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3448 sLength += pDialogName->Length + 1;
3449
3450 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3451 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3452 if (prdLanguage == NULL)
3453 continue;
3454
3455 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3456 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3457
3458 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3459 ((DWORD) prdType + prde1->OffsetToData);
3460 if (prData == NULL)
3461 continue;
3462
3463 size = prData->Size;
3464 sLength += 4 + size;
3465 prde++;
3466 }
3467 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3468 {
3469 sLength += 14;
3470
3471 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3472 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3473 if (prdLanguage == NULL)
3474 continue;
3475
3476 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3477 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3478
3479 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3480 ((DWORD) prdType + prde1->OffsetToData);
3481 if (prData == NULL)
3482 continue;
3483
3484 size = prData->Size;
3485 sLength += 4 + size;
3486 prde++;
3487 }
3488 //
3489 // allocate memory for menu names
3490 //
3491 *pszResTypes = (char *) calloc (sLength, 1);
3492
3493 pMem = *pszResTypes;
3494 //
3495 // and start all over again
3496 //
3497 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3498 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3499
3500 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3501 {
3502 pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3503 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3504
3505
3506 for (j = 0; j < pDialogName->Length; j++)
3507 *pMem++ = (char) (pDialogName->NameString[j]);
3508 *pMem = 0;
3509 pMem++;
3510
3511
3512 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3513 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3514 if (prdLanguage == NULL)
3515 continue;
3516
3517 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3518 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3519
3520 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3521 ((DWORD) prdType + prde1->OffsetToData);
3522 if (prData == NULL)
3523 continue;
3524
3525 pDialogHeader = (PIMAGE_DIALOG_HEADER)
3526 GetActualAddress (lpFile, prData->OffsetToData);
3527
3528
3529
3530 pwd = (WORD *) ((DWORD) pDialogHeader);
3531 size = prData->Size;
3532 *(int *) pMem = size;
3533 pMem += 4;
3534 StrangeMenuFill (&pMem, &pwd, size);
3535
3536 prde++;
3537 }
3538 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3539 {
3540
3541 sprintf (buff, "DialogId_%04lX", (prde->Name));
3542 strcpy (pMem, buff);
3543 pMem += strlen (buff) + 1;
3544
3545 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3546 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3547 if (prdLanguage == NULL)
3548 {
3549 printf ("\nprdLanguage = NULL");
3550 exit (0);
3551 }
3552
3553 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3554 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3555
3556 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3557 ((DWORD) prdType + prde1->OffsetToData);
3558 if (prData == NULL)
3559 {
3560 printf ("\nprData = NULL");
3561 exit (0);
3562 }
3563
3564 pDialogHeader = (PIMAGE_DIALOG_HEADER)
3565 GetActualAddress (lpFile, prData->OffsetToData);
3566
3567
3568 pwd = (WORD *) ((DWORD) pDialogHeader);
3569 size = prData->Size;
3570 *(int *) pMem = size;
3571 pMem += 4;
3572 StrangeMenuFill (&pMem, &pwd, size);
3573
3574 prde++;
3575 }
3576
3577 return nDialogs;
3578 }
3579
3580
3581 //
3582 // This function is written by sang cho
3583 // October 14, 1997
3584 //
3585 /* print contents of dialog */
3586 void WINAPI
3587 PrintNameOrOrdinal (
3588 char **psz)
3589 {
3590 char *ptr;
3591
3592 ptr = *psz;
3593 if (*(WORD *) ptr == 0xFFFF)
3594 {
3595 ptr += 2;
3596 printf ("%04X", *(WORD *) ptr);
3597 ptr += 2;
3598 }
3599 else
3600 {
3601 printf ("%c", '"');
3602 while (*(WORD *) ptr)
3603 {
3604 printf ("%c", *ptr);
3605 ptr += 2;
3606 }
3607 ptr += 2;
3608 printf ("%c", '"');
3609 }
3610 *psz = ptr;
3611 }
3612
3613
3614 //
3615 // This function is written by sang cho
3616 // October 14, 1997
3617 //
3618 /* print contents of dialog */
3619 void WINAPI
3620 PrintDialog (
3621 char **psz)
3622 {
3623 int i/*, j, k, l, n, c*/;
3624 int num, size;
3625 DWORD flag;
3626 WORD class;
3627 //char buff[32];
3628 char *ptr, *pmax;
3629 BOOL isStrange = FALSE;
3630
3631 ptr = *psz;
3632 size = *(int *) ptr;
3633 ptr += 4;
3634 pmax = ptr + size;
3635
3636 // IStype of Dialog Header
3637 flag = *(DWORD *) ptr;
3638 //
3639 // check if flag is right or not
3640 // it has been observed that some dialog information is strange
3641 // and extra work is needed to fix that ... so let's try something
3642 //
3643
3644 if ((flag & 0xFFFF0000) == 0xFFFF0000)
3645 {
3646 flag = *(DWORD *) (ptr + 12);
3647 num = *(short *) (ptr + 16);
3648 isStrange = TRUE;
3649 ptr += 26;
3650 }
3651 else
3652 {
3653 num = *(short *) (ptr + 8);
3654 ptr += 18;
3655 }
3656 printf (", # of Controls=%03d, Caption:%c", num, '"');
3657
3658 // Menu name
3659 if (*(WORD *) ptr == 0xFFFF)
3660 ptr += 4; // ordinal
3661
3662 else
3663 {
3664 while (*(WORD *) ptr)
3665 ptr += 2;
3666 ptr += 2;
3667 } // name
3668
3669 // Class name
3670 if (*(WORD *) ptr == 0xFFFF)
3671 ptr += 4; // ordinal
3672
3673 else
3674 {
3675 while (*(WORD *) ptr)
3676 ptr += 2;
3677 ptr += 2;
3678 } // name
3679
3680 // Caption
3681 while (*(WORD *) ptr)
3682 {
3683 printf ("%c", *ptr);
3684 ptr += 2;
3685 }
3686 ptr += 2;
3687 printf ("%c", '"');
3688
3689 // FONT present
3690 if (flag & 0x00000040)
3691 {
3692 if (isStrange)
3693 ptr += 6;
3694 else
3695 ptr += 2; // FONT size
3696
3697 while (*(WORD *) ptr)
3698 ptr += 2; // WCHARs
3699
3700 ptr += 2; // double null
3701
3702 }
3703
3704 // strange case adjust
3705 if (isStrange)
3706 ptr += 8;
3707
3708 // DWORD padding
3709 if ((ptr - *psz) % 4)
3710 ptr += 4 - ((ptr - *psz) % 4);
3711
3712 // start reporting .. finally
3713 for (i = 0; i < num; i++)
3714 {
3715 flag = *(DWORD *) ptr;
3716 if (isStrange)
3717 ptr += 14;
3718 else
3719 ptr += 16;
3720 printf ("\n Control::%03d - ID:", i + 1);
3721
3722 // Control ID
3723 printf ("%04X, Class:", *(WORD *) ptr);
3724 ptr += 2;
3725
3726 // Control Class
3727 if (*(WORD *) ptr == 0xFFFF)
3728 {
3729 ptr += 2;
3730 class = *(WORD *) ptr;
3731 ptr += 2;
3732 switch (class)
3733 {
3734 case 0x80:
3735 printf ("BUTTON ");
3736 break;
3737 case 0x81:
3738 printf ("EDIT ");
3739 break;
3740 case 0x82:
3741 printf ("STATIC ");
3742 break;
3743 case 0x83:
3744 printf ("LISTBOX ");
3745 break;
3746 case 0x84:
3747 printf ("SCROLLBAR");
3748 break;
3749 case 0x85:
3750 printf ("COMBOBOX ");
3751 break;
3752 default:
3753 printf ("%04X ", class);
3754 break;
3755 }
3756 }
3757 else
3758 PrintNameOrOrdinal (&ptr);
3759
3760 printf (" Text:");
3761
3762 // Text
3763 PrintNameOrOrdinal (&ptr);
3764
3765 // nExtraStuff
3766 ptr += 2;
3767
3768 // strange case adjust
3769 if (isStrange)
3770 ptr += 8;
3771
3772 // DWORD padding
3773 if ((ptr - *psz) % 4)
3774 ptr += 4 - ((ptr - *psz) % 4);
3775 }
3776
3777 /*
3778 ptr = *psz;
3779 printf("\n");
3780
3781 for (i=0; i<(size/16)+1; i++)
3782 {
3783 n = 0;
3784 for (j=0; j<16; j++)
3785 {
3786 c = (int)(*ptr);
3787 if (c<0) c+=256;
3788 buff[j] = c;
3789 printf ("%02X",c);
3790 ptr++;
3791 if (ptr >= pmax) break;
3792 n++;
3793 if (n%4 == 0) printf (" ");
3794 }
3795 n++; if (n%4 == 0) printf (" ");
3796 l = j;
3797 j++;
3798 for (; j<16; j++)
3799 { n++; if (n%4 == 0) printf (" "); else printf (" "); }
3800 printf (" ");
3801 for (k=0; k<l; k++)
3802 if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3803 printf ("\n");
3804 if (ptr >= pmax) break;
3805 }
3806 */
3807
3808 *psz = pmax;
3809
3810 }
3811
3812
3813
3814
3815
3816
3817 /* function indicates whether debug info has been stripped from file */
3818 BOOL WINAPI
3819 IsDebugInfoStripped (
3820 LPVOID lpFile)
3821 {
3822 PIMAGE_FILE_HEADER pfh;
3823
3824 pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
3825
3826 return (pfh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
3827 }
3828
3829
3830
3831
3832 /* retrieve the module name from the debug misc. structure */
3833 int WINAPI
3834 RetrieveModuleName (
3835 LPVOID lpFile,
3836 char **pszModule)
3837 {
3838
3839 PIMAGE_DEBUG_DIRECTORY pdd;
3840 PIMAGE_DEBUG_MISC pdm = NULL;
3841 int nCnt;
3842
3843 if (!(pdd = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_DEBUG)))
3844 return 0;
3845
3846 while (pdd->SizeOfData)
3847 {
3848 if (pdd->Type == IMAGE_DEBUG_TYPE_MISC)
3849 {
3850 pdm = (PIMAGE_DEBUG_MISC) ((DWORD) pdd->PointerToRawData + (DWORD) lpFile);
3851 *pszModule = (char *) calloc ((nCnt = (strlen ((char *)pdm->Data))) + 1, 1);
3852 // may need some unicode business here...above
3853 bcopy (pdm->Data, *pszModule, nCnt);
3854
3855 break;
3856 }
3857
3858 pdd++;
3859 }
3860
3861 if (pdm != NULL)
3862 return nCnt;
3863 else
3864 return 0;
3865 }
3866
3867
3868
3869
3870
3871 /* determine if this is a valid debug file */
3872 BOOL WINAPI
3873 IsDebugFile (
3874 LPVOID lpFile)
3875 {
3876 PIMAGE_SEPARATE_DEBUG_HEADER psdh;
3877
3878 psdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3879
3880 return (psdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE);
3881 }
3882
3883
3884
3885
3886 /* copy separate debug header structure from debug file */
3887 BOOL WINAPI
3888 GetSeparateDebugHeader (
3889 LPVOID lpFile,
3890 PIMAGE_SEPARATE_DEBUG_HEADER psdh)
3891 {
3892 PIMAGE_SEPARATE_DEBUG_HEADER pdh;
3893
3894 pdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3895
3896 if (pdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
3897 {
3898 bcopy ((LPVOID) pdh, (LPVOID) psdh, sizeof (IMAGE_SEPARATE_DEBUG_HEADER));
3899 return TRUE;
3900 }
3901
3902 return FALSE;
3903 }
3904
3905 //
3906 // I tried to immitate the output of w32dasm disassembler.
3907 // which is a pretty good program.
3908 // but I am disappointed with this program and I myself
3909 // am writting a disassembler.
3910 // This PEdump program is a byproduct of that project.
3911 // so enjoy this program and I hope we will have a little more
3912 // knowledge on windows programming world.
3913 // .... sang cho
3914
3915 #define MAXSECTIONNUMBER 16
3916 #define MAXNAMESTRNUMBER 40
3917 int
3918 main (
3919 int argc,
3920 char **argv
3921 )
3922 {
3923 DWORD fileType;
3924 LPVOID lpFile;
3925 FILE *my_fp;
3926 IMAGE_DOS_HEADER dosHdr;
3927 PIMAGE_FILE_HEADER pfh;
3928 PIMAGE_OPTIONAL_HEADER poh;
3929 PIMAGE_SECTION_HEADER psh;
3930 //IMAGE_SECTION_HEADER idsh;
3931 IMAGE_SECTION_HEADER shdr[MAXSECTIONNUMBER];
3932 //PIMAGE_IMPORT_MODULE_DIRECTORY pid;
3933
3934 int nSections; // number of sections
3935
3936 int nResources; // number of resources
3937
3938 int nMenus; // number of menus
3939
3940 int nDialogs; // number of dialogs
3941
3942 int nImportedModules; // number of imported modules
3943
3944 int nFunctions; // number of functions in the imported module
3945
3946 int nExportedFunctions; // number of exported funcions
3947
3948 int imageBase;
3949 int entryPoint;
3950
3951 int i, j, /*k,*/ n;
3952 //int mnsize;
3953 //int nCnt;
3954 //int nSize;
3955 int fsize;
3956 char *pnstr;
3957 char *pst;
3958 char *piNameBuff; // import module name buffer
3959
3960 char *pfNameBuff; // import functions in the module name buffer
3961
3962 char *peNameBuff; // export function name buffer
3963
3964 char *pmNameBuff; // menu name buffer
3965
3966 char *pdNameBuff; // dialog name buffer
3967
3968 /*
3969 * Check user arguments.
3970 */
3971 if (2 == argc)
3972 {
3973 my_fp = fopen (argv[1], "rb");
3974 if (my_fp == NULL)
3975 {
3976 printf (
3977 "%s: can not open input file \"%s\".\n",
3978 argv[0],
3979 argv[1]
3980 );
3981 exit (0);
3982 }
3983 }
3984 else
3985 {
3986 printf (
3987 "%s - PE/COFF file dumper\n"
3988 "Copyright (c) 1993 Randy Kath (MSDN Technology Group)\n"
3989 "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)\n"
3990 "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)\n\n",
3991 argv[0]
3992 );
3993 printf (
3994 "usage: %s input_file_name\n",
3995 argv[0]
3996 );
3997 exit (0);
3998 }
3999 /*
4000 * Get input file's size.
4001 */
4002 /* argv [0], */
4003 fseek (my_fp, 0L, SEEK_END);
4004 fsize = ftell (my_fp);
4005 rewind (my_fp);
4006 /*
4007 * Buffer the file in memory.
4008 */
4009 lpFile = (void *) calloc (fsize, 1);
4010 if (lpFile == NULL)
4011 {
4012 printf (
4013 "%s: can not allocate memory.\n",
4014 argv[0]
4015 );
4016 exit (0);
4017 }
4018 /*
4019 * --- Start of report ---
4020 */
4021 printf ("\n\nDump of file: %s\n\n", argv[1]);
4022
4023 n = fread (lpFile, fsize, 1, my_fp);
4024
4025 if (n == -1)
4026 {
4027 printf (
4028 "%s: failed to read the file \"%s\".\n",
4029 argv[0],
4030 argv[1]
4031 );
4032 exit (0);
4033 }
4034
4035 GetDosHeader (lpFile, &dosHdr);
4036
4037 if ((WORD) IMAGE_DOS_SIGNATURE == dosHdr.e_magic)
4038 {
4039 if ((dosHdr.e_lfanew > 4096)
4040 || (dosHdr.e_lfanew < 64)
4041 )
4042 {
4043 printf (
4044 "%s: This file is not in PE format; it looks like in DOS format.\n",
4045 argv[0]
4046 );
4047 exit (0);
4048 }
4049 }
4050 else
4051 {
4052 printf (
4053 "%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4054 argv[0],
4055 dosHdr.e_magic
4056 );
4057 exit (0);
4058 }
4059
4060 fileType = ImageFileType (lpFile);
4061
4062 if (fileType != IMAGE_NT_SIGNATURE)
4063 {
4064 printf (
4065 "%s: This file is not in PE format (magic = 0x%08lx).\n",
4066 argv[0],
4067 fileType
4068 );
4069 exit (0);
4070 }
4071
4072 //=====================================
4073 // now we can really start processing
4074 //=====================================
4075
4076 pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
4077
4078 poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
4079
4080 psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
4081
4082 nSections = pfh->NumberOfSections;
4083
4084 imageBase = poh->ImageBase;
4085
4086 entryPoint = poh->AddressOfEntryPoint;
4087
4088 if (psh == NULL)
4089 return 0;
4090
4091 /* store section headers */
4092
4093 for (i = 0;
4094 i < nSections;
4095 i++
4096 )
4097 {
4098 shdr[i] = *psh++;
4099 }
4100 /*
4101 * Get Code offset and size,
4102 * Data offset and size.
4103 */
4104 for (i = 0;
4105 i < nSections;
4106 i++
4107 )
4108 {
4109 if (poh->BaseOfCode == shdr[i].VirtualAddress)
4110 {
4111 printf (
4112 "Code Offset = %08lX, Code Size = %08lX \n",
4113 shdr[i].PointerToRawData,
4114 shdr[i].SizeOfRawData
4115 );
4116 }
4117 if (((shdr[i].Characteristics) & 0xC0000040) == 0xC0000040)
4118 {
4119 printf (
4120 "Data Offset = %08lX, Data Size = %08lX \n",
4121 shdr[i].PointerToRawData,
4122 shdr[i].SizeOfRawData
4123 );
4124 break;
4125 }
4126 }
4127
4128 printf ("\n");
4129
4130 printf (
4131 "Number of Objects = %04d (dec), Imagebase = %08Xh \n",
4132 nSections,
4133 imageBase
4134 );
4135 /*
4136 * Object name alignment.
4137 */
4138 for (i = 0;
4139 i < nSections;
4140 i++
4141 )
4142 {
4143 for (j = 0;
4144 j < 7;
4145 j++
4146 )
4147 {
4148 if (shdr[i].Name[j] == 0)
4149 {
4150 shdr[i].Name[j] = 32;
4151 }
4152 }
4153 shdr[i].Name[7] = 0;
4154 }
4155 for (i = 0; i < nSections; i++)
4156 printf ("\n Object%02d: %8s RVA: %08lX Offset: %08lX Size: %08lX Flags: %08lX ",
4157 i + 1, shdr[i].Name, shdr[i].VirtualAddress, shdr[i].PointerToRawData,
4158 shdr[i].SizeOfRawData, shdr[i].Characteristics);
4159 /*
4160 * Get List of Resources.
4161 */
4162 nResources = GetListOfResourceTypes (lpFile, &pnstr);
4163 pst = pnstr;
4164 printf ("\n");
4165 printf ("\n+++++++++++++++++++ RESOURCE INFORMATION +++++++++++++++++++");
4166 printf ("\n");
4167 if (nResources == 0)
4168 printf ("\n There are no Resources in This Application.\n");
4169 else
4170 {
4171 printf ("\nNumber of Resource Types = %4d (decimal)\n", nResources);
4172 for (i = 0; i < nResources; i++)
4173 {
4174 printf ("\n Resource Type %03d: %s", i + 1, pst);
4175 pst += strlen ((char *) (pst)) + 1;
4176 }
4177 free ((void *) pnstr);
4178
4179 printf ("\n");
4180 printf ("\n+++++++++++++++++++ MENU INFORMATION +++++++++++++++++++");
4181 printf ("\n");
4182
4183 nMenus = GetContentsOfMenu (lpFile, &pmNameBuff);
4184
4185 if (nMenus == 0)
4186 {
4187 printf ("\n There are no Menus in This Application.\n");
4188 }
4189 else
4190 {
4191 pst = pmNameBuff;
4192 printf ("\nNumber of Menus = %4d (decimal)", nMenus);
4193
4194 //dumpMenu(&pst, 8096);
4195 for (i = 0; i < nMenus; i++)
4196 {
4197 // menu ID print
4198 printf ("\n\n%s", pst);
4199 pst += strlen (pst) + 1;
4200 printf ("\n-------------");
4201 if (strncmp (pst, ":::::::::::", 11) == 0)
4202 {
4203 printf ("\n");
4204 PrintStrangeMenu (&pst);
4205 }
4206 else
4207 {
4208 PrintMenu (6, &pst);
4209 }
4210 //else PrintStrangeMenu(&pst);
4211 }
4212 free ((void *) pmNameBuff);
4213 printf ("\n");
4214 }
4215
4216 printf ("\n");
4217 printf ("\n+++++++++++++++++ DIALOG INFORMATION +++++++++++++++++++");
4218 printf ("\n");
4219
4220 nDialogs = GetContentsOfDialog (lpFile, &pdNameBuff);
4221
4222 if (nDialogs == 0)
4223 {
4224 printf ("\n There are no Dialogs in This Application.\n");
4225 }
4226 else
4227 {
4228 pst = pdNameBuff;
4229 printf ("\nNumber of Dialogs = %4d (decimal)", nDialogs);
4230
4231 printf ("\n");
4232
4233 for (i = 0; i < nDialogs; i++)
4234 {
4235 // Dialog ID print
4236 printf ("\nName: %s", pst);
4237 pst += strlen (pst) + 1;
4238 PrintDialog (&pst);
4239 }
4240 free ((void *) pdNameBuff);
4241 printf ("\n");
4242 }
4243 }
4244
4245 printf ("\n+++++++++++++++++++ IMPORTED FUNCTIONS +++++++++++++++++++");
4246
4247 nImportedModules = GetImportModuleNames (lpFile, &piNameBuff);
4248 if (nImportedModules == 0)
4249 {
4250 printf ("\n There are no imported Functions in This Application.\n");
4251 }
4252 else
4253 {
4254 pnstr = piNameBuff;
4255 printf ("\nNumber of Imported Modules = %4d (decimal)\n", nImportedModules);
4256 for (i = 0; i < nImportedModules; i++)
4257 {
4258 printf ("\n Import Module %03d: %s", i + 1, pnstr);
4259 pnstr += strlen ((char *) (pnstr)) + 1;
4260 }
4261
4262 printf ("\n");
4263 printf ("\n+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++++");
4264 pnstr = piNameBuff;
4265 for (i = 0; i < nImportedModules; i++)
4266 {
4267 printf ("\n\n Import Module %03d: %s \n", i + 1, pnstr);
4268 nFunctions = GetImportFunctionNamesByModule (lpFile, pnstr, &pfNameBuff);
4269 pnstr += strlen ((char *) (pnstr)) + 1;
4270 pst = pfNameBuff;
4271 for (j = 0; j < nFunctions; j++)
4272 {
4273 printf ("\nAddr:%08X hint(%04X) Name: %s",
4274 (*(int *) pst), (*(short *) (pst + 4)),
4275 //(pst+6));
4276 TranslateFunctionName (pst + 6));
4277 pst += strlen ((char *) (pst + 6)) + 1 + 6;
4278 }
4279 free ((void *) pfNameBuff);
4280 }
4281 free ((void *) piNameBuff);
4282 }
4283
4284 printf ("\n");
4285 printf ("\n+++++++++++++++++++ EXPORTED FUNCTIONS +++++++++++++++++++");
4286
4287 nExportedFunctions = GetExportFunctionNames (lpFile, &peNameBuff);
4288 printf ("\nNumber of Exported Functions = %4d (decimal)\n", nExportedFunctions);
4289
4290 if (nExportedFunctions > 0)
4291 {
4292 pst = peNameBuff;
4293
4294 for (i = 0; i < nExportedFunctions; i++)
4295 {
4296 printf ("\nAddr:%08X Ord:%4d (%04Xh) Name: %s",
4297 (*(int *) pst), (*(WORD *) (pst + 4)), (*(WORD *) (pst + 4)),
4298 //(pst+6));
4299 TranslateFunctionName (pst + 6));
4300 pst += strlen ((char *) (pst + 6)) + 6 + 1;
4301 }
4302 free ((void *) peNameBuff);
4303 }
4304
4305 free ((void *) lpFile);
4306
4307 return 0;
4308 }
4309
4310
4311 /* EOF */