81a8869cece788e268938f816271fc37e15827fc
[reactos.git] / rosapps / sysutils / pedump.c
1 // $Id: pedump.c,v 1.1 2001/01/13 18:19:23 ea Exp $
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
52 #ifndef bcopy
53 #define bcopy(s,d,z) memcpy((d),(s),(z))
54 #endif
55
56 typedef char CHAR;
57 typedef short WCHAR;
58 typedef short SHORT;
59 typedef long LONG;
60 typedef unsigned short USHORT;
61 typedef unsigned long DWORD;
62 typedef int BOOL;
63 typedef unsigned char BYTE;
64 typedef unsigned short WORD;
65 typedef BYTE *PBYTE;
66 typedef WORD *PWORD;
67 typedef DWORD *PDWORD;
68 typedef void *LPVOID;
69 typedef int boolean;
70
71 #define VOID void
72 #define BOOLEAN boolean
73
74 #ifndef NULL
75 #define NULL 0
76 #endif
77
78 #define FALSE 0
79 #define TRUE 1
80 #define CONST const
81 #define LOWORD(l) ((WORD)(l))
82 #define WINAPI __stdcall
83
84 //
85 // Image Format
86 //
87
88 #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
89 #define IMAGE_OS2_SIGNATURE 0x454E // NE
90 #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE
91 #define IMAGE_VXD_SIGNATURE 0x454C // LE
92 #define IMAGE_NT_SIGNATURE 0x00004550 // PE00
93
94 typedef struct _IMAGE_DOS_HEADER
95 { // DOS .EXE header
96
97 WORD e_magic; // Magic number
98
99 WORD e_cblp; // Bytes on last page of file
100
101 WORD e_cp; // Pages in file
102
103 WORD e_crlc; // Relocations
104
105 WORD e_cparhdr; // Size of header in paragraphs
106
107 WORD e_minalloc; // Minimum extra paragraphs needed
108
109 WORD e_maxalloc; // Maximum extra paragraphs needed
110
111 WORD e_ss; // Initial (relative) SS value
112
113 WORD e_sp; // Initial SP value
114
115 WORD e_csum; // Checksum
116
117 WORD e_ip; // Initial IP value
118
119 WORD e_cs; // Initial (relative) CS value
120
121 WORD e_lfarlc; // File address of relocation table
122
123 WORD e_ovno; // Overlay number
124
125 WORD e_res[4]; // Reserved words
126
127 WORD e_oemid; // OEM identifier (for e_oeminfo)
128
129 WORD e_oeminfo; // OEM information; e_oemid specific
130
131 WORD e_res2[10]; // Reserved words
132
133 LONG e_lfanew; // File address of new exe header
134
135 }
136 IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
137
138 //
139 // File header format.
140 //
141
142
143
144 typedef struct _IMAGE_FILE_HEADER
145 {
146 WORD Machine;
147 WORD NumberOfSections;
148 DWORD TimeDateStamp;
149 DWORD PointerToSymbolTable;
150 DWORD NumberOfSymbols;
151 WORD SizeOfOptionalHeader;
152 WORD Characteristics;
153 }
154 IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
155
156 #define IMAGE_SIZEOF_FILE_HEADER 20
157
158 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
159 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
160 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
161 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
162 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
163 #define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
164 #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
165 #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
166 #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
167 #define IMAGE_FILE_SYSTEM 0x1000 // System File.
168 #define IMAGE_FILE_DLL 0x2000 // File is a DLL.
169 #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
170 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
171
172 #define IMAGE_FILE_MACHINE_UNKNOWN 0
173 #define IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
174 #define IMAGE_FILE_MACHINE_R3000 0x162 // MIPS little-endian, 0x160 big-endian
175 #define IMAGE_FILE_MACHINE_R4000 0x166 // MIPS little-endian
176 #define IMAGE_FILE_MACHINE_R10000 0x168 // MIPS little-endian
177 #define IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP
178 #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM PowerPC Little-Endian
179
180
181
182 //
183 // Directory format.
184 //
185
186 typedef struct _IMAGE_DATA_DIRECTORY
187 {
188 DWORD VirtualAddress;
189 DWORD Size;
190
191 }
192 IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
193
194 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
195
196 //
197 // Optional header format.
198 //
199
200 typedef struct _IMAGE_OPTIONAL_HEADER
201 {
202 //
203 // Standard fields.
204 //
205 WORD Magic;
206 BYTE MajorLinkerVersion;
207 BYTE MinorLinkerVersion;
208 DWORD SizeOfCode;
209 DWORD SizeOfInitializedData;
210 DWORD SizeOfUninitializedData;
211 DWORD AddressOfEntryPoint;
212 DWORD BaseOfCode;
213 DWORD BaseOfData;
214
215 //
216 // NT additional fields.
217 //
218
219 DWORD ImageBase;
220 DWORD SectionAlignment;
221 DWORD FileAlignment;
222 WORD MajorOperatingSystemVersion;
223 WORD MinorOperatingSystemVersion;
224 WORD MajorImageVersion;
225 WORD MinorImageVersion;
226 WORD MajorSubsystemVersion;
227 WORD MinorSubsystemVersion;
228 DWORD Win32VersionValue;
229 DWORD SizeOfImage;
230 DWORD SizeOfHeaders;
231 DWORD CheckSum;
232 WORD Subsystem;
233 WORD DllCharacteristics;
234 DWORD SizeOfStackReserve;
235 DWORD SizeOfStackCommit;
236 DWORD SizeOfHeapReserve;
237 DWORD SizeOfHeapCommit;
238 DWORD LoaderFlags;
239 DWORD NumberOfRvaAndSizes;
240 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
241
242 }
243 IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
244
245
246 typedef struct _IMAGE_NT_HEADERS
247 {
248 DWORD Signature;
249 IMAGE_FILE_HEADER FileHeader;
250 IMAGE_OPTIONAL_HEADER OptionalHeader;
251
252 }
253 IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
254
255
256 // Directory Entries
257
258 #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
259 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
260 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
261 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
262 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
263 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
264 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory
265 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // Description String
266 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // Machine Value (MIPS GP)
267 #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory
268 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory
269 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers
270 #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
271
272 //
273 // Section header format.
274 //
275
276 #define IMAGE_SIZEOF_SHORT_NAME 8
277
278 typedef struct _IMAGE_SECTION_HEADER
279 {
280 BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
281 union
282 {
283 DWORD PhysicalAddress;
284 DWORD VirtualSize;
285 }
286 Misc;
287 DWORD VirtualAddress;
288 DWORD SizeOfRawData;
289 DWORD PointerToRawData;
290 DWORD PointerToRelocations;
291 DWORD PointerToLinenumbers;
292 WORD NumberOfRelocations;
293 WORD NumberOfLinenumbers;
294 DWORD Characteristics;
295
296 }
297 IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
298
299 #define IMAGE_SIZEOF_SECTION_HEADER 40
300
301
302 //
303 // Export Format
304 //
305
306 typedef struct _IMAGE_EXPORT_DIRECTORY
307 {
308 DWORD Characteristics;
309 DWORD TimeDateStamp;
310 WORD MajorVersion;
311 WORD MinorVersion;
312 DWORD Name;
313 DWORD Base;
314 DWORD NumberOfFunctions;
315 DWORD NumberOfNames;
316 PDWORD *AddressOfFunctions;
317 PDWORD *AddressOfNames;
318 PWORD *AddressOfNameOrdinals;
319
320 }
321 IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
322
323 //
324 // Import Format
325 //
326
327 typedef struct _IMAGE_IMPORT_BY_NAME
328 {
329 WORD Hint;
330 BYTE Name[1];
331
332 }
333 IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
334
335 #define IMAGE_ORDINAL_FLAG 0x80000000
336 #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
337
338
339 //
340 // Resource Format.
341 //
342
343 //
344 // Resource directory consists of two counts, following by a variable length
345 // array of directory entries. The first count is the number of entries at
346 // beginning of the array that have actual names associated with each entry.
347 // The entries are in ascending order, case insensitive strings. The second
348 // count is the number of entries that immediately follow the named entries.
349 // This second count identifies the number of entries that have 16-bit integer
350 // Ids as their name. These entries are also sorted in ascending order.
351 //
352 // This structure allows fast lookup by either name or number, but for any
353 // given resource entry only one form of lookup is supported, not both.
354 // This is consistant with the syntax of the .RC file and the .RES file.
355 //
356
357 // Predefined resource types ... there may be some more, but I don't have
358 // the information yet. .....sang cho.....
359
360 #define RT_NEWRESOURCE 0x2000
361 #define RT_ERROR 0x7fff
362 #define RT_CURSOR 1
363 #define RT_BITMAP 2
364 #define RT_ICON 3
365 #define RT_MENU 4
366 #define RT_DIALOG 5
367 #define RT_STRING 6
368 #define RT_FONTDIR 7
369 #define RT_FONT 8
370 #define RT_ACCELERATORS 9
371 #define RT_RCDATA 10
372 #define RT_MESSAGETABLE 11
373 #define RT_GROUP_CURSOR 12
374 #define RT_GROUP_ICON 14
375 #define RT_VERSION 16
376 #define NEWBITMAP (RT_BITMAP|RT_NEWRESOURCE)
377 #define NEWMENU (RT_MENU|RT_NEWRESOURCE)
378 #define NEWDIALOG (RT_DIALOG|RT_NEWRESOURCE)
379
380
381 typedef struct _IMAGE_RESOURCE_DIRECTORY
382 {
383 DWORD Characteristics;
384 DWORD TimeDateStamp;
385 WORD MajorVersion;
386 WORD MinorVersion;
387 WORD NumberOfNamedEntries;
388 WORD NumberOfIdEntries;
389 // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[1];
390
391 }
392 IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
393
394 #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
395 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
396
397 //
398 // Each directory contains the 32-bit Name of the entry and an offset,
399 // relative to the beginning of the resource directory of the data associated
400 // with this directory entry. If the name of the entry is an actual text
401 // string instead of an integer Id, then the high order bit of the name field
402 // is set to one and the low order 31-bits are an offset, relative to the
403 // beginning of the resource directory of the string, which is of type
404 // IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the
405 // low-order 16-bits are the integer Id that identify this resource directory
406 // entry. If the directory entry is yet another resource directory (i.e. a
407 // subdirectory), then the high order bit of the offset field will be
408 // set to indicate this. Otherwise the high bit is clear and the offset
409 // field points to a resource data entry.
410 //
411
412 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY
413 {
414 DWORD Name;
415 DWORD OffsetToData;
416
417 }
418 IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
419
420 //
421 // For resource directory entries that have actual string names, the Name
422 // field of the directory entry points to an object of the following type.
423 // All of these string objects are stored together after the last resource
424 // directory entry and before the first resource data object. This minimizes
425 // the impact of these variable length objects on the alignment of the fixed
426 // size directory entry objects.
427 //
428
429 typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING
430 {
431 WORD Length;
432 CHAR NameString[1];
433
434 }
435 IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;
436
437
438 typedef struct _IMAGE_RESOURCE_DIR_STRING_U
439 {
440 WORD Length;
441 WCHAR NameString[1];
442
443 }
444 IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
445
446
447 //
448 // Each resource data entry describes a leaf node in the resource directory
449 // tree. It contains an offset, relative to the beginning of the resource
450 // directory of the data for the resource, a size field that gives the number
451 // of bytes of data at that offset, a CodePage that should be used when
452 // decoding code point values within the resource data. Typically for new
453 // applications the code page would be the unicode code page.
454 //
455
456 typedef struct _IMAGE_RESOURCE_DATA_ENTRY
457 {
458 DWORD OffsetToData;
459 DWORD Size;
460 DWORD CodePage;
461 DWORD Reserved;
462
463 }
464 IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
465
466
467 // Menu Resources ... added by .....sang cho....
468
469 // Menu resources are composed of a menu header followed by a sequential list
470 // of menu items. There are two types of menu items: pop-ups and normal menu
471 // itmes. The MENUITEM SEPARATOR is a special case of a normal menu item with
472 // an empty name, zero ID, and zero flags.
473
474 typedef struct _IMAGE_MENU_HEADER
475 {
476 WORD wVersion; // Currently zero
477
478 WORD cbHeaderSize; // Also zero
479
480 }
481 IMAGE_MENU_HEADER, *PIMAGE_MENU_HEADER;
482
483 typedef struct _IMAGE_POPUP_MENU_ITEM
484 {
485 WORD fItemFlags;
486 WCHAR szItemText[1];
487
488 }
489 IMAGE_POPUP_MENU_ITEM, *PIMAGE_POPUP_MENU_ITEM;
490
491 typedef struct _IMAGE_NORMAL_MENU_ITEM
492 {
493 WORD fItemFlags;
494 WORD wMenuID;
495 WCHAR szItemText[1];
496
497 }
498 IMAGE_NORMAL_MENU_ITEM, *PIMAGE_NORMAL_MENU_ITEM;
499
500 #define GRAYED 0x0001 // GRAYED keyword
501 #define INACTIVE 0x0002 // INACTIVE keyword
502 #define BITMAP 0x0004 // BITMAP keyword
503 #define OWNERDRAW 0x0100 // OWNERDRAW keyword
504 #define CHECKED 0x0008 // CHECKED keyword
505 #define POPUP 0x0010 // used internally
506 #define MENUBARBREAK 0x0020 // MENUBARBREAK keyword
507 #define MENUBREAK 0x0040 // MENUBREAK keyword
508 #define ENDMENU 0x0080 // used internally
509
510
511 // Dialog Box Resources .................. added by sang cho.
512
513 // A dialog box is contained in a single resource and has a header and
514 // a portion repeated for each control in the dialog box.
515 // The item DWORD IStyle is a standard window style composed of flags found
516 // in WINDOWS.H.
517 // The default style for a dialog box is:
518 // WS_POPUP | WS_BORDER | WS_SYSMENU
519 //
520 // The itme marked "Name or Ordinal" are :
521 // If the first word is an 0xffff, the next two bytes contain an ordinal ID.
522 // Otherwise, the first one or more WORDS contain a double-null-terminated string.
523 // An empty string is represented by a single WORD zero in the first location.
524 //
525 // The WORD wPointSize and WCHAR szFontName entries are present if the FONT
526 // statement was included for the dialog box. This can be detected by checking
527 // the entry IStyle. If IStyle & DS_SETFONT ( which is 0x40), then these
528 // entries will be present.
529
530 typedef struct _IMAGE_DIALOG_BOX_HEADER1
531 {
532 DWORD IStyle;
533 DWORD IExtendedStyle; // New for Windows NT
534
535 WORD nControls; // Number of Controls
536
537 WORD x;
538 WORD y;
539 WORD cx;
540 WORD cy;
541 // N_OR_O MenuName; // Name or Ordinal ID
542 // N_OR_O ClassName; // Name or Ordinal ID
543 // WCHAR szCaption[];
544 // WORD wPointSize; // Only here if FONT set for dialog
545 // WCHAR szFontName[]; // This too
546 }
547 IMAGE_DIALOG_HEADER, *PIMAGE_DIALOG_HEADER;
548
549 typedef union _NAME_OR_ORDINAL
550 { // Name or Ordinal ID
551
552 struct _ORD_ID
553 {
554 WORD flgId;
555 WORD Id;
556 }
557 ORD_ID;
558 WCHAR szName[1];
559 }
560 NAME_OR_ORDINAL, *PNAME_OR_ORDINAL;
561
562 // The data for each control starts on a DWORD boundary (which may require
563 // some padding from the previous control), and its format is as follows:
564
565 typedef struct _IMAGE_CONTROL_DATA
566 {
567 DWORD IStyle;
568 DWORD IExtendedStyle;
569 WORD x;
570 WORD y;
571 WORD cx;
572 WORD cy;
573 WORD wId;
574 // N_OR_O ClassId;
575 // N_OR_O Text;
576 // WORD nExtraStuff;
577 }
578 IMAGE_CONTROL_DATA, *PIMAGE_CONTROL_DATA;
579
580 #define BUTTON 0x80
581 #define EDIT 0x81
582 #define STATIC 0x82
583 #define LISTBOX 0x83
584 #define SCROLLBAR 0x84
585 #define COMBOBOX 0x85
586
587 // The various statements used in a dialog script are all mapped to these
588 // classes along with certain modifying styles. The values for these styles
589 // can be found in WINDOWS.H. All dialog controls have the default styles
590 // of WS_CHILD and WS_VISIBLE. A list of the default styles used follows:
591 //
592 // Statement Default Class Default Styles
593 // CONTROL None WS_CHILD|WS_VISIBLE
594 // LTEXT STATIC ES_LEFT
595 // RTEXT STATIC ES_RIGHT
596 // CTEXT STATIC ES_CENTER
597 // LISTBOX LISTBOX WS_BORDER|LBS_NOTIFY
598 // CHECKBOX BUTTON BS_CHECKBOX|WS_TABSTOP
599 // PUSHBUTTON BUTTON BS_PUSHBUTTON|WS_TABSTOP
600 // GROUPBOX BUTTON BS_GROUPBOX
601 // DEFPUSHBUTTON BUTTON BS_DFPUSHBUTTON|WS_TABSTOP
602 // RADIOBUTTON BUTTON BS_RADIOBUTTON
603 // AUTOCHECKBOX BUTTON BS_AUTOCHECKBOX
604 // AUTO3STATE BUTTON BS_AUTO3STATE
605 // AUTORADIOBUTTON BUTTON BS_AUTORADIOBUTTON
606 // PUSHBOX BUTTON BS_PUSHBOX
607 // STATE3 BUTTON BS_3STATE
608 // EDITTEXT EDIT ES_LEFT|WS_BORDER|WS_TABSTOP
609 // COMBOBOX COMBOBOX None
610 // ICON STATIC SS_ICON
611 // SCROLLBAR SCROLLBAR None
612 ///
613
614 #define WS_OVERLAPPED 0x00000000L
615 #define WS_POPUP 0x80000000L
616 #define WS_CHILD 0x40000000L
617 #define WS_CLIPSIBLINGS 0x04000000L
618 #define WS_CLIPCHILDREN 0x02000000L
619 #define WS_VISIBLE 0x10000000L
620 #define WS_DISABLED 0x08000000L
621 #define WS_MINIMIZE 0x20000000L
622 #define WS_MAXIMIZE 0x01000000L
623 #define WS_CAPTION 0x00C00000L
624 #define WS_BORDER 0x00800000L
625 #define WS_DLGFRAME 0x00400000L
626 #define WS_VSCROLL 0x00200000L
627 #define WS_HSCROLL 0x00100000L
628 #define WS_SYSMENU 0x00080000L
629 #define WS_THICKFRAME 0x00040000L
630 #define WS_MINIMIZEBOX 0x00020000L
631 #define WS_MAXIMIZEBOX 0x00010000L
632 #define WS_GROUP 0x00020000L
633 #define WS_TABSTOP 0x00010000L
634
635 // other aliases
636 #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
637 #define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
638 #define WS_CHILDWINDOW (WS_CHILD)
639 #define WS_TILED WS_OVERLAPPED
640 #define WS_ICONIC WS_MINIMIZE
641 #define WS_SIZEBOX WS_THICKFRAME
642 #define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW
643
644 #define WS_EX_DLGMODALFRAME 0x00000001L
645 #define WS_EX_NOPARENTNOTIFY 0x00000004L
646 #define WS_EX_TOPMOST 0x00000008L
647 #define WS_EX_ACCEPTFILES 0x00000010L
648 #define WS_EX_TRANSPARENT 0x00000020L
649
650 #define BS_PUSHBUTTON 0x00000000L
651 #define BS_DEFPUSHBUTTON 0x00000001L
652 #define BS_CHECKBOX 0x00000002L
653 #define BS_AUTOCHECKBOX 0x00000003L
654 #define BS_RADIOBUTTON 0x00000004L
655 #define BS_3STATE 0x00000005L
656 #define BS_AUTO3STATE 0x00000006L
657 #define BS_GROUPBOX 0x00000007L
658 #define BS_USERBUTTON 0x00000008L
659 #define BS_AUTORADIOBUTTON 0x00000009L
660 #define BS_OWNERDRAW 0x0000000BL
661 #define BS_LEFTTEXT 0x00000020L
662
663 #define ES_LEFT 0x00000000L
664 #define ES_CENTER 0x00000001L
665 #define ES_RIGHT 0x00000002L
666 #define ES_MULTILINE 0x00000004L
667 #define ES_UPPERCASE 0x00000008L
668 #define ES_LOWERCASE 0x00000010L
669 #define ES_PASSWORD 0x00000020L
670 #define ES_AUTOVSCROLL 0x00000040L
671 #define ES_AUTOHSCROLL 0x00000080L
672 #define ES_NOHIDESEL 0x00000100L
673 #define ES_OEMCONVERT 0x00000400L
674 #define ES_READONLY 0x00000800L
675 #define ES_WANTRETURN 0x00001000L
676
677 #define LBS_NOTIFY 0x0001L
678 #define LBS_SORT 0x0002L
679 #define LBS_NOREDRAW 0x0004L
680 #define LBS_MULTIPLESEL 0x0008L
681 #define LBS_OWNERDRAWFIXED 0x0010L
682 #define LBS_OWNERDRAWVARIABLE 0x0020L
683 #define LBS_HASSTRINGS 0x0040L
684 #define LBS_USETABSTOPS 0x0080L
685 #define LBS_NOINTEGRALHEIGHT 0x0100L
686 #define LBS_MULTICOLUMN 0x0200L
687 #define LBS_WANTKEYBOARDINPUT 0x0400L
688 #define LBS_EXTENDEDSEL 0x0800L
689 #define LBS_DISABLENOSCROLL 0x1000L
690
691 #define SS_LEFT 0x00000000L
692 #define SS_CENTER 0x00000001L
693 #define SS_RIGHT 0x00000002L
694 #define SS_ICON 0x00000003L
695 #define SS_BLACKRECT 0x00000004L
696 #define SS_GRAYRECT 0x00000005L
697 #define SS_WHITERECT 0x00000006L
698 #define SS_BLACKFRAME 0x00000007L
699 #define SS_GRAYFRAME 0x00000008L
700 #define SS_WHITEFRAME 0x00000009L
701 #define SS_SIMPLE 0x0000000BL
702 #define SS_LEFTNOWORDWRAP 0x0000000CL
703 #define SS_BITMAP 0x0000000EL
704
705 //
706 // Debug Format
707 //
708
709 typedef struct _IMAGE_DEBUG_DIRECTORY
710 {
711 DWORD Characteristics;
712 DWORD TimeDateStamp;
713 WORD MajorVersion;
714 WORD MinorVersion;
715 DWORD Type;
716 DWORD SizeOfData;
717 DWORD AddressOfRawData;
718 DWORD PointerToRawData;
719 }
720 IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
721
722 #define IMAGE_DEBUG_TYPE_UNKNOWN 0
723 #define IMAGE_DEBUG_TYPE_COFF 1
724 #define IMAGE_DEBUG_TYPE_CODEVIEW 2
725 #define IMAGE_DEBUG_TYPE_FPO 3
726 #define IMAGE_DEBUG_TYPE_MISC 4
727 #define IMAGE_DEBUG_TYPE_EXCEPTION 5
728 #define IMAGE_DEBUG_TYPE_FIXUP 6
729 #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
730 #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
731
732
733 typedef struct _IMAGE_DEBUG_MISC
734 {
735 DWORD DataType; // type of misc data, see defines
736
737 DWORD Length; // total length of record, rounded to four
738 // byte multiple.
739
740 BOOLEAN Unicode; // TRUE if data is unicode string
741
742 BYTE Reserved[3];
743 BYTE Data[1]; // Actual data
744
745 }
746 IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC;
747
748
749 //
750 // Debugging information can be stripped from an image file and placed
751 // in a separate .DBG file, whose file name part is the same as the
752 // image file name part (e.g. symbols for CMD.EXE could be stripped
753 // and placed in CMD.DBG). This is indicated by the IMAGE_FILE_DEBUG_STRIPPED
754 // flag in the Characteristics field of the file header. The beginning of
755 // the .DBG file contains the following structure which captures certain
756 // information from the image file. This allows a debug to proceed even if
757 // the original image file is not accessable. This header is followed by
758 // zero of more IMAGE_SECTION_HEADER structures, followed by zero or more
759 // IMAGE_DEBUG_DIRECTORY structures. The latter structures and those in
760 // the image file contain file offsets relative to the beginning of the
761 // .DBG file.
762 //
763 // If symbols have been stripped from an image, the IMAGE_DEBUG_MISC structure
764 // is left in the image file, but not mapped. This allows a debugger to
765 // compute the name of the .DBG file, from the name of the image in the
766 // IMAGE_DEBUG_MISC structure.
767 //
768
769 typedef struct _IMAGE_SEPARATE_DEBUG_HEADER
770 {
771 WORD Signature;
772 WORD Flags;
773 WORD Machine;
774 WORD Characteristics;
775 DWORD TimeDateStamp;
776 DWORD CheckSum;
777 DWORD ImageBase;
778 DWORD SizeOfImage;
779 DWORD NumberOfSections;
780 DWORD ExportedNamesSize;
781 DWORD DebugDirectorySize;
782 DWORD SectionAlignment;
783 DWORD Reserved[2];
784 }
785 IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER;
786
787 #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
788
789 #define IMAGE_SEPARATE_DEBUG_FLAGS_MASK 0x8000
790 #define IMAGE_SEPARATE_DEBUG_MISMATCH 0x8000 // when DBG was updated, the
791 // old checksum didn't match.
792
793
794 //
795 // End Image Format
796 //
797
798
799 #define SIZE_OF_NT_SIGNATURE sizeof (DWORD)
800 #define MAXRESOURCENAME 13
801
802 /* global macros to define header offsets into file */
803 /* offset to PE file signature */
804 #define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
805 ((PIMAGE_DOS_HEADER)a)->e_lfanew))
806
807 /* DOS header identifies the NT PEFile signature dword
808 the PEFILE header exists just after that dword */
809 #define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \
810 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
811 SIZE_OF_NT_SIGNATURE))
812
813 /* PE optional header is immediately after PEFile header */
814 #define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \
815 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
816 SIZE_OF_NT_SIGNATURE + \
817 sizeof (IMAGE_FILE_HEADER)))
818
819 /* section headers are immediately after PE optional header */
820 #define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + \
821 ((PIMAGE_DOS_HEADER)a)->e_lfanew + \
822 SIZE_OF_NT_SIGNATURE + \
823 sizeof (IMAGE_FILE_HEADER) + \
824 sizeof (IMAGE_OPTIONAL_HEADER)))
825
826
827 typedef struct tagImportDirectory
828 {
829 DWORD dwRVAFunctionNameList;
830 DWORD dwUseless1;
831 DWORD dwUseless2;
832 DWORD dwRVAModuleName;
833 DWORD dwRVAFunctionAddressList;
834 }
835 IMAGE_IMPORT_MODULE_DIRECTORY, *PIMAGE_IMPORT_MODULE_DIRECTORY;
836
837
838 /* global prototypes for functions in pefile.c */
839 /* PE file header info */
840 BOOL WINAPI GetDosHeader (LPVOID, PIMAGE_DOS_HEADER);
841 DWORD WINAPI ImageFileType (LPVOID);
842 BOOL WINAPI GetPEFileHeader (LPVOID, PIMAGE_FILE_HEADER);
843
844 /* PE optional header info */
845 BOOL WINAPI GetPEOptionalHeader (LPVOID, PIMAGE_OPTIONAL_HEADER);
846 LPVOID WINAPI GetModuleEntryPoint (LPVOID);
847 int WINAPI NumOfSections (LPVOID);
848 LPVOID WINAPI GetImageBase (LPVOID);
849 LPVOID WINAPI ImageDirectoryOffset (LPVOID, DWORD);
850 LPVOID WINAPI ImageDirectorySection (LPVOID, DWORD);
851
852 /* PE section header info */
853 //int WINAPI GetSectionNames (LPVOID, HANDLE, char **);
854 int WINAPI GetSectionNames (LPVOID, char **);
855 BOOL WINAPI GetSectionHdrByName (LPVOID, PIMAGE_SECTION_HEADER, char *);
856
857 //
858 // structur to store string tokens
859 //
860 typedef struct _Str_P
861 {
862 char flag; // string_flag '@' or '%' or '#'
863
864 char *pos; // starting postion of string
865
866 int length; // length of string
867
868 BOOL wasString; // if it were stringMode or not
869
870 }
871 Str_P;
872
873 /* import section info */
874 int WINAPI GetImportModuleNames (LPVOID, char **);
875 int WINAPI GetImportFunctionNamesByModule (LPVOID, char *, char **);
876
877 // import function name reporting
878 int WINAPI GetStringLength (char *);
879 void WINAPI GetPreviousParamString (char *, char *);
880 void WINAPI TranslateParameters (char **, char **, char **);
881 BOOL WINAPI StringExpands (char **, char **, char **, Str_P *);
882 LPVOID WINAPI TranslateFunctionName (char *);
883
884 /* export section info */
885 int WINAPI GetExportFunctionNames (LPVOID, char **);
886
887 /* resource section info */
888 int WINAPI GetNumberOfResources (LPVOID);
889 int WINAPI GetListOfResourceTypes (LPVOID, char **);
890 int WINAPI MenuScan (int *, WORD **);
891 int WINAPI MenuFill (char **, WORD **);
892 void WINAPI StrangeMenuFill (char **, WORD **, int);
893 int WINAPI GetContentsOfMenu (LPVOID, char **);
894 int WINAPI PrintMenu (int, char **);
895 int WINAPI PrintStrangeMenu (char **);
896 int WINAPI dumpMenu (char **psz, int size);
897
898 /* debug section info */
899 BOOL WINAPI IsDebugInfoStripped (LPVOID);
900 int WINAPI RetrieveModuleName (LPVOID, char **);
901 BOOL WINAPI IsDebugFile (LPVOID);
902 BOOL WINAPI GetSeparateDebugHeader (LPVOID, PIMAGE_SEPARATE_DEBUG_HEADER);
903
904
905 /**********************************************************************
906 * NAME
907 *
908 * DESCRIPTION
909 * Copy DOS header information to structure.
910 *
911 * ARGUMENTS
912 */
913 BOOL WINAPI
914 GetDosHeader (
915 LPVOID lpFile,
916 PIMAGE_DOS_HEADER pHeader
917 )
918 {
919 /*
920 * DOS header represents first structure
921 * of bytes in PE image file.
922 */
923 if ((WORD) IMAGE_DOS_SIGNATURE == *(WORD *) lpFile)
924 {
925 bcopy (
926 lpFile,
927 (LPVOID) pHeader,
928 sizeof (IMAGE_DOS_HEADER)
929 );
930 return TRUE;
931 }
932 return FALSE;
933 }
934
935
936
937
938 /* return file signature */
939 DWORD WINAPI
940 ImageFileType (
941 LPVOID lpFile)
942 {
943 /* dos file signature comes first */
944 if (*(USHORT *) lpFile == IMAGE_DOS_SIGNATURE)
945 {
946 /* determine location of PE File header from dos header */
947 if (LOWORD (*(DWORD *) NTSIGNATURE (lpFile)) == IMAGE_OS2_SIGNATURE ||
948 LOWORD (*(DWORD *) NTSIGNATURE (lpFile)) == IMAGE_OS2_SIGNATURE_LE)
949 return (DWORD) LOWORD (*(DWORD *) NTSIGNATURE (lpFile));
950
951 else if (*(DWORD *) NTSIGNATURE (lpFile) == IMAGE_NT_SIGNATURE)
952 return IMAGE_NT_SIGNATURE;
953
954 else
955 return IMAGE_DOS_SIGNATURE;
956 }
957
958 else
959 /* unknown file type */
960 return 0;
961 }
962
963
964
965
966 /* copy file header information to structure */
967 BOOL WINAPI
968 GetPEFileHeader (
969 LPVOID lpFile,
970 PIMAGE_FILE_HEADER pHeader)
971 {
972 /* file header follows dos header */
973 if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE)
974 bcopy (PEFHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_FILE_HEADER));
975 else
976 return FALSE;
977
978 return TRUE;
979 }
980
981
982
983
984
985 /* copy optional header info to structure */
986 BOOL WINAPI
987 GetPEOptionalHeader (
988 LPVOID lpFile,
989 PIMAGE_OPTIONAL_HEADER pHeader)
990 {
991 /* optional header follows file header and dos header */
992 if (ImageFileType (lpFile) == IMAGE_NT_SIGNATURE)
993 bcopy (OPTHDROFFSET (lpFile), (LPVOID) pHeader, sizeof (IMAGE_OPTIONAL_HEADER));
994 else
995 return FALSE;
996
997 return TRUE;
998 }
999
1000
1001
1002
1003 /* function returns the entry point for an exe module lpFile must
1004 be a memory mapped file pointer to the beginning of the image file */
1005 LPVOID WINAPI
1006 GetModuleEntryPoint (
1007 LPVOID lpFile)
1008 {
1009 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1010
1011 if (poh != NULL)
1012 return (LPVOID) (poh->AddressOfEntryPoint);
1013 else
1014 return NULL;
1015 }
1016
1017
1018
1019
1020 /* return the total number of sections in the module */
1021 int WINAPI
1022 NumOfSections (
1023 LPVOID lpFile)
1024 {
1025 /* number os sections is indicated in file header */
1026 return ((int) ((PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile))->NumberOfSections);
1027 }
1028
1029
1030
1031
1032 /* retrieve entry point */
1033 LPVOID WINAPI
1034 GetImageBase (
1035 LPVOID lpFile)
1036 {
1037 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1038
1039 if (poh != NULL)
1040 return (LPVOID) (poh->ImageBase);
1041 else
1042 return NULL;
1043 }
1044
1045
1046
1047 //
1048 // This function is written by sang cho
1049 // .. october 5, 1997
1050 //
1051 /* function returns the actual address of given RVA, lpFile must
1052 be a memory mapped file pointer to the beginning of the image file */
1053 LPVOID WINAPI
1054 GetActualAddress (
1055 LPVOID lpFile,
1056 DWORD dwRVA)
1057 {
1058 // PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
1059 PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
1060 int nSections = NumOfSections (lpFile);
1061 int i = 0;
1062
1063 if (dwRVA == NULL)
1064 return NULL;
1065 if (dwRVA & 0x80000000)
1066 {
1067 //return (LPVOID)dwRVA;
1068 printf ("\n$$ what is going on $$");
1069 exit (0);
1070 }
1071
1072 /* locate section containing image directory */
1073 while (i++ < nSections)
1074 {
1075 if (psh->VirtualAddress <= (DWORD) dwRVA &&
1076 psh->VirtualAddress + psh->SizeOfRawData > (DWORD) dwRVA)
1077 break;
1078 psh++;
1079 }
1080
1081 if (i > nSections)
1082 return NULL;
1083
1084 /* return image import directory offset */
1085 return (LPVOID) (((int) lpFile + (int) dwRVA - psh->VirtualAddress) +
1086 (int) psh->PointerToRawData);
1087 }
1088
1089
1090 //
1091 // This function is modified by sang cho
1092 //
1093 //
1094 /* return offset to specified IMAGE_DIRECTORY entry */
1095 LPVOID WINAPI
1096 ImageDirectoryOffset (
1097 LPVOID lpFile,
1098 DWORD dwIMAGE_DIRECTORY)
1099 {
1100 PIMAGE_OPTIONAL_HEADER poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
1101 PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
1102 int nSections = NumOfSections (lpFile);
1103 int i = 0;
1104 LPVOID VAImageDir;
1105
1106 /* must be 0 thru (NumberOfRvaAndSizes-1) */
1107 if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
1108 return NULL;
1109
1110 /* locate specific image directory's relative virtual address */
1111 VAImageDir = (LPVOID) poh->DataDirectory[dwIMAGE_DIRECTORY].VirtualAddress;
1112
1113 if (VAImageDir == NULL)
1114 return NULL;
1115 /* locate section containing image directory */
1116 while (i++ < nSections)
1117 {
1118 if (psh->VirtualAddress <= (DWORD) VAImageDir &&
1119 psh->VirtualAddress + psh->SizeOfRawData > (DWORD) VAImageDir)
1120 break;
1121 psh++;
1122 }
1123
1124 if (i > nSections)
1125 return NULL;
1126
1127 /* return image import directory offset */
1128 return (LPVOID) (((int) lpFile + (int) VAImageDir - psh->VirtualAddress) +
1129 (int) psh->PointerToRawData);
1130 }
1131
1132
1133 /* function retrieve names of all the sections in the file */
1134 int WINAPI
1135 GetSectionNames (
1136 LPVOID lpFile,
1137 char **pszSections)
1138 {
1139 int nSections = NumOfSections (lpFile);
1140 int i, nCnt = 0;
1141 PIMAGE_SECTION_HEADER psh;
1142 char *ps;
1143
1144
1145 if (ImageFileType (lpFile) != IMAGE_NT_SIGNATURE ||
1146 (psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) == NULL)
1147 return 0;
1148
1149 /* count the number of chars used in the section names */
1150 for (i = 0; i < nSections; i++)
1151 nCnt += strlen (psh[i].Name) + 1;
1152
1153 /* allocate space for all section names from heap */
1154 ps = *pszSections = (char *) calloc (nCnt, 1);
1155
1156
1157 for (i = 0; i < nSections; i++)
1158 {
1159 strcpy (ps, psh[i].Name);
1160 ps += strlen (psh[i].Name) + 1;
1161 }
1162
1163 return nCnt;
1164 }
1165
1166
1167
1168
1169 /* function gets the function header for a section identified by name */
1170 BOOL WINAPI
1171 GetSectionHdrByName (
1172 LPVOID lpFile,
1173 IMAGE_SECTION_HEADER * sh,
1174 char *szSection)
1175 {
1176 PIMAGE_SECTION_HEADER psh;
1177 int nSections = NumOfSections (lpFile);
1178 int i;
1179
1180
1181 if ((psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile)) != NULL)
1182 {
1183 /* find the section by name */
1184 for (i = 0; i < nSections; i++)
1185 {
1186 if (!strcmp (psh->Name, szSection))
1187 {
1188 /* copy data to header */
1189 bcopy ((LPVOID) psh, (LPVOID) sh, sizeof (IMAGE_SECTION_HEADER));
1190 return TRUE;
1191 }
1192 else
1193 psh++;
1194 }
1195 }
1196 return FALSE;
1197 }
1198
1199
1200
1201 //
1202 // This function is modified by sang cho
1203 //
1204 //
1205 /* get import modules names separated by null terminators, return module count */
1206 int WINAPI
1207 GetImportModuleNames (
1208 LPVOID lpFile,
1209 char **pszModules)
1210 {
1211 PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)
1212 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1213 //
1214 // sometimes there may be no section for idata or edata
1215 // instead rdata or data section may contain these sections ..
1216 // or even module names or function names are in different section.
1217 // so that's why we need to get actual address of RVAs each time.
1218 // ...................sang cho..................
1219 //
1220 // PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1221 // ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1222 // BYTE *pData = (BYTE *)pid;
1223 // DWORD *pdw = (DWORD *)pid;
1224 int nCnt = 0, nSize = 0, i;
1225 char *pModule[1024]; /* hardcoded maximum number of modules?? */
1226 char *psz;
1227
1228 if (pid == NULL)
1229 return 0;
1230
1231 // pData = (BYTE *)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1232
1233 /* extract all import modules */
1234 while (pid->dwRVAModuleName)
1235 {
1236 /* allocate temporary buffer for absolute string offsets */
1237 //pModule[nCnt] = (char *)(pData + pid->dwRVAModuleName);
1238 pModule[nCnt] = (char *) GetActualAddress (lpFile, pid->dwRVAModuleName);
1239 nSize += strlen (pModule[nCnt]) + 1;
1240
1241 /* increment to the next import directory entry */
1242 pid++;
1243 nCnt++;
1244 }
1245
1246 /* copy all strings to one chunk of memory */
1247 *pszModules = (char *) calloc (nSize, 1);
1248 psz = *pszModules;
1249 for (i = 0; i < nCnt; i++)
1250 {
1251 strcpy (psz, pModule[i]);
1252 psz += strlen (psz) + 1;
1253 }
1254 return nCnt;
1255 }
1256
1257
1258 //
1259 // This function is rewritten by sang cho
1260 //
1261 //
1262 /* get import module function names separated by null terminators, return function count */
1263 int WINAPI
1264 GetImportFunctionNamesByModule (
1265 LPVOID lpFile,
1266 char *pszModule,
1267 char **pszFunctions)
1268 {
1269 PIMAGE_IMPORT_MODULE_DIRECTORY pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)
1270 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1271 //
1272 // sometimes there may be no section for idata or edata
1273 // instead rdata or data section may contain these sections ..
1274 // or even module names or function names are in different section.
1275 // so that's why we need to get actual address each time.
1276 // ...................sang cho..................
1277 //
1278 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
1279 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT);
1280 //DWORD dwBase;
1281 int nCnt = 0, nSize = 0;
1282 int nnid = 0;
1283 int mnlength, i;
1284 DWORD dwFunctionName;
1285 DWORD dwFunctionAddress;
1286 char name[128];
1287 char buff[256]; // enough for any string ??
1288
1289 char *psz;
1290 DWORD *pdw;
1291
1292 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
1293
1294 /* find module's pid */
1295 while (pid->dwRVAModuleName &&
1296 strcmp (pszModule, (char *) GetActualAddress (lpFile, pid->dwRVAModuleName)))
1297 pid++;
1298
1299 /* exit if the module is not found */
1300 if (!pid->dwRVAModuleName)
1301 return 0;
1302
1303 // I am doing this to get rid of .dll from module name
1304 strcpy (name, pszModule);
1305 mnlength = strlen (pszModule);
1306 for (i = 0; i < mnlength; i++)
1307 if (name[i] == '.')
1308 break;
1309 name[i] = 0;
1310 mnlength = i;
1311
1312 /* count number of function names and length of strings */
1313 dwFunctionName = pid->dwRVAFunctionNameList;
1314
1315 // IMAGE_IMPORT_BY_NAME OR IMAGE_THUNK_DATA
1316 // modified by Sang Cho
1317 while (dwFunctionName &&
1318 *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName)))
1319 {
1320 if ((*pdw) & 0x80000000)
1321 nSize += mnlength + 10 + 1 + 6;
1322 else
1323 nSize += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1 + 6;
1324 dwFunctionName += 4;
1325 nCnt++;
1326 }
1327
1328 /* allocate memory for function names */
1329 *pszFunctions = (char *) calloc (nSize, 1);
1330 psz = *pszFunctions;
1331
1332 //
1333 // I modified this part to store function address (4 bytes),
1334 // ord number (2 bytes),
1335 // and name strings (which was there originally)
1336 // so that's why there are 6 more bytes...... +6, or +4 and +2 etc.
1337 // these informations are used where they are needed.
1338 // ...........sang cho..................
1339 //
1340 /* copy function names to mempry pointer */
1341 dwFunctionName = pid->dwRVAFunctionNameList;
1342 dwFunctionAddress = pid->dwRVAFunctionAddressList;
1343 while (dwFunctionName &&
1344 *(pdw = (DWORD *) GetActualAddress (lpFile, dwFunctionName)))
1345 {
1346 if ((*pdw) & 0x80000000)
1347 {
1348 *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress));
1349 psz += 4;
1350 *(short *) psz = *(short *) pdw;
1351 psz += 2;
1352 sprintf (buff, "%s:NoName%04d", name, nnid++);
1353 strcpy (psz, buff);
1354 psz += strlen (buff) + 1;
1355 }
1356 else
1357 {
1358 *(int *) psz = (int) (*(DWORD *) GetActualAddress (lpFile, dwFunctionAddress));
1359 psz += 4;
1360 *(short *) psz = (*(short *) GetActualAddress (lpFile, *pdw));
1361 psz += 2;
1362 strcpy (psz, (char *) GetActualAddress (lpFile, *pdw + 2));
1363 psz += strlen ((char *) GetActualAddress (lpFile, *pdw + 2)) + 1;
1364 }
1365 dwFunctionName += 4;
1366 dwFunctionAddress += 4;
1367 }
1368
1369 return nCnt;
1370 }
1371
1372
1373
1374
1375 //
1376 // This function is written by sang cho
1377 // October 6, 1997
1378 //
1379 /* get numerically expressed string length */
1380 int WINAPI
1381 GetStringLength (
1382 char *psz)
1383 {
1384 if (!isdigit (*psz))
1385 return 0;
1386 if (isdigit (*(psz + 1)))
1387 return (*psz - '0') * 10 + *(psz + 1) - '0';
1388 else
1389 return *psz - '0';
1390 }
1391
1392
1393
1394
1395 //
1396 // This function is written by sang cho
1397 // October 12, 1997
1398 //
1399
1400 /* translate parameter part of condensed name */
1401 void WINAPI
1402 GetPreviousParamString (
1403 char *xpin, // read-only source
1404 char *xpout) // translated result
1405 {
1406 int n = 0;
1407 char *pin, *pout;
1408
1409 pin = xpin;
1410 pout = xpout;
1411
1412 pin--;
1413 if (*pin == ',')
1414 pin--;
1415 else
1416 {
1417 printf ("\n **error PreviousParamString1 char = %c", *pin);
1418 exit (0);
1419 }
1420
1421 while (*pin)
1422 {
1423 if (*pin == '>')
1424 n++;
1425 else if (*pin == '<')
1426 n--;
1427 else if (*pin == ')')
1428 n++;
1429
1430 if (n > 0)
1431 {
1432 if (*pin == '(')
1433 n--;
1434 }
1435 else if (strchr (",(", *pin))
1436 break;
1437 pin--;
1438 }
1439
1440 //printf("\n ----- %s", pin);
1441 if (strchr (",(", *pin))
1442 {
1443 pin++;
1444 } // printf("\n %s", pin); }
1445
1446 else
1447 {
1448 printf ("\n **error PreviousParamString2");
1449 exit (0);
1450 }
1451
1452 n = xpin - pin - 1;
1453 strncpy (pout, pin, n);
1454 *(pout + n) = 0;
1455 }
1456
1457
1458
1459
1460 //
1461 // This function is written by sang cho
1462 // October 10, 1997
1463 //
1464
1465 /* translate parameter part of condensed name */
1466 void WINAPI
1467 TranslateParameters (
1468 char **ppin, // read-only source
1469 char **ppout, // translated result
1470 char **pps) // parameter stack
1471 {
1472 int i, n;
1473 char c;
1474 char name[128];
1475 char *pin, *pout, *ps;
1476
1477 //printf(" %c ", **in);
1478 pin = *ppin;
1479 pout = *ppout;
1480 ps = *pps;
1481 c = *pin;
1482 switch (c)
1483 {
1484 // types processing
1485 case 'b':
1486 strcpy (pout, "byte");
1487 pout += 4;
1488 pin++;
1489 break;
1490 case 'c':
1491 strcpy (pout, "char");
1492 pout += 4;
1493 pin++;
1494 break;
1495 case 'd':
1496 strcpy (pout, "double");
1497 pout += 6;
1498 pin++;
1499 break;
1500 case 'f':
1501 strcpy (pout, "float");
1502 pout += 5;
1503 pin++;
1504 break;
1505 case 'g':
1506 strcpy (pout, "long double");
1507 pout += 11;
1508 pin++;
1509 break;
1510 case 'i':
1511 strcpy (pout, "int");
1512 pout += 3;
1513 pin++;
1514 break;
1515 case 'l':
1516 strcpy (pout, "long");
1517 pout += 4;
1518 pin++;
1519 break;
1520 case 's':
1521 strcpy (pout, "short");
1522 pout += 5;
1523 pin++;
1524 break;
1525 case 'v':
1526 strcpy (pout, "void");
1527 pout += 4;
1528 pin++;
1529 break;
1530 // postfix processing
1531 case 'M':
1532 case 'p':
1533 if (*(pin + 1) == 'p')
1534 {
1535 *ps++ = 'p';
1536 pin += 2;
1537 }
1538 else
1539 {
1540 *ps++ = '*';
1541 pin++;
1542 }
1543 *ppin = pin;
1544 *ppout = pout;
1545 *pps = ps;
1546 return;
1547 case 'q':
1548 *pout++ = '(';
1549 pin++;
1550 *ps++ = 'q';
1551 *ppin = pin;
1552 *ppout = pout;
1553 *pps = ps;
1554 return;
1555 case 'r':
1556 if (*(pin + 1) == 'p')
1557 {
1558 *ps++ = 'r';
1559 pin += 2;
1560 }
1561 else
1562 {
1563 *ps++ = '&';
1564 pin++;
1565 }
1566 *ppin = pin;
1567 *ppout = pout;
1568 *pps = ps;
1569 return;
1570 // repeat processing
1571 case 't':
1572 if (isdigit (*(pin + 1)))
1573 {
1574 n = *(pin + 1) - '0';
1575 pin++;
1576 pin++;
1577 GetPreviousParamString (pout, name);
1578 strcpy (pout, name);
1579 pout += strlen (name);
1580 for (i = 1; i < n; i++)
1581 {
1582 *pout++ = ',';
1583 strcpy (pout, name);
1584 pout += strlen (name);
1585 }
1586 }
1587 else
1588 pin++;
1589 break;
1590 // prefix processing
1591 case 'u':
1592 strcpy (pout, "u");
1593 pout += 1;
1594 pin++;
1595 *ppin = pin;
1596 *ppout = pout;
1597 *pps = ps;
1598 return;
1599 case 'x':
1600 strcpy (pout, "const ");
1601 pout += 6;
1602 pin++;
1603 *ppin = pin;
1604 *ppout = pout;
1605 *pps = ps;
1606 return;
1607 case 'z':
1608 strcpy (pout, "static ");
1609 pout += 7;
1610 pin++;
1611 *ppin = pin;
1612 *ppout = pout;
1613 *pps = ps;
1614 return;
1615 default:
1616 strcpy (pout, "!1!");
1617 pout += 3;
1618 *pout++ = *pin++;
1619 *ppin = pin;
1620 *ppout = pout;
1621 *pps = ps;
1622 return;
1623 }
1624 // need to process postfix finally
1625 c = *(ps - 1);
1626 if (strchr ("tqx", c))
1627 {
1628 if (*(pin) && !strchr ("@$%", *(pin)))
1629 *pout++ = ',';
1630 *ppin = pin;
1631 *ppout = pout;
1632 *pps = ps;
1633 return;
1634 }
1635 switch (c)
1636 {
1637 case 'r':
1638 strcpy (pout, "*&");
1639 pout += 2;
1640 ps--;
1641 break;
1642 case 'p':
1643 strcpy (pout, "**");
1644 pout += 2;
1645 ps--;
1646 break;
1647 case '&':
1648 strcpy (pout, "&");
1649 pout += 1;
1650 ps--;
1651 break;
1652 case '*':
1653 strcpy (pout, "*");
1654 pout += 1;
1655 ps--;
1656 break;
1657 default:
1658 strcpy (pout, "!2!");
1659 pout += 3;
1660 ps--;
1661 break;
1662 }
1663 if (*(pin) && !strchr ("@$%", *(pin)))
1664 *pout++ = ',';
1665 *ppin = pin;
1666 *ppout = pout;
1667 *pps = ps;
1668 }
1669
1670
1671 //
1672 // This function is written by sang cho
1673 // October 11, 1997
1674 //
1675
1676 /* translate parameter part of condensed name */
1677 BOOL WINAPI
1678 StringExpands (
1679 char **ppin, // read-only source
1680 char **ppout, // translated result
1681 char **pps, // parameter stack
1682 Str_P * pcstr) // currently stored string
1683 {
1684 // int n;
1685 // char c;
1686 char *pin, *pout, *ps;
1687 Str_P c_str;
1688 BOOL stringMode = TRUE;
1689
1690 pin = *ppin;
1691 pout = *ppout;
1692 ps = *pps;
1693 c_str = *pcstr;
1694
1695 if (strncmp (pin, "bctr", 4) == 0)
1696 {
1697 strncpy (pout, c_str.pos, c_str.length);
1698 pout += c_str.length;
1699 pin += 4;
1700 }
1701 else if (strncmp (pin, "bdtr", 4) == 0)
1702 {
1703 *pout++ = '~';
1704 strncpy (pout, c_str.pos, c_str.length);
1705 pout += c_str.length;
1706 pin += 4;
1707 }
1708 else if (*pin == 'o')
1709 {
1710 strcpy (pout, "const ");
1711 pout += 6;
1712 pin++;
1713 stringMode = FALSE;
1714 }
1715 else if (*pin == 'q')
1716 {
1717 *pout++ = '(';
1718 pin++;
1719 *ps++ = 'q';
1720 stringMode = FALSE;
1721 }
1722 else if (*pin == 't')
1723 {
1724 //if (*(ps-1) == 't') { *pout++ = ','; pin++; } // this also got me...
1725 //else october 12 .. sang
1726 {
1727 *pout++ = '<';
1728 pin++;
1729 *ps++ = 't';
1730 }
1731 stringMode = FALSE;
1732 }
1733 else if (strncmp (pin, "xq", 2) == 0)
1734 {
1735 *pout++ = '(';
1736 pin += 2;
1737 *ps++ = 'x';
1738 *ps++ = 'q';
1739 stringMode = FALSE;
1740 }
1741 else if (strncmp (pin, "bcall", 5) == 0)
1742 {
1743 strcpy (pout, "operator ()");
1744 pout += 11;
1745 pin += 5;
1746 }
1747 else if (strncmp (pin, "bsubs", 5) == 0)
1748 {
1749 strcpy (pout, "operator []");
1750 pout += 11;
1751 pin += 5;
1752 }
1753 else if (strncmp (pin, "bnwa", 4) == 0)
1754 {
1755 strcpy (pout, "operator new[]");
1756 pout += 14;
1757 pin += 4;
1758 }
1759 else if (strncmp (pin, "bdla", 4) == 0)
1760 {
1761 strcpy (pout, "operator delete[]");
1762 pout += 17;
1763 pin += 4;
1764 }
1765 else if (strncmp (pin, "bnew", 4) == 0)
1766 {
1767 strcpy (pout, "operator new");
1768 pout += 12;
1769 pin += 4;
1770 }
1771 else if (strncmp (pin, "bdele", 5) == 0)
1772 {
1773 strcpy (pout, "operator delete");
1774 pout += 15;
1775 pin += 5;
1776 }
1777 else if (strncmp (pin, "blsh", 4) == 0)
1778 {
1779 strcpy (pout, "operator <<");
1780 pout += 11;
1781 pin += 4;
1782 }
1783 else if (strncmp (pin, "brsh", 4) == 0)
1784 {
1785 strcpy (pout, "operator >>");
1786 pout += 11;
1787 pin += 4;
1788 }
1789 else if (strncmp (pin, "binc", 4) == 0)
1790 {
1791 strcpy (pout, "operator ++");
1792 pout += 11;
1793 pin += 4;
1794 }
1795 else if (strncmp (pin, "bdec", 4) == 0)
1796 {
1797 strcpy (pout, "operator --");
1798 pout += 11;
1799 pin += 4;
1800 }
1801 else if (strncmp (pin, "badd", 4) == 0)
1802 {
1803 strcpy (pout, "operator +");
1804 pout += 10;
1805 pin += 4;
1806 }
1807 else if (strncmp (pin, "brplu", 5) == 0)
1808 {
1809 strcpy (pout, "operator +=");
1810 pout += 11;
1811 pin += 5;
1812 }
1813 else if (strncmp (pin, "bdiv", 4) == 0)
1814 {
1815 strcpy (pout, "operator /");
1816 pout += 10;
1817 pin += 4;
1818 }
1819 else if (strncmp (pin, "brdiv", 5) == 0)
1820 {
1821 strcpy (pout, "operator /=");
1822 pout += 11;
1823 pin += 5;
1824 }
1825 else if (strncmp (pin, "bmul", 4) == 0)
1826 {
1827 strcpy (pout, "operator *");
1828 pout += 10;
1829 pin += 4;
1830 }
1831 else if (strncmp (pin, "brmul", 5) == 0)
1832 {
1833 strcpy (pout, "operator *=");
1834 pout += 11;
1835 pin += 5;
1836 }
1837 else if (strncmp (pin, "basg", 4) == 0)
1838 {
1839 strcpy (pout, "operator =");
1840 pout += 10;
1841 pin += 4;
1842 }
1843 else if (strncmp (pin, "beql", 4) == 0)
1844 {
1845 strcpy (pout, "operator ==");
1846 pout += 11;
1847 pin += 4;
1848 }
1849 else if (strncmp (pin, "bneq", 4) == 0)
1850 {
1851 strcpy (pout, "operator !=");
1852 pout += 11;
1853 pin += 4;
1854 }
1855 else if (strncmp (pin, "bor", 3) == 0)
1856 {
1857 strcpy (pout, "operator |");
1858 pout += 10;
1859 pin += 3;
1860 }
1861 else if (strncmp (pin, "bror", 4) == 0)
1862 {
1863 strcpy (pout, "operator |=");
1864 pout += 11;
1865 pin += 4;
1866 }
1867 else if (strncmp (pin, "bcmp", 4) == 0)
1868 {
1869 strcpy (pout, "operator ~");
1870 pout += 10;
1871 pin += 4;
1872 }
1873 else if (strncmp (pin, "bnot", 4) == 0)
1874 {
1875 strcpy (pout, "operator !");
1876 pout += 10;
1877 pin += 4;
1878 }
1879 else if (strncmp (pin, "band", 4) == 0)
1880 {
1881 strcpy (pout, "operator &");
1882 pout += 10;
1883 pin += 4;
1884 }
1885 else if (strncmp (pin, "brand", 5) == 0)
1886 {
1887 strcpy (pout, "operator &=");
1888 pout += 11;
1889 pin += 5;
1890 }
1891 else if (strncmp (pin, "bxor", 4) == 0)
1892 {
1893 strcpy (pout, "operator ^");
1894 pout += 10;
1895 pin += 4;
1896 }
1897 else if (strncmp (pin, "brxor", 5) == 0)
1898 {
1899 strcpy (pout, "operator ^=");
1900 pout += 11;
1901 pin += 5;
1902 }
1903 else
1904 {
1905 strcpy (pout, "!$$$!");
1906 pout += 5;
1907 }
1908 *ppin = pin;
1909 *ppout = pout;
1910 *pps = ps;
1911 return stringMode;
1912 } // end of '$' processing
1913
1914
1915
1916 //----------------------------------------------------------------------
1917 // structure to store string tokens
1918 //----------------------------------------------------------------------
1919 //typedef struct _Str_P {
1920 // char flag; // string_flag '@' or '%' or '#'
1921 // char *pos; // starting postion of string
1922 // int length; // length of string
1923 // BOOL wasString; // if it were stringMode or not
1924 //} Str_P;
1925 //----------------------------------------------------------------------
1926 //
1927 // I think I knocked it down finally. But who knows?
1928 // october 12, 1997 ... sang
1929 //
1930 // well I have to rewrite whole part of TranslateFunctionName..
1931 // this time I am a little bit more experienced than 5 days ago.
1932 // or am i??? anyway i use stacks instead of recurcive calls
1933 // and i hope this will take care of every symptoms i have experienced..
1934 // october 10, 1997 .... sang
1935 // It took a lot of time for me to figure out what is all about....
1936 // but still some prefixes like z (static)
1937 // -- or some types like b (byte) ,g (long double) ,s (short) --
1938 // -- or postfix like M ( * )
1939 // -- or $or ( & ) which is pretty wierd. .. added.. october 12
1940 // -- also $t business is quite tricky too. (templates)
1941 // there may be a lot of things undiscovered yet....
1942 // I am not so sure my interpretation is correct or not
1943 // If I am wrong please let me know.
1944 // october 8, 1997 .... sang
1945 //
1946 //
1947 // This function is written by sang cho
1948 // October 5, 1997
1949 //
1950 /* translate condesed import function name */
1951 LPVOID WINAPI
1952 TranslateFunctionName (
1953 char *psz)
1954 {
1955
1956
1957 int i, j, n;
1958 char c, cc;
1959
1960 static char buff[512]; // result of translation
1961
1962 int is = 0;
1963 char pStack[32]; // parameter processing stack
1964
1965 Str_P sStack[32]; // String processing stack
1966
1967 Str_P tok; // String token
1968
1969 Str_P c_str; // current string
1970
1971 int iend = 0;
1972 char *endTab[8]; // end of string position check
1973
1974 char *ps;
1975 char *pin, *pout;
1976 BOOL stringMode = TRUE;
1977
1978 if (*psz != '@')
1979 return psz;
1980 pin = psz;
1981 pout = buff;
1982 ps = pStack;
1983
1984 //................................................................
1985 // serious users may need to run the following code.
1986 // so I may need to include some flag options...
1987 // If you want to know about how translation is done,
1988 // you can just revive following line and you can see it.
1989 // october 6, 1997 ... sang cho
1990 //printf ("\n................................... %s", psz); // for debugging...
1991
1992 //pa = pb = pout;
1993 pin++;
1994 tok.flag = 'A';
1995 tok.pos = pout;
1996 tok.length = 0;
1997 tok.wasString = stringMode;
1998 sStack[is++] = tok; // initialize sStack with dummy marker
1999
2000 while (*pin)
2001 {
2002 while (*pin)
2003 {
2004 c = *pin;
2005
2006 //---------------------------------------------
2007 // check for the end of number specified string
2008 //---------------------------------------------
2009
2010 if (iend > 0)
2011 {
2012 for (i = 0; i < iend; i++)
2013 if (pin == endTab[i])
2014 break;
2015 if (i < iend)
2016 {
2017 // move the end of endTab to ith position
2018 endTab[i] = endTab[iend - 1];
2019 iend--;
2020
2021 // get top of the string stack
2022 tok = sStack[is - 1];
2023
2024 // I am expecting '#' token from stack
2025 if (tok.flag != '#')
2026
2027 {
2028 printf ("\n**some serious error1** %c is = %d char = %c",
2029 tok.flag, is, *pin);
2030 exit (0);
2031 }
2032
2033 // pop '#' token I am happy now.
2034 else
2035 { //if (c)
2036 //printf("\n pop # token ... current char = %c", c);
2037 //else printf("\n pop percent token..next char = NULL");
2038
2039 is--;
2040 }
2041
2042 stringMode = tok.wasString;
2043
2044 if (!stringMode)
2045 {
2046 // need to process postfix finally
2047 cc = *(ps - 1);
2048 if (strchr ("qtx", cc))
2049 {
2050 if (!strchr ("@$%", c))
2051 *pout++ = ',';
2052 }
2053 else
2054 {
2055 switch (cc)
2056 {
2057 case 'r':
2058 strcpy (pout, "*&");
2059 pout += 2;
2060 ps--;
2061 break;
2062 case 'p':
2063 strcpy (pout, "**");
2064 pout += 2;
2065 ps--;
2066 break;
2067 case '&':
2068 strcpy (pout, "&");
2069 pout += 1;
2070 ps--;
2071 break;
2072 case '*':
2073 strcpy (pout, "*");
2074 pout += 1;
2075 ps--;
2076 break;
2077 default:
2078 strcpy (pout, "!3!");
2079 pout += 3;
2080 ps--;
2081 break;
2082 }
2083 if (!strchr ("@$%", c))
2084 *pout++ = ',';
2085 }
2086 }
2087 // string mode restored...
2088 else;
2089 }
2090 else; // do nothing..
2091
2092 }
2093
2094 //------------------------------------------------
2095 // special control symbol processing:
2096 //------------------------------------------------
2097
2098 if (strchr ("@$%", c))
2099 break;
2100
2101 //---------------------------------------------------------------
2102 // string part processing : no '$' met yet
2103 // or inside of '%' block
2104 // or inside of '#' block (numbered string)
2105 //---------------------------------------------------------------
2106
2107 else if (stringMode)
2108 *pout++ = *pin++;
2109 //else if (is > 1) *pout++ = *pin++;
2110
2111 //------------------------------------------------
2112 // parameter part processing: '$' met
2113 //------------------------------------------------
2114
2115 else // parameter processing
2116
2117 {
2118 if (!isdigit (c))
2119 TranslateParameters (&pin, &pout, &ps);
2120 else // number specified string processing
2121
2122 {
2123 n = GetStringLength (pin);
2124 if (n < 10)
2125 pin++;
2126 else
2127 pin += 2;
2128
2129 // push '#' token
2130 //if (*pin)
2131 //printf("\n push # token .. char = %c", *pin);
2132 //else printf("\n push percent token..next char = NULL");
2133 tok.flag = '#';
2134 tok.pos = pout;
2135 tok.length = 0;
2136 tok.wasString = stringMode;
2137 sStack[is++] = tok;
2138
2139 // mark end of input string
2140 endTab[iend++] = pin + n;
2141 stringMode = TRUE;
2142 }
2143 }
2144 } // end of inner while loop
2145 //
2146 // beginning of new string or end of string ( quotation mark )
2147 //
2148
2149 if (c == '%')
2150 {
2151 pin++; // anyway we have to proceed...
2152
2153 tok = sStack[is - 1]; // get top of the sStack
2154
2155 if (tok.flag == '%')
2156 {
2157 // pop '%' token and set c_str
2158 //if (*pin)
2159 //printf("\n pop percent token..next char = %c", *pin);
2160 //else printf("\n pop percent token..next char = NULL");
2161 is--;
2162 c_str = tok;
2163 c_str.length = pout - c_str.pos;
2164 if (*(ps - 1) == 't')
2165 {
2166 *pout++ = '>';
2167 ps--;
2168 stringMode = tok.wasString;
2169 }
2170 else
2171 {
2172 printf ("\n**some string error3** stack = %c", *(ps - 1));
2173 exit (0);
2174 }
2175 }
2176 else if (tok.flag == 'A' || tok.flag == '#')
2177 {
2178 // push '%' token
2179 //if (*pin)
2180 //printf("\n push percent token..next char = %c", *pin);
2181 //else printf("\n push percent token..next char = NULL");
2182 tok.flag = '%';
2183 tok.pos = pout;
2184 tok.length = 0;
2185 tok.wasString = stringMode;
2186 sStack[is++] = tok;
2187 }
2188 else
2189 {
2190 printf ("\n**some string error5**");
2191 exit (0);
2192 }
2193 }
2194 //
2195 // sometimes we need string to use as constructor name or destructor name
2196 //
2197 else if (c == '@') // get string from previous marker upto here.
2198
2199 {
2200 pin++;
2201 tok = sStack[is - 1];
2202 c_str.flag = 'S';
2203 c_str.pos = tok.pos;
2204 c_str.length = pout - tok.pos;
2205 c_str.wasString = stringMode;
2206 *pout++ = ':';
2207 *pout++ = ':';
2208 }
2209 //
2210 // we need to take care of parameter control sequence
2211 //
2212 else if (c == '$') // need to precess template or parameter part
2213
2214 {
2215 pin++;
2216 if (stringMode)
2217 stringMode = StringExpands (&pin, &pout, &ps, &c_str);
2218 else
2219 { // template parameter mode I guess "$t"
2220
2221 if (is > 1)
2222 {
2223 if (*pin == 't')
2224 pin++;
2225 else
2226 {
2227 printf ("\nMYGOODNESS1 %c", *pin);
2228 exit (0);
2229 }
2230 //ps--;
2231 //if (*ps == 't') *pout++ = '>';
2232 //else { printf("\nMYGOODNESS2"); exit(0);}
2233 *pout++ = ','; //pin++; ..this almost blowed me....
2234
2235 }
2236 // real parameter mode I guess
2237 // unexpected case is found ... humm what can I do...
2238 else
2239 {
2240 // this is newly found twist.. it really hurts.
2241 if (ps <= pStack)
2242 {
2243 if (*pin == 'q')
2244 {
2245 *ps++ = 'q';
2246 *pout++ = '(';
2247 pin++;
2248 }
2249 else
2250 {
2251 printf ("\n** I GIVEUP ***");
2252 exit (0);
2253 }
2254 continue;
2255 }
2256 ps--;
2257 while (*ps != 'q')
2258 {
2259 if (*ps == '*')
2260 *pout++ = '*';
2261 else if (*ps == '&')
2262 *pout++ = '&';
2263 else if (*ps == 'p')
2264 {
2265 *pout++ = '*';
2266 *pout++ = '*';
2267 }
2268 else if (*ps == 'r')
2269 {
2270 *pout++ = '*';
2271 *pout++ = '&';
2272 }
2273 else
2274 {
2275 printf ("\n*** SOMETHING IS WRONG1*** char= %c", *pin);
2276 exit (0);
2277 }
2278 ps--;
2279 }
2280 *pout++ = ')';
2281 ps--;
2282 while (*ps != 'q')
2283 {
2284 if (*ps == '*')
2285 *pout++ = '*';
2286 else if (*ps == '&')
2287 *pout++ = '&';
2288 else if (*ps == 'p')
2289 {
2290 *pout++ = '*';
2291 *pout++ = '*';
2292 }
2293 else if (*ps == 'r')
2294 {
2295 *pout++ = '*';
2296 *pout++ = '&';
2297 }
2298 else
2299 {
2300 printf ("\n*** SOMETHING IS WRONG2***");
2301 exit (0);
2302 }
2303 ps--;
2304 }
2305 ps++;
2306 *pout++ = ',';
2307 }
2308 }
2309 } // end of '$' processing
2310
2311 } // end of outer while loop
2312 //
2313 // need to process remaining parameter stack
2314 //
2315
2316 while (ps > pStack)
2317 {
2318 ps--;
2319 switch (*ps)
2320 {
2321 case 't':
2322 *pout++ = '>';
2323 break;
2324 case 'q':
2325 *pout++ = ')';
2326 break;
2327 case 'x':
2328 strcpy (pout, " const");
2329 pout += 6;
2330 break;
2331 case 'r':
2332 strcpy (pout, "*&");
2333 pout += 2;
2334 break;
2335 case 'p':
2336 strcpy (pout, "**");
2337 pout += 2;
2338 break;
2339 case '&':
2340 *pout++ = '&';
2341 break;
2342 case '*':
2343 *pout++ = '*';
2344 break;
2345 default:
2346 strcpy (pout, "!4!");
2347 pout += 3;
2348 *pout++ = *ps;
2349 }
2350 }
2351 *pout = 0;
2352 return buff;
2353 }
2354
2355
2356
2357 //
2358 // This function is written by sang cho
2359 //
2360 //
2361 /* get exported function names separated by null terminators, return count of functions */
2362 int WINAPI
2363 GetExportFunctionNames (
2364 LPVOID lpFile,
2365 char **pszFunctions)
2366 {
2367 //PIMAGE_SECTION_HEADER psh;
2368 PIMAGE_EXPORT_DIRECTORY ped;
2369 //DWORD dwBase;
2370 DWORD imageBase; //===========================
2371
2372 char *pfns[8192] =
2373 {NULL,}; // maximum number of functions
2374 //=============================
2375
2376 char buff[256]; // enough for any string ??
2377
2378 char *psz; //===============================
2379
2380 DWORD *pdwAddress;
2381 DWORD *pdw1;
2382 DWORD *pdwNames;
2383 WORD *pwOrd;
2384 int i, nCnt = 0, ntmp = 0;
2385 int enid = 0, ordBase = 1; // usally ordBase is 1....
2386
2387 int enames = 0;
2388
2389 /* get section header and pointer to data directory for .edata section */
2390 ped = (PIMAGE_EXPORT_DIRECTORY)
2391 ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2392
2393 if (ped == NULL)
2394 return 0;
2395
2396 //
2397 // sometimes there may be no section for idata or edata
2398 // instead rdata or data section may contain these sections ..
2399 // or even module names or function names are in different section.
2400 // so that's why we need to get actual address each time.
2401 // ...................sang cho..................
2402 //
2403 //psh = (PIMAGE_SECTION_HEADER)
2404 //ImageDirectorySection(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT);
2405
2406 //if (psh == NULL) return 0;
2407
2408 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2409
2410
2411 /* determine the offset of the export function names */
2412
2413 pdwAddress = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfFunctions);
2414
2415 imageBase = (DWORD) GetImageBase (lpFile);
2416
2417 ordBase = ped->Base;
2418
2419 if (ped->NumberOfNames > 0)
2420 {
2421 pdwNames = (DWORD *)
2422 GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2423 pwOrd = (WORD *)
2424 GetActualAddress (lpFile, (DWORD) ped->AddressOfNameOrdinals);
2425 pdw1 = pdwAddress;
2426
2427 /* figure out how much memory to allocate for all strings */
2428 for (i = 0; i < (int) ped->NumberOfNames; i++)
2429 {
2430 nCnt += strlen ((char *)
2431 GetActualAddress (lpFile, *(DWORD *) pdwNames)) + 1 + 6;
2432 pdwNames++;
2433 }
2434 // get the number of unnamed functions
2435 for (i = 0; i < (int) ped->NumberOfFunctions; i++)
2436 if (*pdw1++)
2437 ntmp++;
2438 // add memory required to show unnamed functions.
2439 if (ntmp > (int) ped->NumberOfNames)
2440 nCnt += 18 * (ntmp - (int) ped->NumberOfNames);
2441
2442 /* allocate memory for function names */
2443
2444 *pszFunctions = (char *) calloc (nCnt, 1);
2445 pdwNames = (DWORD *) GetActualAddress (lpFile, (DWORD) ped->AddressOfNames);
2446
2447 /* copy string pointer to buffer */
2448
2449 for (i = 0; i < (int) ped->NumberOfNames; i++)
2450 {
2451 pfns[(int) (*pwOrd) + ordBase] =
2452 (char *) GetActualAddress (lpFile, *(DWORD *) pdwNames);
2453 pdwNames++;
2454 pwOrd++;
2455 }
2456
2457 psz = *pszFunctions;
2458 }
2459
2460 for (i = ordBase; i < (int) ped->NumberOfFunctions + ordBase; i++)
2461 {
2462 if (*pdwAddress > 0)
2463 {
2464 *(DWORD *) psz = imageBase + *pdwAddress;
2465 psz += 4;
2466 *(WORD *) psz = (WORD) (i);
2467 psz += 2;
2468 if (pfns[i])
2469 {
2470 strcpy (psz, pfns[i]);
2471 psz += strlen (psz) + 1;
2472 }
2473 else
2474 {
2475 sprintf (buff, "ExpFn%04d()", enid++);
2476 strcpy (psz, buff);
2477 psz += 12;
2478 }
2479 enames++;
2480 }
2481 pdwAddress++;
2482 }
2483
2484 return enames;
2485
2486 }
2487
2488
2489 /* determine the total number of resources in the section */
2490 int WINAPI
2491 GetNumberOfResources (
2492 LPVOID lpFile)
2493 {
2494 PIMAGE_RESOURCE_DIRECTORY prdRoot, prdType;
2495 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2496 int nCnt = 0, i;
2497
2498
2499 /* get root directory of resource tree */
2500 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2501 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2502 return 0;
2503
2504 /* set pointer to first resource type entry */
2505 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2506
2507 /* loop through all resource directory entry types */
2508 for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2509 {
2510 /* locate directory or each resource type */
2511 prdType = (PIMAGE_RESOURCE_DIRECTORY) ((int) prdRoot + (int) prde->OffsetToData);
2512
2513 /* mask off most significant bit of the data offset */
2514 prdType = (PIMAGE_RESOURCE_DIRECTORY) ((DWORD) prdType ^ 0x80000000);
2515
2516 /* increment count of name'd and ID'd resources in directory */
2517 nCnt += prdType->NumberOfNamedEntries + prdType->NumberOfIdEntries;
2518
2519 /* increment to next entry */
2520 prde++;
2521 }
2522
2523 return nCnt;
2524 }
2525
2526
2527
2528 //
2529 // This function is rewritten by sang cho
2530 //
2531 //
2532 /* name each type of resource in the section */
2533 int WINAPI
2534 GetListOfResourceTypes (
2535 LPVOID lpFile,
2536 char **pszResTypes)
2537 {
2538 PIMAGE_RESOURCE_DIRECTORY prdRoot;
2539 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde;
2540 char *pMem;
2541 char buff[32];
2542 int nCnt, i;
2543 DWORD prdeName;
2544
2545
2546 /* get root directory of resource tree */
2547 if ((prdRoot = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2548 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2549 return 0;
2550
2551 /* allocate enuff space to cover all types */
2552 nCnt = prdRoot->NumberOfIdEntries * (MAXRESOURCENAME + 1);
2553 *pszResTypes = (char *) calloc (nCnt, 1);
2554 if ((pMem = *pszResTypes) == NULL)
2555 return 0;
2556
2557 /* set pointer to first resource type entry */
2558 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ((DWORD) prdRoot + sizeof (IMAGE_RESOURCE_DIRECTORY));
2559
2560 /* loop through all resource directory entry types */
2561 for (i = 0; i < prdRoot->NumberOfIdEntries; i++)
2562 {
2563 prdeName = prde->Name;
2564
2565 //if (LoadString (hDll, prde->Name, pMem, MAXRESOURCENAME))
2566 // pMem += strlen (pMem) + 1;
2567 //
2568 // modified by ...................................Sang Cho..
2569 // I can't user M/S provied funcitons here so I have to figure out
2570 // how to do above functions. But I can settle down with the following
2571 // code, which works pretty good for me.
2572 //
2573 if (prdeName == 1)
2574 {
2575 strcpy (pMem, "RT_CURSOR");
2576 pMem += 10;
2577 }
2578 else if (prdeName == 2)
2579 {
2580 strcpy (pMem, "RT_BITMAP");
2581 pMem += 10;
2582 }
2583 else if (prdeName == 3)
2584 {
2585 strcpy (pMem, "RT_ICON ");
2586 pMem += 10;
2587 }
2588 else if (prdeName == 4)
2589 {
2590 strcpy (pMem, "RT_MENU ");
2591 pMem += 10;
2592 }
2593 else if (prdeName == 5)
2594 {
2595 strcpy (pMem, "RT_DIALOG");
2596 pMem += 10;
2597 }
2598 else if (prdeName == 6)
2599 {
2600 strcpy (pMem, "RT_STRING");
2601 pMem += 10;
2602 }
2603 else if (prdeName == 7)
2604 {
2605 strcpy (pMem, "RT_FONTDIR");
2606 pMem += 11;
2607 }
2608 else if (prdeName == 8)
2609 {
2610 strcpy (pMem, "RT_FONT ");
2611 pMem += 10;
2612 }
2613 else if (prdeName == 9)
2614 {
2615 strcpy (pMem, "RT_ACCELERATORS");
2616 pMem += 16;
2617 }
2618 else if (prdeName == 10)
2619 {
2620 strcpy (pMem, "RT_RCDATA");
2621 pMem += 10;
2622 }
2623 else if (prdeName == 11)
2624 {
2625 strcpy (pMem, "RT_MESSAGETABLE");
2626 pMem += 16;
2627 }
2628 else if (prdeName == 12)
2629 {
2630 strcpy (pMem, "RT_GROUP_CURSOR");
2631 pMem += 16;
2632 }
2633 else if (prdeName == 14)
2634 {
2635 strcpy (pMem, "RT_GROUP_ICON ");
2636 pMem += 16;
2637 }
2638 else if (prdeName == 16)
2639 {
2640 strcpy (pMem, "RT_VERSION");
2641 pMem += 11;
2642 }
2643 else if (prdeName == 17)
2644 {
2645 strcpy (pMem, "RT_DLGINCLUDE ");
2646 pMem += 16;
2647 }
2648 else if (prdeName == 19)
2649 {
2650 strcpy (pMem, "RT_PLUGPLAY ");
2651 pMem += 16;
2652 }
2653 else if (prdeName == 20)
2654 {
2655 strcpy (pMem, "RT_VXD ");
2656 pMem += 10;
2657 }
2658 else if (prdeName == 21)
2659 {
2660 strcpy (pMem, "RT_ANICURSOR ");
2661 pMem += 16;
2662 }
2663 else if (prdeName == 22)
2664 {
2665 strcpy (pMem, "RT_ANIICON");
2666 pMem += 11;
2667 }
2668 else if (prdeName == 0x2002)
2669 {
2670 strcpy (pMem, "RT_NEWBITMAP");
2671 pMem += 13;
2672 }
2673 else if (prdeName == 0x2004)
2674 {
2675 strcpy (pMem, "RT_NEWMENU");
2676 pMem += 11;
2677 }
2678 else if (prdeName == 0x2005)
2679 {
2680 strcpy (pMem, "RT_NEWDIALOG");
2681 pMem += 13;
2682 }
2683 else if (prdeName == 0x7fff)
2684 {
2685 strcpy (pMem, "RT_ERROR ");
2686 pMem += 10;
2687 }
2688 else
2689 {
2690 sprintf (buff, "RT_UNKNOWN:%08X", prdeName);
2691 strcpy (pMem, buff);
2692 pMem += 20;
2693 }
2694 prde++;
2695 }
2696
2697 return prdRoot->NumberOfIdEntries;
2698 }
2699
2700
2701
2702 //
2703 // This function is written by sang cho
2704 // October 12, 1997
2705 //
2706 /* copy menu information */
2707 void WINAPI
2708 StrangeMenuFill (
2709 char **psz, // results
2710 WORD ** pMenu, // read-only
2711 int size)
2712 {
2713 WORD *pwd;
2714 WORD *ptr, *pmax;
2715
2716 pwd = *pMenu;
2717 pmax = (WORD *) ((DWORD) pwd + size);
2718 ptr = (WORD *) (*psz);
2719
2720 while (pwd < pmax)
2721 {
2722 *ptr++ = *pwd++;
2723 }
2724 *psz = (char *) ptr;
2725 *pMenu = pwd;
2726 }
2727
2728
2729
2730 //
2731 // This function is written by sang cho
2732 // October 1, 1997
2733 //
2734 /* obtain menu information */
2735 int WINAPI
2736 MenuScan (
2737 int *len,
2738 WORD ** pMenu)
2739 {
2740 int num = 0;
2741 int ndetails;
2742 WORD *pwd;
2743 WORD flag, flag1;
2744 WORD id, ispopup;
2745
2746
2747 pwd = *pMenu;
2748
2749 flag = *pwd; // so difficult to correctly code this so let's try this
2750
2751 pwd++;
2752 (*len) += 2; // flag store
2753
2754 if ((flag & 0x0010) == 0)
2755 {
2756 ispopup = flag;
2757 id = *pwd;
2758 pwd++;
2759 (*len) += 2; // id store
2760
2761 }
2762 else
2763 {
2764 ispopup = flag;
2765 }
2766
2767 while (*pwd)
2768 {
2769 (*len)++;
2770 pwd++;
2771 }
2772 (*len)++; // name and null character
2773
2774 pwd++; // skip double null
2775
2776 if ((flag & 0x0010) == 0) // normal node: done
2777
2778 {
2779 *pMenu = pwd;
2780 return (int) flag;
2781 }
2782 // popup node: need to go on...
2783 while (1)
2784 {
2785 *pMenu = pwd;
2786 flag1 = (WORD) MenuScan (len, pMenu);
2787 pwd = *pMenu;
2788 if (flag1 & 0x0080)
2789 break;
2790 }
2791 // fill # of details to num above
2792 //(*len) += 2;
2793 *pMenu = pwd;
2794 return flag;
2795 }
2796
2797
2798 //
2799 // This function is written by sang cho
2800 // October 2, 1997
2801 //
2802 /* copy menu information */
2803 int WINAPI
2804 MenuFill (
2805 char **psz,
2806 WORD ** pMenu)
2807 {
2808 int num = 0;
2809 int ndetails;
2810 char *ptr, *pTemp;
2811 WORD *pwd;
2812 WORD flag, flag1;
2813 WORD id, ispopup;
2814
2815 ptr = *psz;
2816 pwd = *pMenu;
2817 //flag = (*(PIMAGE_POPUP_MENU_ITEM *)pwd)->fItemFlags;
2818 flag = *pwd; // so difficult to correctly code this so let's try this
2819
2820 pwd++;
2821 if ((flag & 0x0010) == 0)
2822 {
2823 *(WORD *) ptr = flag; // flag store
2824
2825 ptr += 2;
2826 *(WORD *) ptr = id = *pwd; // id store
2827
2828 ptr += 2;
2829 pwd++;
2830 }
2831 else
2832 {
2833 *(WORD *) ptr = flag; // flag store
2834
2835 ptr += 2;
2836 }
2837
2838 while (*pwd) // name extract
2839
2840 {
2841 *ptr = *(char *) pwd;
2842 ptr++;
2843 pwd++;
2844 } //name and null character
2845
2846 *ptr = 0;
2847 ptr++;
2848 pwd++; // skip double null
2849
2850 if ((flag & 0x0010) == 0) // normal node: done
2851
2852 {
2853 *pMenu = pwd;
2854 *psz = ptr;
2855 return (int) flag;
2856 }
2857 //pTemp = ptr;
2858 //ptr += 2;
2859 // popup node: need to go on...
2860 while (1)
2861 {
2862 //num++;
2863 *pMenu = pwd;
2864 *psz = ptr;
2865 flag1 = (WORD) MenuFill (psz, pMenu);
2866 pwd = *pMenu;
2867 ptr = *psz;
2868 if (flag1 & 0x0080)
2869 break;
2870 }
2871 // fill # of details to num above
2872 //*(WORD *)pTemp = (WORD)num;
2873 *pMenu = pwd;
2874 *psz = ptr;
2875 return flag;
2876 }
2877
2878
2879 //
2880 //==============================================================================
2881 // The following program is based on preorder-tree-traversal.
2882 // once you understand how to traverse.....
2883 // the rest is pretty straight forward.
2884 // still we need to scan it first and fill it next time.
2885 // and finally we can print it.
2886 //
2887 // This function is written by sang cho
2888 // September 29, 1997
2889 // revised october 2, 1997
2890 // revised october 12, 1997
2891 // ..............................................................................
2892 // ------------------------------------------------------------------------------
2893 // I use same structure - which is used in P.E. programs - for my reporting.
2894 // So, my structure is as follows:
2895 // # of menu name is stored else where ( in directory I suppose )
2896 // supermenuname null terminated string, only ascii is considered.
2897 // flag tells : node is a leaf or a internal node.
2898 // popupname null terminated string
2899 //
2900 // flag normal menu flag (leaf node)
2901 // id normal menu id
2902 // name normal menu name
2903 // or or
2904 // flag popup menu flag (internal node)
2905 // popupname popup menu name
2906 //
2907 // flag it may folows
2908 // id normal menu id
2909 // name normal menu name
2910 // or or
2911 // flag popup menu
2912 // popupname popup menu name
2913 // .........
2914 // it goes on like this,
2915 // but usually, it only goes a few steps,...
2916 // ------------------------------------------------------------------------------
2917 /* scan menu and copy menu */
2918 int WINAPI
2919 GetContentsOfMenu (
2920 LPVOID lpFile,
2921 char **pszResTypes)
2922 {
2923 PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage;
2924 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1;
2925 PIMAGE_RESOURCE_DIR_STRING_U pMenuName;
2926 PIMAGE_RESOURCE_DATA_ENTRY prData;
2927 //PIMAGE_SECTION_HEADER psh = (PIMAGE_SECTION_HEADER)
2928 //ImageDirectorySection (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE);
2929 PIMAGE_MENU_HEADER pMenuHeader;
2930 PIMAGE_POPUP_MENU_ITEM pPopup;
2931 PIMAGE_NORMAL_MENU_ITEM pNormal;
2932 char buff[32];
2933 int nCnt = 0, i, j;
2934 int num = 0;
2935 int size;
2936 int sLength, nMenus;
2937 WORD flag;
2938 WORD *pwd;
2939 DWORD prdeName;
2940 //DWORD dwBase; obsolete
2941 char *pMem, *pTemp;
2942 BOOL isStrange = FALSE;
2943
2944
2945 /* get root directory of resource tree */
2946 if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
2947 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
2948 return 0;
2949
2950 /* set pointer to first resource type entry */
2951 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2952 ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
2953
2954 for (i = 0; i < prdType->NumberOfIdEntries; i++)
2955 {
2956 if (prde->Name == RT_MENU)
2957 break;
2958 prde++;
2959 }
2960 if (prde->Name != RT_MENU)
2961 return 0;
2962
2963 prdName = (PIMAGE_RESOURCE_DIRECTORY)
2964 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2965 if (prdName == NULL)
2966 return 0;
2967
2968 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2969 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
2970
2971 // sometimes previous code tells you lots of things hidden underneath
2972 // I wish I could save all the revisions I made ... but again .... sigh.
2973 // october 12, 1997 sang
2974 //dwBase = (DWORD)((int)lpFile + psh->PointerToRawData - psh->VirtualAddress);
2975
2976 nMenus = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
2977 sLength = 0;
2978
2979 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
2980 {
2981 pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
2982 ((DWORD) prdType + (prde->Name ^ 0x80000000));
2983 sLength += pMenuName->Length + 1;
2984
2985 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
2986 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
2987 if (prdLanguage == NULL)
2988 continue;
2989
2990 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
2991 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
2992
2993 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
2994 ((DWORD) prdType + prde1->OffsetToData);
2995 if (prData == NULL)
2996 continue;
2997
2998 pMenuHeader = (PIMAGE_MENU_HEADER)
2999 GetActualAddress (lpFile, prData->OffsetToData);
3000
3001 //
3002 // normally wVersion and cbHeaderSize should be zero
3003 // but if it is not then nothing is known to us...
3004 // so let's do our best ... namely guessing .... and trying ....
3005 // ... and suffering ...
3006 // it gave me many sleepless (not exactly but I like to say this) nights.
3007 //
3008
3009 // strange case
3010 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3011 {
3012 //isStrange = TRUE;
3013 pwd = (WORD *) ((DWORD) pMenuHeader + 16);
3014 size = prData->Size;
3015 // expect to return the length needed to report.
3016 // sixteen more bytes to do something
3017 sLength += 16 + size;
3018 //StrangeMenuScan (&sLength, &pwd, size);
3019 }
3020 // normal case
3021 else
3022 {
3023 pPopup = (PIMAGE_POPUP_MENU_ITEM)
3024 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3025 while (1)
3026 {
3027 flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3028 if (flag & 0x0080)
3029 break;
3030 }
3031 }
3032 prde++;
3033 }
3034 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3035 {
3036 sLength += 12;
3037
3038 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3039 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3040 if (prdLanguage == NULL)
3041 continue;
3042
3043 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3044 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3045
3046 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3047 ((DWORD) prdType + prde1->OffsetToData);
3048 if (prData == NULL)
3049 continue;
3050
3051 pMenuHeader = (PIMAGE_MENU_HEADER)
3052 GetActualAddress (lpFile, prData->OffsetToData);
3053 // strange case
3054 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3055 {
3056 pwd = (WORD *) ((DWORD) pMenuHeader + 16);
3057 size = prData->Size;
3058 // expect to return the length needed to report.
3059 // sixteen more bytes to do something
3060 sLength += 16 + size;
3061 //StrangeMenuScan (&sLength, &pwd, size);
3062 }
3063 // normal case
3064 else
3065 {
3066 pPopup = (PIMAGE_POPUP_MENU_ITEM)
3067 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3068 while (1)
3069 {
3070 flag = (WORD) MenuScan (&sLength, (WORD **) (&pPopup));
3071 if (flag & 0x0080)
3072 break;
3073 }
3074 }
3075 prde++;
3076 }
3077 //
3078 // allocate memory for menu names
3079 //
3080 *pszResTypes = (char *) calloc (sLength, 1);
3081
3082 pMem = *pszResTypes;
3083 //
3084 // and start all over again
3085 //
3086 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3087 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3088
3089 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3090 {
3091 pMenuName = (PIMAGE_RESOURCE_DIR_STRING_U)
3092 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3093
3094
3095 for (j = 0; j < pMenuName->Length; j++)
3096 *pMem++ = (char) (pMenuName->NameString[j]);
3097 *pMem = 0;
3098 pMem++;
3099
3100
3101 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3102 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3103 if (prdLanguage == NULL)
3104 continue;
3105
3106 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3107 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3108
3109 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3110 ((DWORD) prdType + prde1->OffsetToData);
3111 if (prData == NULL)
3112 continue;
3113
3114 pMenuHeader = (PIMAGE_MENU_HEADER)
3115 GetActualAddress (lpFile, prData->OffsetToData);
3116 // strange case
3117 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3118 {
3119 pwd = (WORD *) ((DWORD) pMenuHeader);
3120 size = prData->Size;
3121 strcpy (pMem, ":::::::::::");
3122 pMem += 12;
3123 *(int *) pMem = size;
3124 pMem += 4;
3125 StrangeMenuFill (&pMem, &pwd, size);
3126 }
3127 // normal case
3128 else
3129 {
3130 pPopup = (PIMAGE_POPUP_MENU_ITEM)
3131 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3132 while (1)
3133 {
3134 flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3135 if (flag & 0x0080)
3136 break;
3137 }
3138 }
3139 prde++;
3140 }
3141 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3142 {
3143
3144 sprintf (buff, "MenuId_%04X", (prde->Name));
3145 strcpy (pMem, buff);
3146 pMem += strlen (buff) + 1;
3147
3148 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3149 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3150 if (prdLanguage == NULL)
3151 continue;
3152
3153 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3154 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3155
3156 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3157 ((DWORD) prdType + prde1->OffsetToData);
3158 if (prData == NULL)
3159 continue;
3160
3161 pMenuHeader = (PIMAGE_MENU_HEADER)
3162 GetActualAddress (lpFile, prData->OffsetToData);
3163 // strange case
3164 if (pMenuHeader->wVersion | pMenuHeader->cbHeaderSize)
3165 {
3166 pwd = (WORD *) ((DWORD) pMenuHeader);
3167 size = prData->Size;
3168 strcpy (pMem, ":::::::::::");
3169 pMem += 12;
3170 *(int *) pMem = size;
3171 pMem += 4;
3172 StrangeMenuFill (&pMem, &pwd, size);
3173 }
3174 // normal case
3175 else
3176 {
3177 pPopup = (PIMAGE_POPUP_MENU_ITEM)
3178 ((DWORD) pMenuHeader + sizeof (IMAGE_MENU_HEADER));
3179 while (1)
3180 {
3181 flag = (WORD) MenuFill (&pMem, (WORD **) (&pPopup));
3182 if (flag & 0x0080)
3183 break;
3184 }
3185 }
3186 prde++;
3187 }
3188
3189 return nMenus;
3190 }
3191
3192
3193 //
3194 // This function is written by sang cho
3195 // October 12, 1997
3196 //
3197 /* print contents of menu */
3198 int WINAPI
3199 PrintStrangeMenu (
3200 char **psz)
3201 {
3202
3203 int i, j, k, l;
3204 int num;
3205 WORD flag1, flag2;
3206 char buff[128];
3207 char *ptr, *pmax;
3208
3209 //return dumpMenu (psz, size);
3210
3211 ptr = *psz;
3212
3213 if (strncmp (ptr, ":::::::::::", 11) != 0)
3214 {
3215 printf ("\n#### I don't know why!!!");
3216 dumpMenu (psz, 1024);
3217 exit (0);
3218 }
3219
3220 ptr += 12;
3221 num = *(int *) ptr;
3222 ptr += 4;
3223 pmax = ptr + num;
3224
3225 *psz = ptr;
3226 return dumpMenu (psz, num);
3227
3228 // I will write some code later...
3229
3230 }
3231
3232
3233
3234
3235 //
3236 // This function is written by sang cho
3237 // October 2, 1997
3238 //
3239 /* print contents of menu */
3240 int WINAPI
3241 PrintMenu (
3242 int indent,
3243 char **psz)
3244 {
3245
3246 int /*i, */ j, k, l;
3247 WORD id /*, num */ ;
3248 WORD flag;
3249 char buff[128];
3250 char *ptr;
3251
3252
3253 ptr = *psz;
3254 //num = *(WORD *)ptr;
3255 //ptr += 2;
3256 while (1)
3257 {
3258 flag = *(WORD *) ptr;
3259 if (flag & 0x0010) // flag == popup
3260
3261 {
3262 printf ("\n\n");
3263 for (j = 0; j < indent; j++)
3264 printf (" ");
3265 ptr += 2;
3266 printf ("%s {Popup}\n", ptr);
3267 ptr += strlen (ptr) + 1;
3268 *psz = ptr;
3269 PrintMenu (indent + 5, psz);
3270 ptr = *psz;
3271 }
3272 else // ispopup == 0
3273
3274 {
3275 printf ("\n");
3276 for (j = 0; j < indent; j++)
3277 printf (" ");
3278 ptr += 2;
3279 id = *(WORD *) ptr;
3280 ptr += 2;
3281 strcpy (buff, ptr);
3282 l = strlen (ptr);
3283 ptr += l + 1;
3284 if (strchr (buff, 0x09) != NULL)
3285 {
3286 for (k = 0; k < l; k++)
3287 if (buff[k] == 0x09)
3288 break;
3289 for (j = 0; j < l - k; j++)
3290 buff[31 - j] = buff[l - j];
3291 for (j = k; j < 32 + k - l; j++)
3292 buff[j] = 32;
3293 }
3294 if (strchr (buff, 0x08) != NULL)
3295 {
3296 for (k = 0; k < l; k++)
3297 if (buff[k] == 0x08)
3298 break;
3299 for (j = 0; j < l - k; j++)
3300 buff[31 - j] = buff[l - j];
3301 for (j = k; j < 32 + k - l; j++)
3302 buff[j] = 32;
3303 }
3304 printf ("%s", buff);
3305 l = strlen (buff);
3306 for (j = l; j < 32; j++)
3307 printf (" ");
3308 printf ("[ID=%04Xh]", id);
3309 *psz = ptr;
3310 }
3311 if (flag & 0x0080)
3312 break;
3313 }
3314 return 0;
3315 }
3316
3317
3318 //
3319 // This function is written by sang cho
3320 // October 2, 1997
3321 //
3322 /* the format of menu is not known so I'll do my best */
3323 int WINAPI
3324 dumpMenu (
3325 char **psz,
3326 int size)
3327 {
3328
3329 int i, j, k, n, l, c;
3330 char buff[32];
3331 char *ptr, *pmax;
3332
3333 ptr = *psz;
3334 pmax = ptr + size;
3335 for (i = 0; i < (size / 16) + 1; i++)
3336 {
3337 n = 0;
3338 for (j = 0; j < 16; j++)
3339 {
3340 c = (int) (*ptr);
3341 if (c < 0)
3342 c += 256;
3343 buff[j] = c;
3344 printf ("%02X", c);
3345 ptr++;
3346 if (ptr >= pmax)
3347 break;
3348 n++;
3349 if (n % 4 == 0)
3350 printf (" ");
3351 }
3352 n++;
3353 if (n % 4 == 0)
3354 printf (" ");
3355 l = j;
3356 j++;
3357 for (; j < 16; j++)
3358 {
3359 n++;
3360 if (n % 4 == 0)
3361 printf (" ");
3362 else
3363 printf (" ");
3364 }
3365 printf (" ");
3366 for (k = 0; k < l; k++)
3367 if (isprint (c = buff[k]))
3368 printf ("%c", c);
3369 else
3370 printf (".");
3371 printf ("\n");
3372 if (ptr >= pmax)
3373 break;
3374 }
3375
3376 *psz = ptr;
3377 return 0;
3378 }
3379
3380
3381
3382
3383 //
3384 // This function is written by sang cho
3385 // October 13, 1997
3386 //
3387 /* scan dialog box and copy dialog box */
3388 int WINAPI
3389 GetContentsOfDialog (
3390 LPVOID lpFile,
3391 char **pszResTypes)
3392 {
3393 PIMAGE_RESOURCE_DIRECTORY prdType, prdName, prdLanguage;
3394 PIMAGE_RESOURCE_DIRECTORY_ENTRY prde, prde1;
3395 PIMAGE_RESOURCE_DIR_STRING_U pDialogName;
3396 PIMAGE_RESOURCE_DATA_ENTRY prData;
3397 PIMAGE_DIALOG_HEADER pDialogHeader;
3398 PIMAGE_CONTROL_DATA pControlData;
3399 char buff[32];
3400 int nCnt = 0, i, j;
3401 int num = 0;
3402 int size;
3403 int sLength, nDialogs;
3404 WORD flag;
3405 WORD *pwd;
3406 DWORD prdeName;
3407 char *pMem, *pTemp;
3408 BOOL isStrange = FALSE;
3409
3410
3411 /* get root directory of resource tree */
3412 if ((prdType = (PIMAGE_RESOURCE_DIRECTORY) ImageDirectoryOffset
3413 (lpFile, IMAGE_DIRECTORY_ENTRY_RESOURCE)) == NULL)
3414 return 0;
3415
3416 /* set pointer to first resource type entry */
3417 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3418 ((DWORD) prdType + sizeof (IMAGE_RESOURCE_DIRECTORY));
3419
3420 for (i = 0; i < prdType->NumberOfIdEntries; i++)
3421 {
3422 if (prde->Name == RT_DIALOG)
3423 break;
3424 prde++;
3425 }
3426 if (prde->Name != RT_DIALOG)
3427 return 0;
3428
3429 prdName = (PIMAGE_RESOURCE_DIRECTORY)
3430 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3431 if (prdName == NULL)
3432 return 0;
3433
3434 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3435 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3436
3437
3438 nDialogs = prdName->NumberOfNamedEntries + prdName->NumberOfIdEntries;
3439 sLength = 0;
3440
3441 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3442 {
3443 pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3444 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3445 sLength += pDialogName->Length + 1;
3446
3447 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3448 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3449 if (prdLanguage == NULL)
3450 continue;
3451
3452 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3453 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3454
3455 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3456 ((DWORD) prdType + prde1->OffsetToData);
3457 if (prData == NULL)
3458 continue;
3459
3460 size = prData->Size;
3461 sLength += 4 + size;
3462 prde++;
3463 }
3464 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3465 {
3466 sLength += 14;
3467
3468 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3469 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3470 if (prdLanguage == NULL)
3471 continue;
3472
3473 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3474 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3475
3476 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3477 ((DWORD) prdType + prde1->OffsetToData);
3478 if (prData == NULL)
3479 continue;
3480
3481 size = prData->Size;
3482 sLength += 4 + size;
3483 prde++;
3484 }
3485 //
3486 // allocate memory for menu names
3487 //
3488 *pszResTypes = (char *) calloc (sLength, 1);
3489
3490 pMem = *pszResTypes;
3491 //
3492 // and start all over again
3493 //
3494 prde = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3495 ((DWORD) prdName + sizeof (IMAGE_RESOURCE_DIRECTORY));
3496
3497 for (i = 0; i < prdName->NumberOfNamedEntries; i++)
3498 {
3499 pDialogName = (PIMAGE_RESOURCE_DIR_STRING_U)
3500 ((DWORD) prdType + (prde->Name ^ 0x80000000));
3501
3502
3503 for (j = 0; j < pDialogName->Length; j++)
3504 *pMem++ = (char) (pDialogName->NameString[j]);
3505 *pMem = 0;
3506 pMem++;
3507
3508
3509 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3510 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3511 if (prdLanguage == NULL)
3512 continue;
3513
3514 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3515 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3516
3517 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3518 ((DWORD) prdType + prde1->OffsetToData);
3519 if (prData == NULL)
3520 continue;
3521
3522 pDialogHeader = (PIMAGE_DIALOG_HEADER)
3523 GetActualAddress (lpFile, prData->OffsetToData);
3524
3525
3526
3527 pwd = (WORD *) ((DWORD) pDialogHeader);
3528 size = prData->Size;
3529 *(int *) pMem = size;
3530 pMem += 4;
3531 StrangeMenuFill (&pMem, &pwd, size);
3532
3533 prde++;
3534 }
3535 for (i = 0; i < prdName->NumberOfIdEntries; i++)
3536 {
3537
3538 sprintf (buff, "DialogId_%04X", (prde->Name));
3539 strcpy (pMem, buff);
3540 pMem += strlen (buff) + 1;
3541
3542 prdLanguage = (PIMAGE_RESOURCE_DIRECTORY)
3543 ((DWORD) prdType + (prde->OffsetToData ^ 0x80000000));
3544 if (prdLanguage == NULL)
3545 {
3546 printf ("\nprdLanguage = NULL");
3547 exit (0);
3548 }
3549
3550 prde1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)
3551 ((DWORD) prdLanguage + sizeof (IMAGE_RESOURCE_DIRECTORY));
3552
3553 prData = (PIMAGE_RESOURCE_DATA_ENTRY)
3554 ((DWORD) prdType + prde1->OffsetToData);
3555 if (prData == NULL)
3556 {
3557 printf ("\nprData = NULL");
3558 exit (0);
3559 }
3560
3561 pDialogHeader = (PIMAGE_DIALOG_HEADER)
3562 GetActualAddress (lpFile, prData->OffsetToData);
3563
3564
3565 pwd = (WORD *) ((DWORD) pDialogHeader);
3566 size = prData->Size;
3567 *(int *) pMem = size;
3568 pMem += 4;
3569 StrangeMenuFill (&pMem, &pwd, size);
3570
3571 prde++;
3572 }
3573
3574 return nDialogs;
3575 }
3576
3577
3578 //
3579 // This function is written by sang cho
3580 // October 14, 1997
3581 //
3582 /* print contents of dialog */
3583 int WINAPI
3584 PrintNameOrOrdinal (
3585 char **psz)
3586 {
3587 char *ptr;
3588
3589 ptr = *psz;
3590 if (*(WORD *) ptr == 0xFFFF)
3591 {
3592 ptr += 2;
3593 printf ("%04X", *(WORD *) ptr);
3594 ptr += 2;
3595 }
3596 else
3597 {
3598 printf ("%c", '"');
3599 while (*(WORD *) ptr)
3600 {
3601 printf ("%c", *ptr);
3602 ptr += 2;
3603 }
3604 ptr += 2;
3605 printf ("%c", '"');
3606 }
3607 *psz = ptr;
3608 }
3609
3610
3611 //
3612 // This function is written by sang cho
3613 // October 14, 1997
3614 //
3615 /* print contents of dialog */
3616 int WINAPI
3617 PrintDialog (
3618 char **psz)
3619 {
3620 int i, j, k, l, n, c;
3621 int num, size;
3622 DWORD flag;
3623 WORD class;
3624 char buff[32];
3625 char *ptr, *pmax;
3626 BOOL isStrange = FALSE;
3627
3628 ptr = *psz;
3629 size = *(int *) ptr;
3630 ptr += 4;
3631 pmax = ptr + size;
3632
3633 // IStype of Dialog Header
3634 flag = *(DWORD *) ptr;
3635 //
3636 // check if flag is right or not
3637 // it has been observed that some dialog information is strange
3638 // and extra work is needed to fix that ... so let's try something
3639 //
3640
3641 if ((flag & 0xFFFF0000) == 0xFFFF0000)
3642 {
3643 flag = *(DWORD *) (ptr + 12);
3644 num = *(short *) (ptr + 16);
3645 isStrange = TRUE;
3646 ptr += 26;
3647 }
3648 else
3649 {
3650 num = *(short *) (ptr + 8);
3651 ptr += 18;
3652 }
3653 printf (", # of Controls=%03d, Caption:%c", num, '"');
3654
3655 // Menu name
3656 if (*(WORD *) ptr == 0xFFFF)
3657 ptr += 4; // ordinal
3658
3659 else
3660 {
3661 while (*(WORD *) ptr)
3662 ptr += 2;
3663 ptr += 2;
3664 } // name
3665
3666 // Class name
3667 if (*(WORD *) ptr == 0xFFFF)
3668 ptr += 4; // ordinal
3669
3670 else
3671 {
3672 while (*(WORD *) ptr)
3673 ptr += 2;
3674 ptr += 2;
3675 } // name
3676
3677 // Caption
3678 while (*(WORD *) ptr)
3679 {
3680 printf ("%c", *ptr);
3681 ptr += 2;
3682 }
3683 ptr += 2;
3684 printf ("%c", '"');
3685
3686 // FONT present
3687 if (flag & 0x00000040)
3688 {
3689 if (isStrange)
3690 ptr += 6;
3691 else
3692 ptr += 2; // FONT size
3693
3694 while (*(WORD *) ptr)
3695 ptr += 2; // WCHARs
3696
3697 ptr += 2; // double null
3698
3699 }
3700
3701 // strange case adjust
3702 if (isStrange)
3703 ptr += 8;
3704
3705 // DWORD padding
3706 if ((ptr - *psz) % 4)
3707 ptr += 4 - ((ptr - *psz) % 4);
3708
3709 // start reporting .. finally
3710 for (i = 0; i < num; i++)
3711 {
3712 flag = *(DWORD *) ptr;
3713 if (isStrange)
3714 ptr += 14;
3715 else
3716 ptr += 16;
3717 printf ("\n Control::%03d - ID:", i + 1);
3718
3719 // Control ID
3720 printf ("%04X, Class:", *(WORD *) ptr);
3721 ptr += 2;
3722
3723 // Control Class
3724 if (*(WORD *) ptr == 0xFFFF)
3725 {
3726 ptr += 2;
3727 class = *(WORD *) ptr;
3728 ptr += 2;
3729 switch (class)
3730 {
3731 case 0x80:
3732 printf ("BUTTON ");
3733 break;
3734 case 0x81:
3735 printf ("EDIT ");
3736 break;
3737 case 0x82:
3738 printf ("STATIC ");
3739 break;
3740 case 0x83:
3741 printf ("LISTBOX ");
3742 break;
3743 case 0x84:
3744 printf ("SCROLLBAR");
3745 break;
3746 case 0x85:
3747 printf ("COMBOBOX ");
3748 break;
3749 default:
3750 printf ("%04X ", class);
3751 break;
3752 }
3753 }
3754 else
3755 PrintNameOrOrdinal (&ptr);
3756
3757 printf (" Text:");
3758
3759 // Text
3760 PrintNameOrOrdinal (&ptr);
3761
3762 // nExtraStuff
3763 ptr += 2;
3764
3765 // strange case adjust
3766 if (isStrange)
3767 ptr += 8;
3768
3769 // DWORD padding
3770 if ((ptr - *psz) % 4)
3771 ptr += 4 - ((ptr - *psz) % 4);
3772 }
3773
3774 /*
3775 ptr = *psz;
3776 printf("\n");
3777
3778 for (i=0; i<(size/16)+1; i++)
3779 {
3780 n = 0;
3781 for (j=0; j<16; j++)
3782 {
3783 c = (int)(*ptr);
3784 if (c<0) c+=256;
3785 buff[j] = c;
3786 printf ("%02X",c);
3787 ptr++;
3788 if (ptr >= pmax) break;
3789 n++;
3790 if (n%4 == 0) printf (" ");
3791 }
3792 n++; if (n%4 == 0) printf (" ");
3793 l = j;
3794 j++;
3795 for (; j<16; j++)
3796 { n++; if (n%4 == 0) printf (" "); else printf (" "); }
3797 printf (" ");
3798 for (k=0; k<l; k++)
3799 if (isprint(c=buff[k])) printf("%c", c); else printf(".");
3800 printf ("\n");
3801 if (ptr >= pmax) break;
3802 }
3803 */
3804
3805 *psz = pmax;
3806
3807 }
3808
3809
3810
3811
3812
3813
3814 /* function indicates whether debug info has been stripped from file */
3815 BOOL WINAPI
3816 IsDebugInfoStripped (
3817 LPVOID lpFile)
3818 {
3819 PIMAGE_FILE_HEADER pfh;
3820
3821 pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
3822
3823 return (pfh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED);
3824 }
3825
3826
3827
3828
3829 /* retrieve the module name from the debug misc. structure */
3830 int WINAPI
3831 RetrieveModuleName (
3832 LPVOID lpFile,
3833 char **pszModule)
3834 {
3835
3836 PIMAGE_DEBUG_DIRECTORY pdd;
3837 PIMAGE_DEBUG_MISC pdm = NULL;
3838 int nCnt;
3839
3840 if (!(pdd = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryOffset (lpFile, IMAGE_DIRECTORY_ENTRY_DEBUG)))
3841 return 0;
3842
3843 while (pdd->SizeOfData)
3844 {
3845 if (pdd->Type == IMAGE_DEBUG_TYPE_MISC)
3846 {
3847 pdm = (PIMAGE_DEBUG_MISC) ((DWORD) pdd->PointerToRawData + (DWORD) lpFile);
3848 *pszModule = (char *) calloc ((nCnt = (strlen (pdm->Data))) + 1, 1);
3849 // may need some unicode business here...above
3850 bcopy (pdm->Data, *pszModule, nCnt);
3851
3852 break;
3853 }
3854
3855 pdd++;
3856 }
3857
3858 if (pdm != NULL)
3859 return nCnt;
3860 else
3861 return 0;
3862 }
3863
3864
3865
3866
3867
3868 /* determine if this is a valid debug file */
3869 BOOL WINAPI
3870 IsDebugFile (
3871 LPVOID lpFile)
3872 {
3873 PIMAGE_SEPARATE_DEBUG_HEADER psdh;
3874
3875 psdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3876
3877 return (psdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE);
3878 }
3879
3880
3881
3882
3883 /* copy separate debug header structure from debug file */
3884 BOOL WINAPI
3885 GetSeparateDebugHeader (
3886 LPVOID lpFile,
3887 PIMAGE_SEPARATE_DEBUG_HEADER psdh)
3888 {
3889 PIMAGE_SEPARATE_DEBUG_HEADER pdh;
3890
3891 pdh = (PIMAGE_SEPARATE_DEBUG_HEADER) lpFile;
3892
3893 if (pdh->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
3894 {
3895 bcopy ((LPVOID) pdh, (LPVOID) psdh, sizeof (IMAGE_SEPARATE_DEBUG_HEADER));
3896 return TRUE;
3897 }
3898
3899 return FALSE;
3900 }
3901
3902 //
3903 // I tried to immitate the output of w32dasm disassembler.
3904 // which is a pretty good program.
3905 // but I am disappointed with this program and I myself
3906 // am writting a disassembler.
3907 // This PEdump program is a byproduct of that project.
3908 // so enjoy this program and I hope we will have a little more
3909 // knowledge on windows programming world.
3910 // .... sang cho
3911
3912 #define MAXSECTIONNUMBER 16
3913 #define MAXNAMESTRNUMBER 40
3914 int
3915 main (
3916 int argc,
3917 char **argv
3918 )
3919 {
3920 DWORD fileType;
3921 LPVOID lpFile;
3922 FILE *my_fp;
3923 IMAGE_DOS_HEADER dosHdr;
3924 PIMAGE_FILE_HEADER pfh;
3925 PIMAGE_OPTIONAL_HEADER poh;
3926 PIMAGE_SECTION_HEADER psh;
3927 IMAGE_SECTION_HEADER idsh;
3928 IMAGE_SECTION_HEADER shdr[MAXSECTIONNUMBER];
3929 PIMAGE_IMPORT_MODULE_DIRECTORY pid;
3930
3931 int nSections; // number of sections
3932
3933 int nResources; // number of resources
3934
3935 int nMenus; // number of menus
3936
3937 int nDialogs; // number of dialogs
3938
3939 int nImportedModules; // number of imported modules
3940
3941 int nFunctions; // number of functions in the imported module
3942
3943 int nExportedFunctions; // number of exported funcions
3944
3945 int imageBase;
3946 int entryPoint;
3947
3948 int i, j, k, n;
3949 int mnsize;
3950 int nCnt;
3951 int nSize;
3952 int fsize;
3953 char *pnstr;
3954 char *pst;
3955 char *piNameBuff; // import module name buffer
3956
3957 char *pfNameBuff; // import functions in the module name buffer
3958
3959 char *peNameBuff; // export function name buffer
3960
3961 char *pmNameBuff; // menu name buffer
3962
3963 char *pdNameBuff; // dialog name buffer
3964
3965 /*
3966 * Check user arguments.
3967 */
3968 if (2 == argc)
3969 {
3970 my_fp = fopen (argv[1], "rb");
3971 if (my_fp == NULL)
3972 {
3973 printf (
3974 "%s: can not open input file \"%s\".\n",
3975 argv[0],
3976 argv[1]
3977 );
3978 exit (0);
3979 }
3980 }
3981 else
3982 {
3983 printf (
3984 "%s - PE/COFF file dumper\n"
3985 "Copyright (c) 1993 Randy Kath (MSDN Technology Group)\n"
3986 "Copyright (c) 1997 Sang Cho (CS & Engineering - Chongju University)\n"
3987 "Copyright (c) 2000 Emanuele Aliberti (ReactOS Development Team)\n\n",
3988 argv[0]
3989 );
3990 printf (
3991 "usage: %s input_file_name\n",
3992 argv[0]
3993 );
3994 exit (0);
3995 }
3996 /*
3997 * Get input file's size.
3998 */
3999 /* argv [0], */
4000 fseek (my_fp, 0L, SEEK_END);
4001 fsize = ftell (my_fp);
4002 rewind (my_fp);
4003 /*
4004 * Buffer the file in memory.
4005 */
4006 lpFile = (void *) calloc (fsize, 1);
4007 if (lpFile == NULL)
4008 {
4009 printf (
4010 "%s: can not allocate memory.\n",
4011 argv[0]
4012 );
4013 exit (0);
4014 }
4015 /*
4016 * --- Start of report ---
4017 */
4018 printf ("\n\nDump of file: %s\n\n", argv[1]);
4019
4020 n = fread (lpFile, fsize, 1, my_fp);
4021
4022 if (n == -1)
4023 {
4024 printf (
4025 "%s: failed to read the file \"%s\".\n",
4026 argv[0],
4027 argv[1]
4028 );
4029 exit (0);
4030 }
4031
4032 GetDosHeader (lpFile, &dosHdr);
4033
4034 if ((WORD) IMAGE_DOS_SIGNATURE == dosHdr.e_magic)
4035 {
4036 if ((dosHdr.e_lfanew > 4096)
4037 || (dosHdr.e_lfanew < 64)
4038 )
4039 {
4040 printf (
4041 "%s: This file is not in PE format; it looks like in DOS format.\n",
4042 argv[0]
4043 );
4044 exit (0);
4045 }
4046 }
4047 else
4048 {
4049 printf (
4050 "%s: This doesn't look like an executable file (magic = 0x%04x).\n",
4051 argv[0],
4052 dosHdr.e_magic
4053 );
4054 exit (0);
4055 }
4056
4057 fileType = ImageFileType (lpFile);
4058
4059 if (fileType != IMAGE_NT_SIGNATURE)
4060 {
4061 printf (
4062 "%s: This file is not in PE format (magic = 0x%08x).\n",
4063 argv[0],
4064 fileType
4065 );
4066 exit (0);
4067 }
4068
4069 //=====================================
4070 // now we can really start processing
4071 //=====================================
4072
4073 pfh = (PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile);
4074
4075 poh = (PIMAGE_OPTIONAL_HEADER) OPTHDROFFSET (lpFile);
4076
4077 psh = (PIMAGE_SECTION_HEADER) SECHDROFFSET (lpFile);
4078
4079 nSections = pfh->NumberOfSections;
4080
4081 imageBase = poh->ImageBase;
4082
4083 entryPoint = poh->AddressOfEntryPoint;
4084
4085 if (psh == NULL)
4086 return 0;
4087
4088 /* store section headers */
4089
4090 for (i = 0;
4091 i < nSections;
4092 i++
4093 )
4094 {
4095 shdr[i] = *psh++;
4096 }
4097 /*
4098 * Get Code offset and size,
4099 * Data offset and size.