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