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