home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Fravia / fravia / pe.txt < prev    next >
Text File  |  2000-05-25  |  95KB  |  2,044 lines

  1. $Id: pe.txt,v 1.9 1999/03/20 23:55:09 LUEVELSMEYER Exp $
  2.  
  3.  
  4.  
  5. The PE file format
  6. ==================
  7.  
  8.  
  9.  
  10. Preface
  11. -------
  12.  
  13. The PE ("portable executable") file format is the format of executable
  14. binaries (DLLs and programs) for MS windows NT, windows 95 and
  15. win32s; in windows NT, the drivers are in this format, too.
  16. It can also be used for object files and libraries.
  17.  
  18. The format is designed by Microsoft and standardized by the TIS (tool
  19. interface standard) Committee (Microsoft, Intel, Borland, Watcom, IBM
  20. and others) in 1993, apparently based on a good knowledge of COFF, the
  21. "common object file format" used for object files and executables on
  22. several UNIXes and on VMS.
  23.  
  24. The win32 SDK includes a header file <winnt.h> containing #defines and
  25. typedefs for the PE-format. I will mention the struct-member-names and
  26. #defines as we go.
  27.  
  28. You may also find the DLL "imagehelp.dll" to be helpful. It is part of
  29. windows NT, but documentation is scarce. Some of its functions are
  30. described in the "Developer Network".
  31.  
  32.  
  33.  
  34. General Layout
  35. --------------
  36.  
  37. At the start of a PE file we find an MS-DOS executable ("stub"); this
  38. makes any PE file a valid MS-DOS executable. 
  39.  
  40. After the DOS-stub there is a 32-bit-signature with the magic number
  41. 0x00004550 (IMAGE_NT_SIGNATURE).
  42.  
  43. Then there is a file header (in the COFF-format) that tells on which
  44. machine the binary is supposed to run, how many sections are in it, the
  45. time it was linked, whether it is an executable or a DLL and so on. (The
  46. difference between executable and DLL in this context is: a DLL can not
  47. be started but only be used by another binary, and a binary cannot link
  48. to an executable).
  49.  
  50. After that, we have an optional header (it is always there but still
  51. called "optional" - COFF uses an "optional header" for libraries but not
  52. for objects, that's why it is called "optional"). This tells us more
  53. about how the binary should be loaded: The starting address, the amount
  54. of stack to reserve, the size of the data segment etc..
  55.  
  56. An interesting part of the optional header is the trailing array of
  57. 'data directories'; these directories contain pointers to data in the
  58. 'sections'. If, for example, the binary has an export directory, you
  59. will find a pointer to that directory in the array member
  60. IMAGE_DIRECTORY_ENTRY_EXPORT, and it will point into one of the
  61. sections.
  62.  
  63. Following the headers we find the 'sections', introduced by the 'section
  64. headers'. Essentially, the sections' contents is what you really need to
  65. execute a program, and all the header and directory stuff is just there
  66. to help you find it.
  67. Each section has some flags about alignment, what kind of data it
  68. contains ("initialized data" and so on), whether it can be shared etc.,
  69. and the data itself. Most, but not all, sections contain one or more
  70. directories referenced through the entries of the optional header's
  71. "data directory" array, like the directory of exported functions or the
  72. directory of base relocations. Directoryless types of contents are, for
  73. example, "executable code" or "initialized data".
  74.  
  75.     +-------------------+
  76.     | DOS-stub          |
  77.     +-------------------+
  78.     | file-header       |
  79.     +-------------------+
  80.     | optional header   |
  81.     |- - - - - - - - - -|
  82.     |                   |
  83.     | data directories  |
  84.     |                   |
  85.     +-------------------+
  86.     |                   |
  87.     | section headers   |
  88.     |                   |
  89.     +-------------------+
  90.     |                   |
  91.     | section 1         |
  92.     |                   |
  93.     +-------------------+
  94.     |                   |
  95.     | section 2         |
  96.     |                   |
  97.     +-------------------+
  98.     |                   |
  99.     | ...               |
  100.     |                   |
  101.     +-------------------+
  102.     |                   |
  103.     | section n         |
  104.     |                   |
  105.     +-------------------+
  106.  
  107.  
  108.  
  109. DOS-stub and Signature
  110. ----------------------
  111.  
  112. The concept of a DOS-stub is well-known from the 16-bit-windows-
  113. executables (which were in the "NE" format). The stub is used for
  114. OS/2-executables, self-extracting archives and other applications, too.
  115. For PE-files, it is a MS-DOS 2.0 compatible executable that almost
  116. always consists of about 100 bytes that output an error message such as
  117. "this program needs windows NT".
  118. You recognize a DOS-stub by validating the DOS-header, being a
  119. struct IMAGE_DOS_HEADER. The first 2 bytes should be the sequence "MZ"
  120. (there is a #define IMAGE_DOS_SIGNATURE for this WORD).
  121. You distinguish a PE binary from other stubbed binaries by the trailing
  122. signature, which you find at the offset given by the header member
  123. 'e_lfanew' (which is 32 bits long beginning at byte offset 60). For OS/2
  124. and windows binaries, the signature is a 16-bit-word; for PE files, it
  125. is a 32-bit-longword aligned at a 8-byte-boundary and having the value
  126. IMAGE_NT_SIGNATURE #defined to be 0x00004550.
  127.  
  128.  
  129.  
  130. File Header
  131. -----------
  132.  
  133. To get to the IMAGE_FILE_HEADER, validate the "MZ" of the DOS-header
  134. (1st 2 bytes), then find the 'e_lfanew' member of the DOS-stub's header
  135. and skip that many bytes from the beginning of the file. Verify the
  136. signature you will find there. The file header, a struct
  137. IMAGE_FILE_HEADER, begins immediatly after it; the members are described
  138. top to bottom.
  139.  
  140. The first member is the 'Machine', a 16-bit-value indicating the system
  141. the binary is intended to run on. Known legal values are
  142.  
  143.     IMAGE_FILE_MACHINE_I386 (0x14c)
  144.         for Intel 80386 processor or better
  145.  
  146.     0x014d
  147.         for Intel 80486 processor or better
  148.  
  149.     0x014e
  150.         for Intel Pentium processor or better
  151.  
  152.     0x0160
  153.         for R3000 (MIPS) processor, big endian
  154.  
  155.     IMAGE_FILE_MACHINE_R3000 (0x162)
  156.         for R3000 (MIPS) processor, little endian
  157.  
  158.     IMAGE_FILE_MACHINE_R4000 (0x166)
  159.         for R4000 (MIPS) processor, little endian
  160.  
  161.     IMAGE_FILE_MACHINE_R10000 (0x168)
  162.         for R10000 (MIPS) processor, little endian
  163.  
  164.     IMAGE_FILE_MACHINE_ALPHA (0x184)
  165.         for DEC Alpha AXP processor
  166.  
  167.     IMAGE_FILE_MACHINE_POWERPC (0x1F0)
  168.         for IBM Power PC, little endian
  169.  
  170. Then we have the 'NumberOfSections', a 16-bit-value. It is the number of
  171. sections that follow the headers. We will discuss the sections later.
  172.  
  173. Next is a timestamp 'TimeDateStamp' (32 bit), giving the time the file
  174. was created. You can distinguish several versions of the same file by
  175. this value, even if the "official" version number was not altered. (The
  176. format of the timestamp is not documented except that it should be
  177. somewhat unique among versions of the same file, but apparently it is
  178. 'seconds since January 1 1970 00:00:00' in UTC - the format used by most
  179. C compilers for the time_t.)
  180. This timestamp is used for the binding of import directories, which will
  181. be discussed later.
  182. Warning: some linkers tend to set this timestamp to absurd values which
  183. are not the time of linking in time_t format as described.
  184.  
  185. The members 'PointerToSymbolTable' and 'NumberOfSymbols' (both 32 bit)
  186. are used for debugging information. I don't know how to decipher them,
  187. and I've found the pointer to be always 0.
  188.  
  189. 'SizeOfOptionalHeader' (16 bit) is simply sizeof(IMAGE_OPTIONAL_HEADER).
  190. You can use it to validate the correctness of the PE file's structure.
  191.  
  192. 'Characteristics' is 16 bits and consists of a collection of flags, most
  193. of them being valid only for object files and libraries:
  194.  
  195.     Bit 0 (IMAGE_FILE_RELOCS_STRIPPED) is set if there is no relocation
  196.     information in the file. This refers to relocation information per
  197.     section in the sections themselves; it is not used for executables,
  198.     which have relocation information in the 'base relocation' directory
  199.     described below.
  200.  
  201.     Bit 1 (IMAGE_FILE_EXECUTABLE_IMAGE) is set if the file is
  202.     executable, i.e. it is not an object file or a library. This flag
  203.     may also be set if the linker attempted to create an executable but
  204.     failed for some reason, and keeps the image in order to do e.g.
  205.     incremental linking the next time.
  206.  
  207.     Bit 2 (IMAGE_FILE_LINE_NUMS_STRIPPED) is set if the line number
  208.     information is stripped; this is not used for executable files.
  209.  
  210.     Bit 3 (IMAGE_FILE_LOCAL_SYMS_STRIPPED) is set if there is no
  211.     information about local symbols in the file (this is not used
  212.     for executable files).
  213.  
  214.     Bit 4 (IMAGE_FILE_AGGRESIVE_WS_TRIM) is set if the operating system
  215.     is supposed to trim the working set of the running process (the
  216.     amount of RAM the process uses) aggressivly by paging it out. This
  217.     should be set if it is a demon-like application that waits most of
  218.     the time and only wakes up once a day, or the like.
  219.  
  220.     Bits 7 (IMAGE_FILE_BYTES_REVERSED_LO) and 15
  221.     (IMAGE_FILE_BYTES_REVERSED_HI) are set if the endianess of the file is
  222.     not what the machine would expect, so it must swap bytes before
  223.     reading. This is unreliable for executable files (the OS expects
  224.     executables to be correctly byte-ordered).
  225.  
  226.     Bit 8 (IMAGE_FILE_32BIT_MACHINE) is set if the machine is expected
  227.     to be a 32 bit machine. This is always set for current
  228.     implementations; NT5 may work differently.
  229.  
  230.     Bit 9 (IMAGE_FILE_DEBUG_STRIPPED) is set if there is no debugging
  231.     information in the file. This is unused for executable files.
  232.     According to other information ([6]), this bit is called "fixed" and
  233.     is set if the image can only run if it is loaded at the preferred
  234.     load address (i.e. it is not relocatable).
  235.  
  236.     Bit 10 (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) is set if the application
  237.     may not run from a removable medium such as a floppy or a CD-ROM. In
  238.     this case, the operating system is advised to copy the file to the
  239.     swapfile and execute it from there.
  240.  
  241.     Bit 11 (IMAGE_FILE_NET_RUN_FROM_SWAP) is set if the application may
  242.     not run from the network. In this case, the operating system is
  243.     advised to copy the file to the swapfile and execute it from there.
  244.  
  245.     Bit 12 (IMAGE_FILE_SYSTEM) is set if the file is a system file such
  246.     as a driver. This is unused for executable files; it is also not
  247.     used in all the NT drivers I inspected.
  248.  
  249.     Bit 13 (IMAGE_FILE_DLL) is set if the file is a DLL.
  250.  
  251.     Bit 14 (IMAGE_FILE_UP_SYSTEM_ONLY) is set if the file is not
  252.     designed to run on multiprocessor systems (that is, it will crash
  253.     there because it relies in some way on exactly one processor).
  254.  
  255.  
  256.  
  257. Relative Virtual Addresses
  258. --------------------------
  259.  
  260. The PE format makes heavy use of so-called RVAs. An RVA, aka "relative
  261. virtual address", is used to describe a memory address if you don't know
  262. the base address. It is the value you need to add to the base address to
  263. get the linear address.
  264. The base address is the address the PE image is loaded to, and may vary
  265. from one invocation to the next.
  266.  
  267. Example: suppose an executable file is loaded to address 0x400000 and
  268. execution starts at RVA 0x1560. The effective execution start will then
  269. be at the address 0x401560. If the executable were loaded to 0x100000,
  270. the execution start would be 0x101560.
  271.  
  272. Things become complicated because the parts of the PE-file (the
  273. sections) are not necessarily aligned the same way the loaded image is.
  274. For example, the sections of the file are often aligned to
  275. 512-byte-borders, but the loaded image is perhaps aligned to
  276. 4096-byte-borders. See 'SectionAlignment' and 'FileAlignment' below.
  277.  
  278. So to find a piece of information in a PE-file for a specific RVA,
  279. you must calculate the offsets as if the file were loaded, but skip
  280. according to the file-offsets.
  281. As an example, suppose you knew the execution starts at RVA 0x1560, and
  282. want to diassemble the code starting there. To find the address in the
  283. file, you will have to find out that sections in RAM are aligned to 4096
  284. bytes and the ".code"-section starts at RVA 0x1000 in RAM and is 16384
  285. bytes long; then you know that RVA 0x1560 is at offset 0x560 in that
  286. section. Find out that the sections are aligned to 512-byte-borders in
  287. the file and that ".code" begins at offset 0x800 in the file, and you
  288. know that the code execution start is at byte 0x800+0x560=0xd60 in the
  289. file.
  290.  
  291. Then you disassemble and find an access to a variable at the linear
  292. address 0x1051d0. The linear address will be relocated upon loading the
  293. binary and is given on the assumption that the preferred load address is
  294. used. You find out that the preferred load address is 0x100000, so we
  295. are dealing with RVA 0x51d0. This is in the data section which starts at
  296. RVA 0x5000 and is 2048 bytes long. It begins at file offset 0x4800.
  297. Hence. the veriable can be found at file offset
  298. 0x4800+0x51d0-0x5000=0x49d0.
  299.  
  300.  
  301. Optional Header
  302. ---------------
  303.  
  304. Immediatly following the file header is the IMAGE_OPTIONAL_HEADER
  305. (which, in spite of the name, is always there). It contains
  306. information about how to treat the PE-file exactly. We'll also have the
  307. members from top to bottom.
  308.  
  309. The first 16-bit-word is 'Magic' and has, as far as I looked into
  310. PE-files, always the value 0x010b.
  311.  
  312. The next 2 bytes are the version of the linker ('MajorLinkerVersion' and
  313. 'MinorLinkerVersion') that produced the file. These values, again, are
  314. unreliable and do not always reflect the linker version properly.
  315. (Several linkers simply don't set this field.)
  316. And, coming to think about it, what good is the version if you have got
  317. no idea *which* linker was used?
  318.  
  319. The next 3 longwords (32 bit each) are intended to be the size of the
  320. executable code ('SizeOfCode'), the size of the initialized data
  321. ('SizeOfInitializedData', the so-called "data segment"), and the size of
  322. the uninitialized data ('SizeOfUninitializedData', the so-called "bss
  323. segment"). These values are, again, unreliable (e.g. the data segment
  324. may actually be split into several segments by the compiler or linker),
  325. and you get better sizes by inspecting the 'sections' that follow the
  326. optional header.
  327.  
  328. Next is a 32-bit-value that is a RVA. This RVA is the offset to the
  329. codes's entry point ('AddressOfEntryPoint').
  330. Execution starts here; it is e.g. the address of a DLL's LibMain() or a
  331. program's startup code (which will in turn call main()) or a driver's
  332. DriverEntry(). If you dare to load the image "by hand", you call this
  333. address to start the process after you have done all the fixups and the
  334. relocations.
  335.  
  336. The next 2 32-bit-values are the offsets to the executable code
  337. ('BaseOfCode') and the initialized data ('BaseOfData'), both of them
  338. RVAs again, and both of them being of little interest because you get
  339. more reliable information by inspecting the 'sections' that follow the
  340. headers.
  341. There is no offset to the uninitialized data because, being
  342. uninitialized, there is little point in providing this data in the
  343. image.
  344.  
  345. The next entry is a 32-bit-value giving the preferred (linear) load
  346. address ('ImageBase') of the entire binary, including all headers. This
  347. is the address (always a multiple of 64 KB) the file has been relocated
  348. to by the linker; if the binary can in fact be loaded to that address,
  349. the loader doesn't need to relocate the file again, which is a win in
  350. loading time.
  351. The preferred load address can not be used if another image has already
  352. been loaded to that address (an "address clash", which happens quite
  353. often if you load several DLLs that are all relocated to the linker's
  354. default), or the memory in question has been used for other purposes
  355. (stack, malloc(), uninitialized data, whatever). In these cases, the
  356. image must be loaded to some other address and it needs to be relocated
  357. (see 'relocation directory' below). This has further consequences if the
  358. image is a DLL, because then the "bound imports" are no longer valid,
  359. and fixups have to be made to the binary that uses the DLL - see 'import
  360. directory' below.
  361.  
  362. The next 2 32-bit-values are the alignments of the PE-file's sections in
  363. RAM ('SectionAlignment', when the image has been loaded) and in the file
  364. ('FileAlignment'). Usually both values are 32, or FileAlignment is 512
  365. and SectionAlignment is 4096. Sections will be discussed later.
  366.  
  367. The next 2 16-bit-words are the expected operating system version
  368. ('MajorOperatingSystemVersion' and 'MinorOperatingSystemVersion' [they
  369. _do_ like self-documenting names at MS]). This version information is
  370. intended to be the operating system's (e.g. NT or Win95) version, as
  371. opposed to the subsystem's version (e.g. Win32); it is often not
  372. supplied, or wrong supplied. The loader doesn't use it, apparently.
  373.  
  374. The next 2 16-bit-words are the binary's version, ('MajorImageVersion' and
  375. 'MinorImageVersion'). Many linkers don't set this information correctly
  376. and many programmers don't bother to supply it, so it is better to rely
  377. on the version-resource if one exists.
  378.  
  379. The next 2 16-bit-words are the expected subsystem version
  380. ('MajorSubsystemVersion' and 'MinorSubsystemVersion'). This should be
  381. the Win32 version or the POSIX version, because 16-bit-programs or
  382. OS/2-programs won't be in PE-format, obviously.
  383. This subsystem version should be supplied correctly, because it *is*
  384. checked and used:
  385. If the application is a Win32-GUI-application and runs on NT4, and the
  386. subsystem version is *not* 4.0, the dialogs won't be 3D-style and
  387. certain other features will also work "old-style" because the
  388. application expects to run on NT 3.51, which had the program manager
  389. instead of explorer and so on, and NT 4.0 will mimic that behaviour as
  390. faithfully as possible.
  391.  
  392. Then we have a 'Win32VersionValue' of 32 bits. I don't know what it is
  393. good for. It has been 0 in all the PE files that I inspected.
  394.  
  395. Next is a 32-bits-value giving the amount of memory the image will need,
  396. in bytes ('SizeOfImage'). It is the sum of all headers' and sections'
  397. lengths if aligned to 'SectionAlignment'. It is a hint to the loader how
  398. many pages it will need in order to load the image.
  399.  
  400. The next thing is a 32-bit-value giving the total length of all headers
  401. including the data directories and the section headers
  402. ('SizeOfHeaders'). It is at the same time the offset from the beginning
  403. of the file to the first section's raw data.
  404.  
  405. Then we have got a 32-bit-checksum ('CheckSum'). This checksum is, for
  406. current versions of NT, only checked if the image is a NT-driver (the
  407. driver will fail to load if the checksum isn't correct). For other
  408. binary types, the checksum need not be supplied and may be 0.
  409. The algorithm to compute the checksum is property of Microsoft, and they
  410. won't tell you. However, several tools of the Win32 SDK will compute
  411. and/or patch a valid checksum, and the function CheckSumMappedFile() in
  412. the imagehelp.dll will do so too.
  413. The checksum is supposed to prevent loading of damaged binaries that
  414. would crash anyway - and a crashing driver would result in a BSOD, so
  415. it is better not to load it at all.
  416.  
  417. Then there is a 16-bit-word 'Subsystem' that tells in which of the
  418. NT-subsystems the image runs:
  419.  
  420.     IMAGE_SUBSYSTEM_NATIVE (1)
  421.         The binary doesn't need a subsystem. This is used for drivers.
  422.     
  423.     IMAGE_SUBSYSTEM_WINDOWS_GUI (2)
  424.         The image is a Win32 graphical binary. (It can still open a
  425.         console with AllocConsole() but won't get one automatically at
  426.         startup.)
  427.     
  428.     IMAGE_SUBSYSTEM_WINDOWS_CUI (3)
  429.         The binary is a Win32 console binary. (It will get a console
  430.         per default at startup, or inherit the parent's console.)
  431.     
  432.     IMAGE_SUBSYSTEM_OS2_CUI (5)
  433.         The binary is a OS/2 console binary. (OS/2 binaries will be in
  434.         OS/2 format, so this value will seldom be used in a PE file.)
  435.     
  436.     IMAGE_SUBSYSTEM_POSIX_CUI (7)
  437.         The binary uses the POSIX console subsystem.
  438.  
  439. Windows 95 binaries will always use the Win32 subsystem, so the only
  440. legal values for these binaries are 2 and 3; I don't know if "native"
  441. binaries on windows 95 are possible.
  442.  
  443. The next thing is a 16-bit-value that tells, if the image is a DLL, when
  444. to call the DLL's entry point ('DllCharacteristics'). This seems not to
  445. be used; apparently, the DLL is always notified about everything.
  446.     If bit 0 is set, the DLL is notified about process attachment (i.e.
  447.         DLL load).
  448.     If bit 1 is set, the DLL is notified about thread detachments (i.e.
  449.         thread terminations).
  450.     If bit 2 is set, the DLL is notified about thread attachments (i.e.
  451.         thread creations).
  452.     If bit 3 is set, the DLL is notified about process detachment (i.e.
  453.         DLL unload).
  454.  
  455. The next 4 32-bit-values are the size of reserved stack
  456. ('SizeOfStackReserve'), the size of initially committed stack
  457. ('SizeOfStackCommit'), the size of the reserved heap
  458. ('SizeOfHeapReserve') and the size of the committed heap
  459. ('SizeOfHeapCommit').
  460. The 'reserved' amounts are address space (not real RAM) that is reserved
  461. for the specific purpose; at program startup, the 'committed' amount is
  462. actually allocated in RAM. The 'committed' value is also the amount by
  463. which the committed stack or heap grows if necessary. (Other sources
  464. claim that the stack will grow in pages, regardless of the
  465. 'SizeOfStackCommit' value. I didn't check this.)
  466. So, as an example, if a program has a reserved heap of 1 MB and a
  467. committed heap of 64 KB, the heap will start out at 64 KB and is
  468. guaranteed to be enlargeable up to 1 MB. The heap will grow in
  469. 64-KB-chunks.
  470. The 'heap' in this context is the primary (default) heap. A process can
  471. create more heaps if so it wishes.
  472. The stack is the first thread's stack (the one that starts main()). The
  473. process can create more threads which will have their own stacks.
  474. DLLs don't have a stack or heap of their own, so the values are ignored
  475. for their images. I don't know if drivers have a heap or a stack of
  476. their own, but I don't think so.
  477.  
  478. After these stack- and heap-descriptions, we find 32 bits of
  479. 'LoaderFlags', which I didn't find a useful description of. I only found
  480. a vague note about setting bits that automatically invoke a breakpoint
  481. or a debugger after loading the image; however, this doesn't seem to
  482. work.
  483.  
  484. Then we find 32 bits of 'NumberOfRvaAndSizes', which is the number of
  485. valid entries in the directories that follow immediatly. I've found this
  486. value to be unreliable; you might wish use the constant
  487. IMAGE_NUMBEROF_DIRECTORY_ENTRIES instead, or the lesser of both.
  488.  
  489. After the 'NumberOfRvaAndSizes' there is an array of
  490. IMAGE_NUMBEROF_DIRECTORY_ENTRIES (16) IMAGE_DATA_DIRECTORYs.
  491. Each of these directories describes the location (32 bits RVA called
  492. 'VirtualAddress') and size (also 32 bit, called 'Size') of a particular
  493. piece of information, which is located in one of the sections that
  494. follow the directory entries.
  495. For example, the security directory is found at the RVA and has the size
  496. that are given at index 4.
  497. The directories that I know the structure of will be discussed later.
  498. Defined directory indexes are:
  499.  
  500.     IMAGE_DIRECTORY_ENTRY_EXPORT (0)
  501.         The directory of exported symbols; mostly used for DLLs.
  502.         Described below.
  503.     
  504.     IMAGE_DIRECTORY_ENTRY_IMPORT (1)
  505.         The directory of imported symbols; see below.
  506.     
  507.     IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
  508.         Directory of resources. Described below.
  509.     
  510.     IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
  511.         Exception directory - structure and purpose unknown.
  512.     
  513.     IMAGE_DIRECTORY_ENTRY_SECURITY (4)
  514.         Security directory - structure and purpose unknown.
  515.     
  516.     IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
  517.         Base relocation table - see below.
  518.     
  519.     IMAGE_DIRECTORY_ENTRY_DEBUG (6)
  520.         Debug directory - contents is compiler dependent. Moreover, many
  521.         compilers stuff the debug information into the code section and
  522.         don't create a separate section for it.
  523.     
  524.     IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
  525.         Description string - some arbitrary copyright note or the like.
  526.     
  527.     IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
  528.         Machine Value (MIPS GP) - structure and purpose unknown.
  529.     
  530.     IMAGE_DIRECTORY_ENTRY_TLS (9)
  531.         Thread local storage directory - structure unknown; contains
  532.         variables that are declared "__declspec(thread)", i.e.
  533.         per-thread global variables.
  534.     
  535.     IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
  536.         Load configuration directory - structure and purpose unknown.
  537.     
  538.     IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
  539.         Bound import directory - see description of import directory.
  540.     
  541.     IMAGE_DIRECTORY_ENTRY_IAT (12)
  542.         Import Address Table - see description of import directory.
  543.     
  544. As an example, if we find at index 7 the 2 longwords 0x12000 and 33, and
  545. the load address is 0x10000, we know that the copyright data is at
  546. address 0x10000+0x12000 (in whatever section there may be), and the
  547. copyright note is 33 bytes long.
  548. If a directory of a particular type is not used in a binary, the Size
  549. and VirtualAddress are both 0.
  550.  
  551.  
  552.  
  553. Section directories
  554. -------------------
  555.  
  556. The sections consist of two major parts: first, a section description
  557. (of type IMAGE_SECTION_HEADER) and then the raw section data. So after
  558. the data directories we find an array of 'NumberOfSections' section
  559. headers, ordered by the sections' RVAs.
  560.  
  561. A section header contains:
  562.  
  563. An array of IMAGE_SIZEOF_SHORT_NAME (8) bytes that make up the name
  564. (ASCII) of the section. If all of the 8 bytes are used there is no 0-
  565. terminator for the string! The name is typically something like ".data"
  566. or ".text" or ".bss". There need not be a leading '.', the names may
  567. also be "CODE" or "IAT" or the like.
  568. Please note that the names are not at all related to the contents of the
  569. section. A section named ".code" may or may not contain the executable
  570. code; it may just as well contain the import address table; it may also
  571. contain the code *and* the address table *and* the initialized data.
  572. To find information in the sections, you will have to look it up via the
  573. data directories of the optional header. Do not rely on the names, and
  574. do not assume that the section's raw data starts at the beginning of a
  575. section.
  576.  
  577. The next member of the IMAGE_SECTION_HEADER is a 32-bit-union of
  578. 'PhysicalAddress' and 'VirtualSize'. In an object file, this is the
  579. address the contents is relocated to; in an executable, it is the size of
  580. the contents. In fact, the field seems to be unused; There are linkers
  581. that enter the size, and there are linkers that enter the address, and
  582. I've also found a linker that enters a 0, and all the executables run
  583. like the gentle wind.
  584.  
  585. The next member is 'VirtualAddress', a 32-bit-value holding the RVA to
  586. the section's data when it is loaded in RAM.
  587.  
  588. Then we have got 32 bits of 'SizeOfRawData', which is the size of the
  589. secion's data rounded up to the next multiple of 'FileAlignment'.
  590.  
  591. Next is 'PointerToRawData' (32 bits), which is incredibly useful because
  592. it is the offset from the file's beginning to the section's data. If it
  593. is 0, the section's data are not contained in the file and will be
  594. arbitrary at load time.
  595.  
  596. Then we have got 'PointerToRelocations' (32 bits) and
  597. 'PointerToLinenumbers' (also 32 bits), 'NumberOfRelocations' (16 bits)
  598. and 'NumberOfLinenumbers' (also 16 bits). All of these are information
  599. that's only used for object files. Executables have a special base
  600. relocation directory, and the line number information, if present at
  601. all, is usually contained in a special purpose debugging segment or
  602. elsewhere.
  603.  
  604. The last member of a section header is the 32 bits 'Characteristics',
  605. which is a bunch of flags describing how the section's memory should be
  606. treated:
  607.  
  608.     If bit 5 (IMAGE_SCN_CNT_CODE) is set, the section contains
  609.     executable code.
  610.     
  611.     If bit 6 (IMAGE_SCN_CNT_INITIALIZED_DATA) is set, the section
  612.     contains data that gets a defined value before execution starts. In
  613.     other words: the section's data in the file is meaningful.
  614.     
  615.     If bit 7 (IMAGE_SCN_CNT_UNINITIALIZED_DATA) is set, this section
  616.     contains uninitialized data and will be initialized to all-0-bytes
  617.     before execution starts. This is normally the BSS.
  618.  
  619.     If bit 9 (IMAGE_SCN_LNK_INFO) is set, the section doesn't contain
  620.     image data but comments, description or other documentation. This
  621.     information is part of an object file and may be information for the
  622.     linker, such as which libraries are needed.
  623.  
  624.     If bit 11 (IMAGE_SCN_LNK_REMOVE) is set, the data is part of an
  625.     object file's section that is supposed to be left out when the
  626.     executable file is linked. Often combined with bit 9.
  627.  
  628.     If bit 12 (IMAGE_SCN_LNK_COMDAT) is set, the section contains
  629.     "common block data", which are packaged functions of some sort.
  630.  
  631.     If bit 15 (IMAGE_SCN_MEM_FARDATA) is set, we have far data -
  632.     whatever that means. This bit's meaning is unsure.
  633.  
  634.     If bit 17 (IMAGE_SCN_MEM_PURGEABLE) is set, the section's data
  635.     is purgeable - but I don't think that this is the same as
  636.     "discardable", which has a bit of its own, see below.
  637.     The same bit is apparently used to indicate 16-bit-information as
  638.     there is also a define IMAGE_SCN_MEM_16BIT for it.
  639.     This bit's meaning is unsure.
  640.  
  641.     If bit 18 (IMAGE_SCN_MEM_LOCKED) is set, the section should not be
  642.     moved in memory? Perhaps it indicates there is no relocation
  643.     information? This bit's meaning is unsure.
  644.  
  645.     If bit 19 (IMAGE_SCN_MEM_PRELOAD) is set, the section should be
  646.     paged in before execution starts? This bit's meaning is unsure.
  647.  
  648.     Bits 20 to 23 specify an alignment that I have no information
  649.     about. There are #defines IMAGE_SCN_ALIGN_16BYTES and the like. The
  650.     only value I've ever seen used is 0, for the default 16-byte-
  651.     alignment. I suspect that this is the alignment of objects in a
  652.     library file or the like.
  653.  
  654.     If bit 24 (IMAGE_SCN_LNK_NRELOC_OVFL) is set, the section contains
  655.     some extended relocations that I don't know about.
  656.  
  657.     If bit 25 (IMAGE_SCN_MEM_DISCARDABLE) is set, the section's data is
  658.     not needed after the process has started. This is the case,
  659.     for example, with the relocation information. I've seen it also for
  660.     startup routines of drivers and services that are only executed
  661.     once, and for import directories.
  662.  
  663.     If bit 26 (IMAGE_SCN_MEM_NOT_CACHED) is set, the section's data
  664.     should not be cached. Don't ask my why not. Does this mean to switch
  665.     off the 2nd-level-cache?
  666.  
  667.     If bit 27 (IMAGE_SCN_MEM_NOT_PAGED) is set, the section's data
  668.     should not be paged out. This is interesting for drivers.
  669.  
  670.     If bit 28 (IMAGE_SCN_MEM_SHARED) is set, the section's data is
  671.     shared among all running instances of the image. If it is e.g. the
  672.     initialized data of a DLL, all running instances of the DLL will at
  673.     any time have the same variable contents.
  674.     Note that only the first instance's section is initialized.
  675.     Sections containing code are always shared copy-on-write (i.e. the
  676.     sharing doesn't work if relocations are necessary).
  677.  
  678.     If bit 29 (IMAGE_SCN_MEM_EXECUTE) is set, the process gets
  679.     'execute'-access to the section's memory.
  680.     
  681.     If bit 30 (IMAGE_SCN_MEM_READ) is set, the process gets
  682.     'read'-access to the section's memory.
  683.     
  684.     If bit 31 (IMAGE_SCN_MEM_WRITE) is set, the process gets
  685.     'write'-access to the section's memory.
  686.  
  687.  
  688.  
  689. After the section headers we find the sections themselves. They are, in
  690. the file, aligned to 'FileAlignment' bytes (that is, after the optional
  691. header and after each section's data there will be padding bytes) and
  692. ordered by their RVAs. When loaded (in RAM), the sections are aligned to
  693. 'SectionAlignment' bytes.
  694.  
  695. As an example, if the optional header ends at file offset 981 and
  696. 'FileAlignment' is 512, the first section will start at byte 1024. Note
  697. that you can find the sections via the 'PointerToRawData' or the
  698. 'VirtualAddress', so there is hardly any need to actually fuss around
  699. with the alignments.
  700.  
  701.  
  702. I will try to make an image of it all:
  703.  
  704.  
  705.     +-------------------+
  706.     | DOS-stub          |
  707.     +-------------------+
  708.     | file-header       |
  709.     +-------------------+
  710.     | optional header   |
  711.     |- - - - - - - - - -|
  712.     |                   |----------------+
  713.     | data directories  |                |
  714.     |                   |                |
  715.     |(RVAs to direc-    |-------------+  |
  716.     |tories in sections)|             |  |
  717.     |                   |---------+   |  |
  718.     |                   |         |   |  |
  719.     +-------------------+         |   |  |
  720.     |                   |-----+   |   |  |
  721.     | section headers   |     |   |   |  |
  722.     | (RVAs to section  |--+  |   |   |  |
  723.     |  borders)         |  |  |   |   |  |
  724.     +-------------------+<-+  |   |   |  |
  725.     |                   |     | <-+   |  |
  726.     | section data 1    |     |       |  |
  727.     |                   |     | <-----+  |
  728.     +-------------------+<----+          |
  729.     |                   |                |
  730.     | section data 2    |                |
  731.     |                   | <--------------+
  732.     +-------------------+
  733.  
  734. There is one section header for each section, and each data directory
  735. will point to one of the sections (several data directories may point to
  736. the same section, and there may be sections without data directory
  737. pointing to them).
  738.  
  739.  
  740.  
  741. Sections' raw data
  742. ------------------
  743.  
  744.  
  745. general
  746. -------
  747. All sections are aligned to 'SectionAlignment' when loaded in RAM, and
  748. 'FileAlignment' in the file. The sections are described by entries in
  749. the section headers: You find the sections in the file via
  750. 'PointerToRawData' and in memory via 'VirtualAddress'; the length is in
  751. 'SizeOfRawData'.
  752.  
  753. There are several kinds of sections, depending on what's contained in
  754. them. In most cases (but not in all) there will be at least one
  755. data directory in a section, with a pointer to it in the optional
  756. header's data directory array.
  757.  
  758.  
  759. code section
  760. ------------
  761. First, I will mention the code section. The section will have, at least,
  762. the bits 'IMAGE_SCN_CNT_CODE', 'IMAGE_SCN_MEM_EXECUTE' and
  763. 'IMAGE_SCN_MEM_READ' set, and 'AddressOfEntryPoint' will point somewhere
  764. into the section, to the start of the function that the developer wants
  765. to execute first.
  766. 'BaseOfCode' will normally point to the start of this section, but may
  767. point to somewhere later in the section if some non-code-bytes are
  768. placed before the code in the section.
  769. Normally, there will be nothing but executable code in this section, and
  770. there will be only one code section, but don't rely on this.
  771. Typical section names are ".text", ".code", "AUTO" and the like.
  772.  
  773.  
  774. data section
  775. ------------
  776. The next thing we'll discuss is the initialized variables; this section
  777. contains initialized static variables (like "static int i = 5;"). It will
  778. have, at least, the bits 'IMAGE_SCN_CNT_INITIALIZED_DATA',
  779. 'IMAGE_SCN_MEM_READ' and 'IMAGE_SCN_MEM_WRITE' set. Some linkers may
  780. place constant data into a section of their own that doesn't have the
  781. writeable-bit. If part of the data is shareable, or there are other
  782. peculiarities, there may be more sections with the apropriate section-
  783. bits set.
  784. The section, or sections, will be in the range 'BaseOfData' up to
  785. 'BaseOfData'+'SizeOfInitializedData'.
  786. Typical section names are '.data', '.idata', 'DATA' and so on.
  787.  
  788.  
  789. bss section
  790. -----------
  791. Then there is the uninitialized data (for static variables like "static
  792. int k;"); this section is quite like the initialized data, but will have
  793. a file offset ('PointerToRawData') of 0 indicating its contents is not
  794. stored in the file, and 'IMAGE_SCN_CNT_UNINITIALIZED_DATA' is set
  795. instead of 'IMAGE_SCN_CNT_INITIALIZED_DATA' to indicate that the
  796. contents should be set to 0-bytes at load-time. This means, there is a
  797. section header but no section in the file; the section will be created
  798. by the loader and consist entirely of 0-bytes.
  799. The length will be 'SizeOfUninitializedData'.
  800. Typical names are '.bss', 'BSS' and the like.
  801.  
  802. These were the section data that are *not* pointed to by data
  803. directories. Their contents and structure is supplied by the compiler,
  804. not by the linker.
  805. (The stack-segment and heap-segment are not sections in the binary but
  806. created by the loader from the stacksize- and heapsize-entries in the
  807. optional header.)
  808.  
  809.  
  810. copyright
  811. ---------
  812. To begin with a simple directory-section, let's look at the data
  813. directory 'IMAGE_DIRECTORY_ENTRY_COPYRIGHT'. The contents is a
  814. copyright- or description string in ASCII (not 0-terminated), like
  815. "Gonkulator control application, copyright (c) 1848 Hugendubel & Cie".
  816. This string is, normally, supplied to the linker with the command line
  817. or a description file.
  818. This string is not needed at runtime and may be discarded. It is not
  819. writeable; in fact, the application doesn't need access at all.
  820. So the linker will find out if there is a discardable non-writeable
  821. section already and if not, create one (named '.descr' or the like). It
  822. will then stuff the string into the section and let the
  823. copyright-directory-pointer point to the string. The
  824. 'IMAGE_SCN_CNT_INITIALIZED_DATA' bit should be set.
  825.  
  826.  
  827. exported symbols
  828. ----------------
  829. (Note that the description of the export directory was faulty in versions
  830. of this text before 1999-03-12. It didn't describe forwarders, exports
  831. by ordinal only, or exports with several names.)
  832.  
  833. The next-simplest thing is the export directory,
  834. 'IMAGE_DIRECTORY_ENTRY_EXPORT'. This is a directory typically found
  835. in DLLs; it contains the entry points of exported functions (and the
  836. addresses of exported objects etc.). Executables may of course also have
  837. exported symbols but usually they don't.
  838. The containing section should be "initialized data" and "readable". It
  839. should not be "discardable" because the process might call
  840. "GetProcAddress()" to find a function's entry point at runtime.
  841. The section is normally called '.edata' if it is a separate thing; often
  842. enough, it is merged into some other section like "initialized data".
  843.  
  844. The structure of the export table ('IMAGE_EXPORT_DIRECTORY') comprises a
  845. header and the export data, that is: the symbol names, their ordinals
  846. and the offsets to their entry points.
  847.  
  848. First, we have 32 bits of 'Characteristics' that are unused and normally
  849. 0. Then there is a 32-bit-'TimeDateStamp', which presumably should give
  850. the time the table was created in the time_t-format; alas, it is not
  851. always valid (some linkers set it to 0). Then we have 2 16-bit-words of
  852. version-info ('MajorVersion' and 'MinorVersion'), and these, too, are
  853. often enough set to 0.
  854.  
  855. The next thing is 32 bits of 'Name'; this is an RVA to the DLL name as a
  856. 0-terminated ASCII string. (The name is necessary in case the DLL file is
  857. renamed - see "binding" at the import directory.)
  858. Then, we have got a 32-bit-'Base'. We'll come to that in a moment.
  859.  
  860. The next 32-bit-value is the total number of exported items
  861. ('NumberOfFunctions'). In addition to their ordinal number, items may be
  862. exported by one or several names. and the next 32-bit-number is the
  863. total number of exported names ('NumberOfNames').
  864. In most cases, each exported item will have exactly one corresponding
  865. name and it will be used by that name, but an item may have several
  866. associated names (it is then accessible by each of them), or it may have
  867. no name, in which case it is only accessible by its ordinal number. The
  868. use of unnamed exports (purely by ordinal) is discouraged, because all
  869. versions of the exporting DLL would have to use the same ordinal
  870. numbering, which is a maintainance problem.
  871.  
  872. The next 32-bit-value 'AddressOfFunctions' is a RVA to the list of
  873. exported items. It points to an array of 'NumberOfFunctions'
  874. 32-bit-values, each being a RVA to the exported function or variable.
  875.  
  876. There are 2 quirks about this list: First, such an exported RVA may be 0,
  877. in which case it is unused. Second, if the RVA points into the section
  878. containing the export directory, this is a forwarded export. A forwarded
  879. export is a pointer to an export in another binary; if it is used, the
  880. pointed-to export in the other binary is used instead. The RVA in this
  881. case points, as mentioned, into the export directory's section, to a
  882. zero-terminated string comprising the name of the pointed-to DLL and
  883. the export name separated by a dot, like "otherdll.exportname", or the
  884. DLL's name and the export ordinal, like "otherdll.#19".
  885.  
  886. Now is the time to explain the export ordinal. An export's ordinal is
  887. the index into the AddressOfFunctions-Array (the 0-based position in
  888. this array) plus the 'Base' mentioned above.
  889. In most cases, the 'Base' is 1, which means the first export has an
  890. ordinal of 1, the second has an ordinal of 2 and so on.
  891.  
  892. After the 'AddressOfFunctions'-RVA we find a RVA to the array of
  893. 32-bit-RVAs to symbol names 'AddressOfNames', and a RVA to the array of
  894. 16-bit-ordinals 'AddressOfNameOrdinals'. Both arrays have
  895. 'NumberOfNames' elements.
  896. The symbol names may be missing entirely, in which case the
  897. 'AddressOfNames' is 0. Otherwise, the pointed-to arrays are running
  898. parallel, which means their elements at each index belong together. The
  899. 'AddressOfNames'-array consists of RVAs to 0-terminated export names;
  900. the names are held in a sorted list (i.e. the first array member is the
  901. RVA to the alphabetically smallest name; this allows efficient searching
  902. when looking up an exported symbol by name).
  903. According to the PE specification, the 'AddressOfNameOrdinals'-array has
  904. the ordinal corresponding to each name; however, I've found this array
  905. to contain the actual index into the 'AddressOfFunctions-Array instead.
  906.  
  907. I'll draw a picture about the three tables:
  908.  
  909.  
  910.     AddressOfFunctions
  911.            |
  912.            |
  913.            |
  914.            v
  915.     exported RVA with ordinal 'Base'
  916.     exported RVA with ordinal 'Base'+1
  917.     ...
  918.     exported RVA with ordinal 'Base'+'NumberOfFunctions'-1
  919.  
  920.  
  921.  
  922.     AddressOfNames                  AddressOfNameOrdinals
  923.            |                              |
  924.            |                              |
  925.            |                              |
  926.            v                              v
  927.     RVA to first name           <-> Index of export for first name
  928.     RVA to second name          <-> Index of export for second name
  929.     ...                             ...
  930.     RVA to name 'NumberOfNames' <-> Index of export for name 'NumberOfNames'
  931.  
  932.  
  933. Some examples are in order.
  934.  
  935. To find an exported symbol by ordinal, subtract the 'Base' to get the
  936. index, follow the 'AddressOfFunctions'-RVA to find the exports-array and
  937. use the index to find the exported RVA in the array. If it does not
  938. point into the export section, you are done. Otherwise, it points to a
  939. string describing the exporting DLL and the name or ordinal therein, and
  940. you have to look up the forwarded export there.
  941.  
  942. To find an exported symbol by name, follow the 'AddressOfNames'-RVA (if
  943. it is 0 there are no names) to find the array of RVAs to the export
  944. names. Search your name in the list. Use the name's index in the
  945. 'AddressOfNameOrdinals'-Array and get the 16-bit-number corresponding to
  946. the found name. According to the PE spec, it is an ordinal and you need
  947. to subtract the 'Base' to get the export index; according to my
  948. experiences it is the export index and you don't subtract. Using the
  949. export index, you find the export RVA in the 'AddressOfFunctions'-Array,
  950. being either the exported RVA itself or a RVA to a string describing a
  951. forwarded export.
  952.  
  953.  
  954. imported symbols
  955. ----------------
  956. When the compiler finds a call to a function that is in a different
  957. executable (mostly in a DLL), it will, in the most simplistic case, not
  958. know anything about the circumstances and simply output a normal
  959. call-instruction to that symbol, the address of which the linker will
  960. have to fix, like it does for any external symbol.
  961. The linker uses an import library to look up from which DLL which symnol
  962. is imported, and produces stubs for all the imported symbols, each of
  963. which consists of a jump-instruction; the stubs are the actual
  964. call-targets. These jump-instructions will actually jump to an address
  965. that's fetched from the so-called import address table. In more
  966. sophisticated applications (when "__declspec(dllimport)" is used), the
  967. compiler knows the function is imported, and outputs a call to the
  968. address that's in the import address table, bypassing the jump.
  969.  
  970. Anyway, the address of the function in the DLL is always necessary and
  971. will be supplied by the loader from the exporting DLL's export directory
  972. when the application is loaded. The loader knows which symbols in what
  973. libraries have to be looked up and their addresses fixed by searching
  974. the import directory.
  975.  
  976. I will better give you an example. The calls with or without
  977. __declspec(dllimport) look like this:
  978.  
  979.     source:
  980.         int symbol(char *);
  981.         __declspec(dllimport) int symbol2(char*);
  982.         void foo(void)
  983.         {
  984.             int i=symbol("bar");
  985.             int j=symbol2("baz");
  986.         }
  987.     
  988.     assembly:
  989.         ...
  990.         call _symbol                 ; without declspec(dllimport)
  991.         ...
  992.         call [__imp__symbol2]        ; with declspec(dllimport)
  993.         ...
  994.  
  995. In the first case (without __declspec(dllimport)), the compiler didn't
  996. know that '_symbol' was in a DLL, so the linker has to provide the
  997. function '_symbol'. Since the function isn't there, it will supply a
  998. stub function for the imported symbol, being an indirect jump. The
  999. collection of all import-stubs is called the "transfer area" (also
  1000. sometimes called a "trampoline", because you jump there in order to jump
  1001. to somewhere else).
  1002. Typically this transfer area is located in the code section (it is not
  1003. part of the import directory). Each of the function stubs is a jump to
  1004. the actual function in the target DLLs. The transfer area looks like
  1005. this:
  1006.  
  1007.     _symbol:        jmp  [__imp__symbol]
  1008.     _other_symbol:  jmp  [__imp__other__symbol]
  1009.     ...
  1010.  
  1011.  
  1012. This means: if you use imported symbols without specifying
  1013. "__declspec(dllimport)" then the linker will generate a transfer area
  1014. for them, consisting of indirect jumps. If you do specify
  1015. "__declspec(dllimport)", the compiler will do the indirection itself and
  1016. a transfer area is not necessary. (It also means: if you import
  1017. variables or other stuff you must specify "__declspec(dllimport)",
  1018. because a stub with a jmp instruction is appropriate for functions
  1019. only.)
  1020.  
  1021. In any case the adress of symbol 'x' is stored at a location '__imp_x'.
  1022. All these locations together comprise the so-called "import address
  1023. table", which is provided to the linker by the import libraries of the
  1024. various DLLs that are used. The import address table is a list of
  1025. addresses like this:
  1026.  
  1027.    __imp__symbol:   0xdeadbeef
  1028.    __imp__symbol2:  0x40100
  1029.    __imp__symbol3:  0x300100
  1030.    ...
  1031.  
  1032. This import address table is a part of the import directory, and it is
  1033. pointed to by the IMAGE_DIRECTORY_ENTRY_IAT directory pointer (although
  1034. some linkers don't set this directory entry and it works nevertheless;
  1035. apparently, the loader can resolve imports without using the directory
  1036. IMAGE_DIRECTORY_ENTRY_IAT).
  1037. The addresses in this table are unknown to the linker; the linker
  1038. inserts dummies (RVAs to the function names; see below for more
  1039. information) that are patched by the loader at load time using the
  1040. export directory of the exporting DLL. The import address table, and how
  1041. it is found by the loader, will be described in more detail later in
  1042. this chapter.
  1043.  
  1044. Note that this description is C-specific; there are other application
  1045. building environments that don't use import libraries. They all need to
  1046. generate an import address table, though, which they use to let their
  1047. programs access the imported objects and functions. C compilers tend to
  1048. use import libraries because it is convenient for them - their linkers
  1049. use libraries anyway. Other environments use e.g. a description file
  1050. that lists the necessary DLL names and function names (like the "module
  1051. definition file"), or a declaration-style list in the source.
  1052.  
  1053.  
  1054. This is how imports are used by the program's code; now we'll look how
  1055. an import directory is made up so the loader can use it.
  1056.  
  1057.  
  1058. The import directory should reside in a section that's "initialized
  1059. data" and "readable".
  1060. The import directory is an array of IMAGE_IMPORT_DESCRIPTORs, one for
  1061. each used DLL. The list is terminated by a IMAGE_IMPORT_DESCRIPTOR
  1062. that's entirely filled with 0-bytes.
  1063. An IMAGE_IMPORT_DESCRIPTOR is a struct with these members:
  1064.  
  1065.     OriginalFirstThunk
  1066.         An RVA (32 bit) pointing to a 0-terminated array of RVAs to
  1067.         IMAGE_THUNK_DATAs, each describing one imported function. The
  1068.         array will never change.
  1069.  
  1070.     TimeDateStamp
  1071.         A 32-bit-timestamp that has several purposes. Let's pretend that
  1072.         the timestamp is 0, and handle the advanced cases later.
  1073.  
  1074.     ForwarderChain
  1075.         The 32-bit-index of the first forwarder in the list of imported
  1076.         functions. Forwarders are also advanced stuff; set to all-bits-1
  1077.         for beginners.
  1078.         
  1079.     Name
  1080.         A 32-bit-RVA to the name (a 0-terminated ASCII string) of the
  1081.         DLL.
  1082.         
  1083.     FirstThunk
  1084.         An RVA (32 bit) to a 0-terminated array of RVAs to
  1085.         IMAGE_THUNK_DATAs, each describing one imported function. The
  1086.         array is part of the import address table and will change.
  1087.  
  1088. So each IMAGE_IMPORT_DESCRIPTOR in the array gives you the name of the
  1089. exporting DLL and, apart from the forwarder and timestamp, it gives you
  1090. 2 RVAs to arrays of IMAGE_THUNK_DATAs, using 32 bits. (The last member
  1091. of each array is entirely filled with 0-bytes to mark the end.)
  1092. Each IMAGE_THUNK_DATA is, for now, an RVA to a IMAGE_IMPORT_BY_NAME
  1093. which describes the imported function.
  1094. The interesting point is now, the arrays run parallel, i.e.: they point
  1095. to the same IMAGE_IMPORT_BY_NAMEs.
  1096.  
  1097. No need to be desparate, I will draw another picture. This is the
  1098. essential contents of one IMAGE_IMPORT_DESCRIPTOR:
  1099.  
  1100.      OriginalFirstThunk      FirstThunk
  1101.             |                    |
  1102.             |                    |
  1103.             |                    |
  1104.             V                    V
  1105.  
  1106.             0-->    func1     <--0
  1107.             1-->    func2     <--1
  1108.             2-->    func3     <--2
  1109.             3-->    foo       <--3
  1110.             4-->    mumpitz   <--4
  1111.             5-->    knuff     <--5
  1112.             6-->0            0<--6      /* the last RVA is 0! */
  1113.  
  1114. where the names in the center are the yet to discuss
  1115. IMAGE_IMPORT_BY_NAMEs. Each of them is a 16-bit-number (a hint) followed
  1116. by an unspecified amount of bytes, being the 0-terminated ASCII name of
  1117. the imported symbol.
  1118. The hint is an index into the exporting DLL's name table (see export
  1119. directory above). The name at that index is tried, and if it doesn't
  1120. match then a binary search is done to find the name.
  1121. (Some linkers don't bother to look up correct hints and simply specify
  1122. 1 all the time, or some other arbitrary number. This doesn't harm, it
  1123. just makes the first attempt to resolve the name always fail, enforcing
  1124. a binary search for each name.)
  1125.  
  1126. To summarize, if you want to look up information about the imported
  1127. function "foo" from DLL "knurr", you first find the entry
  1128. IMAGE_DIRECTORY_ENTRY_IMPORT in the data directories, get an RVA, find
  1129. that address in the raw section data and now have an array of
  1130. IMAGE_IMPORT_DESCRIPTORs. Get the member of this array that relates to
  1131. the DLL "knurr" by inspecting the strings pointed to by the 'Name's.
  1132. When you have found the right IMAGE_IMPORT_DESCRIPTOR, follow its
  1133. 'OriginalFirstThunk' and get hold of the pointed-to array of
  1134. IMAGE_THUNK_DATAs; inspect the RVAs and find the function "foo".
  1135.  
  1136. Ok, now, why do we have *two* lists of pointers to the
  1137. IMAGE_IMPORT_BY_NAMEs? Because at runtime the application doesn't need
  1138. the imported functions' names but the addresses. This is where the
  1139. import address table comes in again. The loader will look up each
  1140. imported symbol in the export-directory of the DLL in question and
  1141. replace the IMAGE_THUNK_DATA-element in the 'FirstThunk'-list (which
  1142. until now also points to the IMAGE_IMPORT_BY_NAME) with the linear
  1143. address of the DLL's entry point.
  1144. Remember the list of addresses with labels like "__imp__symbol"; the
  1145. import address table, pointed to by the data directory
  1146. IMAGE_DIRECTORY_ENTRY_IAT, is exactly the list pointed to by
  1147. 'FirstThunk'. (In case of imports from several DLLs, the import address
  1148. table comprises the 'FirstThunk'-Arrays of all the DLLs. The directory
  1149. entry IMAGE_DIRECTORY_ENTRY_IAT may be missing, the imports will still
  1150. work fine.)
  1151. The 'OriginalFirstThunk'-array remains untouched, so you can always look
  1152. up the original list of imported names via the
  1153. 'OriginalFirstThunk'-list.
  1154.  
  1155. The import is now patched with the correct linear addresses and looks
  1156. like this:
  1157.  
  1158.      OriginalFirstThunk      FirstThunk
  1159.             |                    |
  1160.             |                    |
  1161.             |                    |
  1162.             V                    V
  1163.  
  1164.             0-->    func1        0-->  exported func1
  1165.             1-->    func2        1-->  exported func2
  1166.             2-->    func3        2-->  exported func3
  1167.             3-->    foo          3-->  exported foo
  1168.             4-->    mumpitz      4-->  exported mumpitz
  1169.             5-->    knuff        5-->  exported knuff
  1170.             6-->0            0<--6
  1171.  
  1172.             
  1173. This was the basic structure, for simple cases. Now we'll learn about
  1174. tweaks in the import directories.
  1175.  
  1176. First, the bit IMAGE_ORDINAL_FLAG (that is: the MSB) of the
  1177. IMAGE_THUNK_DATA in the arrays can be set, in which case there is no
  1178. symbol-name-information in the list and the symbol is imported purely by
  1179. ordinal. You get the ordinal by inspecting the lower word of the
  1180. IMAGE_THUNK_DATA.
  1181. The import by ordinals is discouraged; it is much safer to import by
  1182. name, because the export ordinals might change if the exporting DLL is
  1183. not in the expected version.
  1184.  
  1185. Second, there are the so-called "bound imports".
  1186.  
  1187. Think about the loader's task: when a binary that it wants to execute
  1188. needs a function from a DLL, the loader loads the DLL, finds its export
  1189. directory, looks up the function's RVA and calculates the function's
  1190. entry point. Then it patches the so-found address into the 'FirstThunk'-
  1191. list.
  1192. Given that the programmer was clever and supplied unique preferred load
  1193. addresses for the DLLs that don't clash, we can assume that the
  1194. functions' entry points will always be the same. They can be computed
  1195. and patched into the 'FirstThunk'-list at link-time, and that's what
  1196. happens with the "bound imports". (The utility "bind" does this; it is
  1197. part of the Win32 SDK.)
  1198.  
  1199. Of course, one must be cautious: The user's DLL may have a different
  1200. version, or it may be necessary to relocate the DLL, thus invalidating
  1201. the pre-patched 'FirstThunk'-list; in this case, the loader will still
  1202. be able to walk the 'OriginalFirstThunk'-list, find the imported symbols
  1203. and re-patch the 'FirstThunk'-list. The loader knows that this is
  1204. necessary if a) the versions of the exporting DLL don't match or b) the
  1205. exporting DLL had to be relocated.
  1206.  
  1207. To decide whether there were relocations is no problem for the loader,
  1208. but how to find out if the versions differ? This is where the
  1209. 'TimeDateStamp' of the IMAGE_IMPORT_DESCRIPTOR comes in. If it is 0, the
  1210. import-list has not been bound, and the loader must fix the entry points
  1211. always. Otherwise, the imports are bound, and 'TimeDateStamp' must match
  1212. the 'TimeDateStamp' of the exporting DLL's 'FileHeader'; if it doesn't
  1213. match, the loader assumes that the binary is bound to a "wrong" DLL and
  1214. will re-patch the import list.
  1215.  
  1216. There is an additional quirk about "forwarders" in the import-list. A DLL
  1217. can export a symbol that's not defined in the DLL but imported from
  1218. another DLL; such a symbol is said to be forwarded (see the export
  1219. directory description above).
  1220. Now, obviously you can't tell if the symbol's entry point is valid by
  1221. looking into the timestamp of a DLL that doesn't actually contain the
  1222. entry point. So the forwarded symbols' entry points must always be fixed
  1223. up, for safety reasons. In the import list of a binary, imports of
  1224. forwarded symbols need to be found so the loader can patch them.
  1225.  
  1226. This is done via the 'ForwarderChain'. It is an index into the thunk-
  1227. lists; the import at the indexed position is a forwarded export, and the
  1228. contents of the 'FirstThunk'-list at this position is the index of the
  1229. *next* forwarded import, and so on, until the index is "-1" which
  1230. indicates there are no more forwards. If there are no forwarders at all,
  1231. 'ForwarderChain' is -1 itself.
  1232.  
  1233. This was the so-called "old-style" binding.
  1234.  
  1235. At this point, we should sum up what we have had so far :-)
  1236.  
  1237. Ok, I will assume you have found the IMAGE_DIRECTORY_ENTRY_IMPORT and you have
  1238. followed it to find the import-directory, which will be in one of the
  1239. sections. Now you're at the beginning of an array of
  1240. IMAGE_IMPORT_DESCRIPTORs the last of which will be entirely 0-bytes-
  1241. filled.
  1242. To decipher one of the IMAGE_IMPORT_DESCRIPTORs, you first look into the
  1243. 'Name'-field, follow the RVA and thusly find the name of the exporting
  1244. DLL. Next you decide whether the imports are bound or not;
  1245. 'TimeDateStamp' will be non-zero if the imports are bound. If they are
  1246. bound, now is a good time to check if the DLL version matches yours by
  1247. comparing the 'TimeDateStamp's.
  1248. Now you follow the 'OriginalFirstThunk'-RVA to go to the
  1249. IMAGE_THUNK_DATA-array; walk down this array (it is be 0-terminated),
  1250. and each member will be the RVA of a IMAGE_IMPORT_BY_NAME (unless the
  1251. hi-bit is set in which case you don't have a name but are left with a
  1252. mere ordinal). Follow the RVA, and skip 2 bytes (the hint), and now
  1253. you have got a 0-terminated ASCII-string that's the name of the imported
  1254. function.
  1255. To find the supplied entry point addresses in case it is a bound import,
  1256. follow the 'FirstThunk' and walk it parallel to the
  1257. 'OriginalFirstThunk'-array; the array-members are the linear addresses
  1258. of the entry points (leaving aside the forwarders-topic for a moment).
  1259.  
  1260. There is one thing I didn't mention until now: Apparently there are
  1261. linkers that exhibit a bug when they build the import directory (I've
  1262. found this bug being in use by a Borland C linker). These linkers set
  1263. the 'OriginalFirstThunk' in the IMAGE_IMPORT_DESCRIPTOR to 0 and create
  1264. only the 'FirstThunk'-array. Obviously, such import directories cannot
  1265. be bound (else the necessary information to re-fix the imports were
  1266. lost - you couldn't find the function names). In this case, you will
  1267. have to follow the 'FirstThunk'-array to get the imported symbol names,
  1268. and you will never have pre-patched entry point addresses. I have found
  1269. a TIS document ([6]) describing the import directory in a way that is
  1270. compatible to this bug, so that paper may be the origin of the bug.
  1271. The TIS document specifies:
  1272.     IMPORT FLAGS
  1273.     TIME/DATE STAMP
  1274.     MAJOR VERSION - MINOR VERSION
  1275.     NAME RVA
  1276.     IMPORT LOOKUP TABLE RVA
  1277.     IMPORT ADDRESS TABLE RVA
  1278. as opposed to the structure used elsewhere:
  1279.     OriginalFirstThunk
  1280.     TimeDateStamp
  1281.     ForwarderChain
  1282.     Name
  1283.     FirstThunk
  1284.  
  1285. The last tweak about the import directories is the so-called "new style"
  1286. binding (it is described in [3]), which can also be done with the
  1287. "bind"-utility. When this is used, the 'TimeDateStamp' is set to
  1288. all-bits-1 and there is no forwarderchain; all imported symbols get their
  1289. address patched, whether they are forwarded or not. Still, you need to
  1290. know the DLLs' version, and you need to distinguish forwarded symbols
  1291. from ordinary ones. For this purpose, the
  1292. IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT directory is created. This will, as
  1293. far as I could find out, *not* be in a section but in the header, after
  1294. the section headers and before the first section. (Hey, I didn't invent
  1295. this, I'm only describing it!)
  1296. This directory tells you, for each used DLL, from which other DLLs there
  1297. are forwarded exports.
  1298. The structure is an IMAGE_BOUND_IMPORT_DESCRIPTOR, comprising (in this
  1299. order):
  1300. A 32-bit number, giving you the 'TimeDateStamp' of the DLL;
  1301. a 16-bit-number 'OffsetModuleName', being the offset from the beginning
  1302. of the directory to the 0-terminated name of the DLL;
  1303. a 16-bit-number 'NumberOfModuleForwarderRefs' giving you the number of
  1304. DLLs that this DLL uses for its forwarders.
  1305.  
  1306. Immediatly following this struct you find 'NumberOfModuleForwarderRefs'
  1307. structs that tell you the names and versions of the DLLs that this DLL
  1308. forwards from. These structs are 'IMAGE_BOUND_FORWARDER_REF's:
  1309. A 32-bit-number 'TimeDateStamp';
  1310. a 16-bit-number 'OffsetModuleName', being the offset from the beginning
  1311. of the directory to the 0-terminated name of the forwarded-from DLL;
  1312. 16 unused bits.
  1313.  
  1314. Following the 'IMAGE_BOUND_FORWARDER_REF's is the next
  1315. 'IMAGE_BOUND_IMPORT_DESCRIPTOR' and so on; the list is terminated by an
  1316. all-0-bits-IMAGE_BOUND_IMPORT_DESCRIPTOR.
  1317.  
  1318.  
  1319. Sorry for the inconvenience, but that's what it looks like :-)
  1320.  
  1321.  
  1322. Now, if you have a new-bound import directory, you load all the DLLs,
  1323. use the directory pointer IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT to find the
  1324. IMAGE_BOUND_IMPORT_DESCRIPTOR, scan through it and check if the
  1325. 'TimeDateStamp's of the loaded DLLs match the ones given in this
  1326. directory. If not, fix them in the 'FirstThunk'-array of the import
  1327. directory.
  1328.  
  1329.  
  1330.  
  1331. resources
  1332. ---------
  1333. The resources, such as dialog boxes, menus, icons and so on, are stored
  1334. in the data directory pointed to by IMAGE_DIRECTORY_ENTRY_RESOURCE. It
  1335. is in a section that has, at least, the bits
  1336. 'IMAGE_SCN_CNT_INITIALIZED_DATA' and 'IMAGE_SCN_MEM_READ' set.
  1337.  
  1338. A resource base is a 'IMAGE_RESOURCE_DIRECTORY'; it contains several
  1339. 'IMAGE_RESOURCE_DIRECTORY_ENTRY's each of which in turn may point to a
  1340. 'IMAGE_RESOURCE_DIRECTORY'. This way, you get a tree of
  1341. 'IMAGE_RESOURCE_DIRECTORY's with 'IMAGE_RESOURCE_DIRECTORY_ENTRY's as
  1342. leafs; these leafs point to the actual resource data.
  1343.  
  1344. In real life, the situation is somewhat relaxed. Normally you won't find
  1345. convoluted trees you can't possibly sort out.
  1346. The hierarchy is, normally, like this: one directory is the root. It
  1347. points to directories, one for each resource type. These directories
  1348. point to subdirectories, each of which will have a name or an ID and
  1349. point to a directory of the languages provided for this resource; for
  1350. each language you will find one resource entry, which will finally point
  1351. to the data. (Note that multi-language-resources don't work on
  1352. Win95, which always uses the same resource if it is available in several
  1353. languages - I didn't check which one, but I guess it's the first it
  1354. encounters. They do work on NT.)
  1355.  
  1356. The tree, without the pointer to the data, may look like this:
  1357.  
  1358.                            (root)
  1359.                               |
  1360.              +----------------+------------------+
  1361.              |                |                  |
  1362.             menu            dialog             icon
  1363.              |                |                  |
  1364.        +-----+-----+        +-+----+           +-+----+----+
  1365.        |           |        |      |           |      |    |
  1366.     "main"      "popup"   0x10   "maindlg"    0x100 0x110 0x120
  1367.        |            |       |      |           |      |    | 
  1368.    +---+-+          |       |      |           |      |    |
  1369.    |     |     default   english   default    def.   def.  def.
  1370. german english
  1371.  
  1372.  
  1373. A IMAGE_RESOURCE_DIRECTORY comprises:
  1374. 32 bits of unused flags called 'Characteristics';
  1375. 32 bits 'TimeDateStamp' (again in the common time_t representation),
  1376. giving you the time the resource was created (if the entry is set);
  1377. 16 bits 'MajorVersion' and 16 bits 'MinorVersion', thusly allowing you
  1378. to maintain several versions of the resource;
  1379. 16 bits 'NumberOfNamedEntries' and another 16 bits 'NumberOfIdEntries'.
  1380.  
  1381. Immediatly following such a structure are
  1382. 'NumberOfNamedEntries'+'NumberOfIdEntries' structs which are of the
  1383. format 'IMAGE_RESOURCE_DIRECTORY_ENTRY', those with the names coming first.
  1384. They may point to further 'IMAGE_RESOURCE_DIRECTORY's or they point to
  1385. the actual resource data.
  1386. A IMAGE_RESOURCE_DIRECTORY_ENTRY consists of:
  1387. 32 bits giving you the id of the resource or the directory it describes;
  1388. 32 bits offset to the data or offset to the next sub-directory.
  1389.  
  1390. The meaning of the id depends on the level in the tree; the id may be a
  1391. number (if the hi-bit is clear) or a name (if the hi-bit is set). If it
  1392. is a name, the lower 31 bits are the offset from the beginning of the
  1393. resource section's raw data to the name (the name consists of 16 bits
  1394. length and trailing wide characters, in unicode, not 0-terminated).
  1395.  
  1396. If you are in the root-directory, the id, if it is a number, is the
  1397. resource-type:
  1398.     1: cursor
  1399.     2: bitmap
  1400.     3: icon
  1401.     4: menu
  1402.     5: dialog
  1403.     6: string table
  1404.     7: font directory
  1405.     8: font
  1406.     9: accelerators
  1407.     10: unformatted resource data
  1408.     11: message table
  1409.     12: group cursor
  1410.     14: group icon
  1411.     16: version information
  1412. Any other number is user-defined. Any resource-type with a type-name is
  1413. always user-defined.
  1414.  
  1415. If you are one level deeper, the id is the resource-id (or resource-
  1416. name).
  1417.  
  1418. If you are another level deeper, the id must be a number, and it is the
  1419. language-id of the specific instance of the resource; for example, you
  1420. can have the same dialog in australian english, canadian french and
  1421. swiss german localized forms, and they all share the same resource-id.
  1422. The system will choose the dialog to load based on the thread's locale,
  1423. which in turn will usually reflect the user's "regional setting".
  1424. (If the resource cannot be found for the thread locale, the system will
  1425. first try to find a resource for the locale using a neutral sublanguage,
  1426. e.g. it will look for standard french instead of the user's canadian
  1427. french; if it still can't be found, the instance with the smallest
  1428. language id will be used. As noted, all this works only on NT.)
  1429. To decipher the language id, split it into the primary language id and
  1430. the sublanguage id using the macros PRIMARYLANGID() and SUBLANGID(),
  1431. giving you the bits 0 to 9 or 10 to 15, respectivly. The values are
  1432. defined in the file "winresrc.h".
  1433. Language-resources are only supported for accelerators, dialogs, menus,
  1434. rcdata or stringtables; other resource-types should be
  1435. LANG_NEUTRAL/SUBLANG_NEUTRAL.
  1436.  
  1437. To find out whether the next level below a resource directory is another
  1438. directory, you inspect the hi-bit of the offset. If it is set, the
  1439. remaining 31 bits are the offset from the beginning of the resource
  1440. section's raw data to the next directory, again in the format
  1441. IMAGE_RESOURCE_DIRECTORY with trailing IMAGE_RESOURCE_DIRECTORY_ENTRYs.
  1442.  
  1443. If the bit is clear, the offset is the distance from the beginning of
  1444. the resource section's raw data to the resource's raw data description,
  1445. a IMAGE_RESOURCE_DATA_ENTRY. It consists of 32 bits 'OffsetToData' (the
  1446. offset to the raw data, counting from the beginning of the resource
  1447. section's raw data), 32 bits of 'Size' of the data, 32 bits 'CodePage'
  1448. and 32 unused bits.
  1449. (The use of codepages is discouraged, you should use the 'language'-
  1450. feature to support multiple locales.)
  1451.  
  1452.  
  1453. The raw data format depends on the resource type; descriptions can be
  1454. found in the MS SDK documentation. Note that any string in resources is
  1455. always in UNICODE except for user defined resources, which are in the
  1456. format the developer chooses, obviously.
  1457.  
  1458.  
  1459. relocations
  1460. -----------
  1461. The last data directory I will describe is the base relocation
  1462. directory. It is pointed to by the IMAGE_DIRECTORY_ENTRY_BASERELOC entry
  1463. in the data directories of the optional header. It is typically
  1464. contained in a section if its own, with a name like ".reloc" and the
  1465. bits IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE and
  1466. IMAGE_SCN_MEM_READ set.
  1467.  
  1468. The relocation data is needed by the loader if the image cannot be
  1469. loaded to the preferred load address 'ImageBase' mentioned in the
  1470. optional header. In this case, the fixed addresses supplied by the
  1471. linker are no longer valid, and the loader has to apply fixups for
  1472. absolute addresses used for locations of static variables, string
  1473. literals and so on.
  1474.  
  1475. The relocation directory is a sequence of chunks. Each chunk contains
  1476. the relocation information for 4 KB of the image. A chunk starts with a
  1477. 'IMAGE_BASE_RELOCATION' struct. It consists of 32 bits 'VirtualAddress'
  1478. and 32 bits 'SizeOfBlock'. It is followed by the chunk's actual
  1479. relocation data, being 16 bits each.
  1480. The 'VirtualAddress' is the base RVA that the relocations of this chunk
  1481. need to be applied to; the 'SizeOfBlock' is the size of the entire chunk
  1482. in bytes.
  1483. The number of trailing relocations is
  1484. ('SizeOfBlock'-sizeof(IMAGE_BASE_RELOCATION))/2
  1485. The relocation information ends when you encounter a
  1486. IMAGE_BASE_RELOCATION struct with a 'VirtualAddress' of 0.
  1487.  
  1488. Each 16-bit-relocation information consists of the relocation position
  1489. in the lower 12 bits and a relocation type in the high 4 bits. To get
  1490. the relocation RVA, you need to add the IMAGE_BASE_RELOCATION's
  1491. 'VirtualAddress' to the 12-bit-position. The type is one of:
  1492.     IMAGE_REL_BASED_ABSOLUTE (0)
  1493.         This is a no-op; it is used to align the chunk to a 32-bits-
  1494.         border. The position should be 0.
  1495.     IMAGE_REL_BASED_HIGH (1)
  1496.         The high 16 bits of the relocation must be applied to the 16
  1497.         bits of the WORD pointed to by the offset, which is the high
  1498.         word of a 32-bit-DWORD.
  1499.     IMAGE_REL_BASED_LOW (2)
  1500.         The low 16 bits of the relocation must be applied to the 16
  1501.         bits of the WORD pointed to by the offset, which is the low
  1502.         word of a 32-bit-DWORD.
  1503.     IMAGE_REL_BASED_HIGHLOW (3)
  1504.         The entire 32-bit-relocation must be applied to the entire 32
  1505.         bits in question. This (and the no-op '0') is the only
  1506.         relocation type I've actually found in binaries.
  1507.     IMAGE_REL_BASED_HIGHADJ (4)
  1508.         This is one for the tough. Read yourself (from [6]) and make
  1509.         sense out of it if you can:
  1510.         "Highadjust. This fixup requires a full 32-bit value. The high
  1511.         16-bits is located at Offset, and the low 16-bits is located in
  1512.         the next Offset array element (this array element is included in
  1513.         the Size field). The two need to be combined into a signed
  1514.         variable. Add the 32-bit delta. Then add 0x8000 and store the
  1515.         high 16-bits of the signed variable to the 16-bit field at
  1516.         Offset."
  1517.     IMAGE_REL_BASED_MIPS_JMPADDR (5)
  1518.         Unknown
  1519.     IMAGE_REL_BASED_SECTION (6)
  1520.         Unknown
  1521.     IMAGE_REL_BASED_REL32 (7)
  1522.         Unknown
  1523.  
  1524. As an example, if you find the relocation information to be
  1525.     0x00004000      (32 bits, starting RVA)
  1526.     0x00000010      (32 bits, size of chunk)
  1527.     0x3012          (16 bits reloc data)
  1528.     0x3080          (16 bits reloc data)
  1529.     0x30f6          (16 bits reloc data)
  1530.     0x0000          (16 bits reloc data)
  1531.     0x00000000      (next chunk's RVA)
  1532.     0xff341234
  1533. you know the first chunk describes relocations starting at RVA 0x4000 and
  1534. is 16 bytes long. Because the header uses 8 bytes and one relocation
  1535. uses 2 bytes, there are (16-8)/2=4 relocations in the chunk.
  1536. The first relocation is to be applied to the DWORD at 0x4012, the next
  1537. to the DWORD at 0x4080, and the third to the DWORD at 0x40f6. The last
  1538. relocation is a no-op.
  1539. The next chunk has a RVA of 0 and finishes the list.
  1540.  
  1541. Now, how do you do a relocation?
  1542. You know that the image *is* relocated to the preferred load address
  1543. 'ImageBase' in the optional header; you also know the address you did
  1544. load the image to. If they match, you don't need to do anything.
  1545. If they don't match, you calculate the difference
  1546. actual_base-preferred_base
  1547. and add that value (signed, it may be negative) to the relocation
  1548. positions, which you will find with the method described above.
  1549.  
  1550.  
  1551. Acknowledgments
  1552. ---------------
  1553. Thanks go to David Binette for his debugging and proof-reading.
  1554. (The remaining errors are entirely mine.)
  1555. Also thanks to wotsit.org for letting me put the file on their site.
  1556.  
  1557.  
  1558. Copyright
  1559. ---------
  1560. This text is copyright 1999 by B. Luevelsmeyer. It is freeware, and you
  1561. may use it for any purpose but on your own risk. It contains errors and
  1562. it is incomplete. You have been warned.
  1563.  
  1564.  
  1565. Bug reports
  1566. -----------
  1567. Send any bug reports (or other comments) to
  1568. bernd.luevelsmeyer@iplan.heitec.net
  1569.  
  1570.  
  1571. Versions
  1572. --------
  1573. You find the date of the current release at the top of the file.
  1574.  
  1575. 1998-04-06
  1576.   First public release
  1577.  
  1578. 1998-07-29
  1579.   Changed wrong "byte" to "word" for image version and subsystem version
  1580.   Corrected error "stack is limited to 1 MB" (in fact it is not limited)
  1581.   Corrected some typos
  1582.  
  1583. 1999-03-15
  1584.   Corrected export directory description, which was very incomplete
  1585.   Reworded import directory description, which had been unclear
  1586.   Corrected typos and did some rewording in other sections
  1587.   
  1588.  
  1589. Literature
  1590. ----------
  1591.  
  1592. [1]
  1593. "Peering Inside the PE: A Tour of the Win32 Portable Executable File
  1594. Format" (M. Pietrek), in: Microsoft Systems Journal 3/1994
  1595.  
  1596. [2]
  1597. "Why to Use _declspec(dllimport) & _declspec(dllexport) In Code", MS
  1598. Knowledge Base Q132044
  1599.  
  1600. [3]
  1601. "Windows Q&A" (M. Pietrek), in: Microsoft Systems Journal 8/1995
  1602.  
  1603. [4]
  1604. "Writing Multiple-Language Resources", MS Knowledge Base Q89866
  1605.  
  1606. [5]
  1607. "The Portable Executable File Format from Top to Bottom" (Randy Kath),
  1608. in: Microsoft Developer Network
  1609.  
  1610. [6]
  1611. Tool Interface Standard (TIS) Formats Specification for Windows Version
  1612. 1.0 (Intel Order Number 241597, Intel Corporation 1993)
  1613.  
  1614.  
  1615. Appendix: hello world
  1616. ---------------------
  1617. In this appendix I will show how to make programs by hand. The example
  1618. will use Intel-assembly, because I don't speak DEC Alpha.
  1619.  
  1620. The program will be the equivalent of
  1621.  
  1622.     #include <stdio.h>
  1623.     int main(void)
  1624.     {
  1625.         puts(hello,world);
  1626.         return 0;
  1627.     }
  1628.  
  1629. First, I translate it to use Win32 functions instead of the C runtime:
  1630.  
  1631.     #define STD_OUTPUT_HANDLE -11UL
  1632.     #define hello "hello, world\n"
  1633.  
  1634.     __declspec(dllimport) unsigned long __stdcall
  1635.     GetStdHandle(unsigned long hdl);
  1636.  
  1637.     __declspec(dllimport) unsigned long __stdcall
  1638.     WriteConsoleA(unsigned long hConsoleOutput,
  1639.                     const void *buffer,
  1640.                     unsigned long chrs,
  1641.                     unsigned long *written,
  1642.                     unsigned long unused
  1643.                     );
  1644.  
  1645.     static unsigned long written;
  1646.  
  1647.     void startup(void)
  1648.     {
  1649.         WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),hello,sizeof(hello)-1,&written,0);
  1650.         return;
  1651.     }
  1652.  
  1653. Now I will fumble out the assembly:
  1654.     startup:
  1655.                 ; parameters for WriteConsole(), backwards
  1656.     6A 00                     push      0x00000000
  1657.     68 ?? ?? ?? ??            push      offset _written
  1658.     6A 0D                     push      0x0000000d
  1659.     68 ?? ?? ?? ??            push      offset hello
  1660.                 ; parameter for GetStdHandle()
  1661.     6A F5                     push      0xfffffff5
  1662.     2E FF 15 ?? ?? ?? ??      call      dword ptr cs:__imp__GetStdHandle@4
  1663.                 ; result is last parameter for WriteConsole()
  1664.     50                        push      eax
  1665.     2E FF 15 ?? ?? ?? ??      call      dword ptr cs:__imp__WriteConsoleA@20
  1666.     C3                        ret       
  1667.  
  1668.     hello:
  1669.     68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A   "hello, world\n"
  1670.     _written:
  1671.     00 00 00 00
  1672.  
  1673. That was the compiler part. Anyone can do that. From now on we play
  1674. linker, which is much more interesting :-)
  1675.  
  1676. I need to find the functions WriteConsoleA() and GetStdHandle(). They
  1677. happen to be in "kernel32.dll". (That was the 'import library' part.)
  1678.  
  1679. Now I can start to make the executable. Question marks will take the
  1680. place of yet-to-find-out values; they will be patched afterwards.
  1681.  
  1682. First the DOS-stub, starting at 0x0 and being 0x40 bytes long:
  1683.     00 | 4d 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  1684.     10 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  1685.     20 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  1686.     30 | 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00
  1687. As you can see, this isn't really a MS-DOS program. It's just the header
  1688. with the signature "MZ" at the beginning and the e_lfanew pointing
  1689. immediatly after the header, without any code. That's because it isn't
  1690. intended to run on MS-DOS; it's just here because the specification
  1691. requires it.
  1692.  
  1693. Then the PE signature, starting at 0x40 and being 0x4 bytes long:
  1694.         50 45 00 00
  1695.  
  1696. Now the file-header, which will start at byte 0x44 and is 0x14 bytes long:
  1697.     Machine                     4c 01       ; i386
  1698.     NumberOfSections            02 00       ; code and data
  1699.     TimeDateStamp               00 00 00 00 ; who cares?
  1700.     PointerToSymbolTable        00 00 00 00 ; unused
  1701.     NumberOfSymbols             00 00 00 00 ; unused
  1702.     SizeOfOptionalHeader        e0 00       ; constant
  1703.     Characteristics             02 01       ; executable on 32-bit-machine
  1704.  
  1705. And the optional header, which will start at byte 0x58 and is 0x60 bytes long:
  1706.     Magic                       0b 01       ; constant
  1707.     MajorLinkerVersion          00          ; I'm version 0.0 :-)
  1708.     MinorLinkerVersion          00          ;
  1709.     SizeOfCode                  20 00 00 00 ; 32 bytes of code
  1710.     SizeOfInitializedData       ?? ?? ?? ?? ; yet to find out
  1711.     SizeOfUninitializedData     00 00 00 00 ; we don't have a BSS
  1712.     AddressOfEntryPoint         ?? ?? ?? ?? ; yet to find out
  1713.     BaseOfCode                  ?? ?? ?? ?? ; yet to find out
  1714.     BaseOfData                  ?? ?? ?? ?? ; yet to find out
  1715.     ImageBase                   00 00 10 00 ; 1 MB, chosen arbitrarily
  1716.     SectionAlignment            20 00 00 00 ; 32-bytes-alignment
  1717.     FileAlignment               20 00 00 00 ; 32-bytes-alignment
  1718.     MajorOperatingSystemVersion  04 00      ; NT 4.0
  1719.     MinorOperatingSystemVersion  00 00      ;
  1720.     MajorImageVersion           00 00       ; version 0.0
  1721.     MinorImageVersion           00 00       ;
  1722.     MajorSubsystemVersion       04 00       ; Win32 4.0
  1723.     MinorSubsystemVersion       00 00       ;
  1724.     Win32VersionValue           00 00 00 00 ; unused?
  1725.     SizeOfImage                 ?? ?? ?? ?? ; yet to find out
  1726.     SizeOfHeaders               ?? ?? ?? ?? ; yet to find out
  1727.     CheckSum                    00 00 00 00 ; not used for non-drivers
  1728.     Subsystem                   03 00       ; Win32 console
  1729.     DllCharacteristics          00 00       ; unused (not a DLL)
  1730.     SizeOfStackReserve          00 00 10 00 ; 1 MB stack
  1731.     SizeOfStackCommit           00 10 00 00 ; 4 KB to start with
  1732.     SizeOfHeapReserve           00 00 10 00 ; 1 MB heap
  1733.     SizeOfHeapCommit            00 10 00 00 ; 4 KB to start with
  1734.     LoaderFlags                 00 00 00 00 ; unknown
  1735.     NumberOfRvaAndSizes         10 00 00 00 ; constant
  1736.  
  1737. As you can see, I plan to have only 2 sections, one for code and one for
  1738. all the rest (data, constants and import directory). There will be no
  1739. relocations and no other stuff like resources. Also I won't have a BSS
  1740. segment and stuff the variable 'written' into the initialized data.
  1741. The section alignment is the same in the file and in RAM (32 bytes);
  1742. this helps to keep the task easy, otherwise I'd have to calculate RVAs
  1743. back and forth too much.
  1744.  
  1745. Now we set up the data directories, beginning at byte 0xb8 and being 0x80 bytes long:
  1746.     Address        Size
  1747.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_EXPORT (0)
  1748.     ?? ?? ?? ??    ?? ?? ?? ??         ; IMAGE_DIRECTORY_ENTRY_IMPORT (1)
  1749.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
  1750.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
  1751.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_SECURITY (4)
  1752.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
  1753.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_DEBUG (6)
  1754.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
  1755.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
  1756.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_TLS (9)
  1757.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
  1758.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
  1759.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_IAT (12)
  1760.     00 00 00 00    00 00 00 00         ; 13
  1761.     00 00 00 00    00 00 00 00         ; 14
  1762.     00 00 00 00    00 00 00 00         ; 15
  1763. Only the import directory is in use.
  1764.  
  1765. Next are the section headers. First we make the code section, which will
  1766. contain the above mentioned assembly. It is 32 bytes long, and so will
  1767. be the code section. The header begins at 0x138 and is 0x28 bytes long:
  1768.  
  1769.     Name            2e 63 6f 64 65 00 00 00     ; ".code"
  1770.     VirtualSize         00 00 00 00             ; unused
  1771.     VirtualAddress      ?? ?? ?? ??             ; yet to find out
  1772.     SizeOfRawData       20 00 00 00             ; size of code
  1773.     PointerToRawData    ?? ?? ?? ??             ; yet to find out
  1774.     PointerToRelocations 00 00 00 00            ; unused
  1775.     PointerToLinenumbers 00 00 00 00            ; unused
  1776.     NumberOfRelocations  00 00                  ; unused
  1777.     NumberOfLinenumbers  00 00                  ; unused
  1778.     Characteristics     20 00 00 60             ; code, executable, readable
  1779.  
  1780. The second section will contain the data. The header begins at 0x160 and
  1781. is 0x28 bytes long:
  1782.  
  1783.     Name            2e 64 61 74 61 00 00 00     ; ".data"
  1784.     VirtualSize         00 00 00 00             ; unused
  1785.     VirtualAddress      ?? ?? ?? ??             ; yet to find out
  1786.     SizeOfRawData       ?? ?? ?? ??             ; yet to find out
  1787.     PointerToRawData    ?? ?? ?? ??             ; yet to find out
  1788.     PointerToRelocations 00 00 00 00            ; unused
  1789.     PointerToLinenumbers 00 00 00 00            ; unused
  1790.     NumberOfRelocations  00 00                  ; unused
  1791.     NumberOfLinenumbers  00 00                  ; unused
  1792.     Characteristics     40 00 00 c0             ; initialized, readable, writeable
  1793.  
  1794. The next byte is 0x188, but the sections need to be aligned to 32 bytes
  1795. (because I chose so), so we need padding bytes up to 0x1a0:
  1796.  
  1797.     00 00 00 00 00 00       ; padding
  1798.     00 00 00 00 00 00
  1799.     00 00 00 00 00 00
  1800.     00 00 00 00 00 00
  1801.  
  1802.  
  1803. Now the first section, being the code section with the above mentioned
  1804. assembly, *does* come. It begins at byte 0x1a0 and is 0x20 bytes long:
  1805.     6A 00                    ; push      0x00000000
  1806.     68 ?? ?? ?? ??           ; push      offset _written
  1807.     6A 0D                    ; push      0x0000000d
  1808.     68 ?? ?? ?? ??           ; push      offset hello_string
  1809.     6A F5                    ; push      0xfffffff5
  1810.     2E FF 15 ?? ?? ?? ??     ; call      dword ptr cs:__imp__GetStdHandle@4
  1811.     50                       ; push      eax
  1812.     2E FF 15 ?? ?? ?? ??     ; call      dword ptr cs:__imp__WriteConsoleA@20
  1813.     C3                       ; ret       
  1814.  
  1815. Because of the previous section's length we don't need any padding
  1816. before the next section (data), and here it comes, beginning at 0x1c0:
  1817.  
  1818.     68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A  ; "hello, world\n"
  1819.     00 00 00                                ; padding to align _written
  1820.     00 00 00 00                             ; _written
  1821.  
  1822. Now all that's left is the import directory. It will import 2 functions
  1823. from "kernel32.dll", and it's immediatly following the variables in the
  1824. same section. First we will align it to 32 bytes:
  1825.  
  1826.     00 00 00 00 00 00 00 00 00 00 00 00     ; padding
  1827.  
  1828. It begins at 0x1e0 with the IMAGE_IMPORT_DESCRIPTOR:
  1829.     OriginalFirstThunk      ?? ?? ?? ??     ; yet to find out
  1830.     TimeDateStamp           00 00 00 00     ; unbound
  1831.     ForwarderChain          ff ff ff ff     ; no forwarders
  1832.     Name                    ?? ?? ?? ??     ; yet to find out
  1833.     FirstThunk              ?? ?? ?? ??     ; yet to find out
  1834.  
  1835. We need to terminate the import-directory with a 0-bytes-entry (we are at 0x1f4):
  1836.     OriginalFirstThunk      00 00 00 00     ; terminator
  1837.     TimeDateStamp           00 00 00 00     ;
  1838.     ForwarderChain          00 00 00 00     ;
  1839.     Name                    00 00 00 00     ;
  1840.     FirstThunk              00 00 00 00     ;
  1841.  
  1842. Now there's the DLL name left, and the 2 thunks, and the thunk-data, and
  1843. the function names. But we will be finished real soon now!
  1844.  
  1845. The DLL name, 0-terminated, beginning at 0x208:
  1846.     6b 65 72 6e 65 6c 33 32 2e 64 6c 6c 00  ; "kernel32.dll"
  1847.     00 00 00                                ; padding to 32-bit-boundary
  1848.  
  1849. The original first thunk, starting at 0x218:
  1850.     AddressOfData   ?? ?? ?? ??             ; RVA to function name "WriteConsoleA"
  1851.     AddressOfData   ?? ?? ?? ??             ; RVA to function name "GetStdHandle"
  1852.                     00 00 00 00             ; terminator
  1853.  
  1854. The first thunk is exactly the same list and starts at 0x224:
  1855. (__imp__WriteConsoleA@20, at 0x224)
  1856.     AddressOfData   ?? ?? ?? ??             ; RVA to function name "WriteConsoleA"
  1857. (__imp__GetStdHandle@4, at 0x228)
  1858.     AddressOfData   ?? ?? ?? ??             ; RVA to function name "GetStdHandle"
  1859.                     00 00 00 00             ; terminator
  1860.  
  1861. Now what's left is the two function names in the shape of an
  1862. IMAGE_IMPORT_BY_NAME. We are at byte 0x230.
  1863.     01 00                                      ; ordinal, need not be correct
  1864.     57 72 69 74 65 43 6f 6e 73 6f 6c 65 41 00  ; "WriteConsoleA"
  1865.     02 00                                      ; ordinal, need not be correct
  1866.     47 65 74 53 74 64 48 61 6e 64 6c 65 00     ; "GetStdHandle"
  1867.  
  1868. Ok, that's about all. The next byte, which we don't really need, is
  1869. 0x24f. We need to fill the section with padding up to 0x260:
  1870.     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; padding
  1871.     00
  1872.  
  1873. ------------
  1874.  
  1875. We are done. Now that we know all the byte-offsets, we can apply fixups
  1876. to all those addresses and sizes that were indicated as "unknown" with
  1877. '??'-marks.
  1878. I won't force you to read that step-by-step (it's quite
  1879. straightforward), and simply present the result:
  1880.  
  1881. ------------
  1882.  
  1883. DOS-header, starting at 0x0:
  1884.     00 | 4d 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  1885.     10 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  1886.     20 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  1887.     30 | 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00
  1888.  
  1889. signature, starting at 0x40:
  1890.         50 45 00 00
  1891.  
  1892. file-header, starting at 0x44:
  1893.     Machine                     4c 01       ; i386
  1894.     NumberOfSections            02 00       ; code and data
  1895.     TimeDateStamp               00 00 00 00 ; who cares?
  1896.     PointerToSymbolTable        00 00 00 00 ; unused
  1897.     NumberOfSymbols             00 00 00 00 ; unused
  1898.     SizeOfOptionalHeader        e0 00       ; constant
  1899.     Characteristics             02 01       ; executable on 32-bit-machine
  1900.  
  1901. optional header, starting at 0x58:
  1902.     Magic                       0b 01       ; constant
  1903.     MajorLinkerVersion          00          ; I'm version 0.0 :-)
  1904.     MinorLinkerVersion          00          ;
  1905.     SizeOfCode                  20 00 00 00 ; 32 bytes of code
  1906.     SizeOfInitializedData       a0 00 00 00 ; data section size
  1907.     SizeOfUninitializedData     00 00 00 00 ; we don't have a BSS
  1908.     AddressOfEntryPoint         a0 01 00 00 ; beginning of code section
  1909.     BaseOfCode                  a0 01 00 00 ; RVA to code section
  1910.     BaseOfData                  c0 01 00 00 ; RVA to data section
  1911.     ImageBase                   00 00 10 00 ; 1 MB, chosen arbitrarily
  1912.     SectionAlignment            20 00 00 00 ; 32-bytes-alignment
  1913.     FileAlignment               20 00 00 00 ; 32-bytes-alignment
  1914.     MajorOperatingSystemVersion  04 00      ; NT 4.0
  1915.     MinorOperatingSystemVersion  00 00      ;
  1916.     MajorImageVersion           00 00       ; version 0.0
  1917.     MinorImageVersion           00 00       ;
  1918.     MajorSubsystemVersion       04 00       ; Win32 4.0
  1919.     MinorSubsystemVersion       00 00       ;
  1920.     Win32VersionValue           00 00 00 00 ; unused?
  1921.     SizeOfImage                 c0 00 00 00 ; sum of all section sizes
  1922.     SizeOfHeaders               a0 01 00 00 ; offset to 1st section
  1923.     CheckSum                    00 00 00 00 ; not used for non-drivers
  1924.     Subsystem                   03 00       ; Win32 console
  1925.     DllCharacteristics          00 00       ; unused (not a DLL)
  1926.     SizeOfStackReserve          00 00 10 00 ; 1 MB stack
  1927.     SizeOfStackCommit           00 10 00 00 ; 4 KB to start with
  1928.     SizeOfHeapReserve           00 00 10 00 ; 1 MB heap
  1929.     SizeOfHeapCommit            00 10 00 00 ; 4 KB to start with
  1930.     LoaderFlags                 00 00 00 00 ; unknown
  1931.     NumberOfRvaAndSizes         10 00 00 00 ; constant
  1932.  
  1933. data directories, starting at 0xb8:
  1934.     Address        Size
  1935.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_EXPORT (0)
  1936.     e0 01 00 00    6f 00 00 00         ; IMAGE_DIRECTORY_ENTRY_IMPORT (1)
  1937.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_RESOURCE (2)
  1938.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)
  1939.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_SECURITY (4)
  1940.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_BASERELOC (5)
  1941.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_DEBUG (6)
  1942.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)
  1943.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)
  1944.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_TLS (9)
  1945.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)
  1946.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)
  1947.     00 00 00 00    00 00 00 00         ; IMAGE_DIRECTORY_ENTRY_IAT (12)
  1948.     00 00 00 00    00 00 00 00         ; 13
  1949.     00 00 00 00    00 00 00 00         ; 14
  1950.     00 00 00 00    00 00 00 00         ; 15
  1951.  
  1952. section header (code), starting at 0x138:
  1953.     Name            2e 63 6f 64 65 00 00 00     ; ".code"
  1954.     VirtualSize         00 00 00 00             ; unused
  1955.     VirtualAddress      a0 01 00 00             ; RVA to code section
  1956.     SizeOfRawData       20 00 00 00             ; size of code
  1957.     PointerToRawData    a0 01 00 00             ; file offset to code section
  1958.     PointerToRelocations 00 00 00 00            ; unused
  1959.     PointerToLinenumbers 00 00 00 00            ; unused
  1960.     NumberOfRelocations  00 00                  ; unused
  1961.     NumberOfLinenumbers  00 00                  ; unused
  1962.     Characteristics     20 00 00 60             ; code, executable, readable
  1963.  
  1964. section header (data), starting at 0x160:
  1965.     Name            2e 64 61 74 61 00 00 00     ; ".data"
  1966.     VirtualSize         00 00 00 00             ; unused
  1967.     VirtualAddress      c0 01 00 00             ; RVA to data section
  1968.     SizeOfRawData       a0 00 00 00             ; size of data section
  1969.     PointerToRawData    c0 01 00 00             ; file offset to data section
  1970.     PointerToRelocations 00 00 00 00            ; unused
  1971.     PointerToLinenumbers 00 00 00 00            ; unused
  1972.     NumberOfRelocations  00 00                  ; unused
  1973.     NumberOfLinenumbers  00 00                  ; unused
  1974.     Characteristics     40 00 00 c0             ; initialized, readable, writeable
  1975.  
  1976. (padding)
  1977.     00 00 00 00 00 00       ; padding
  1978.     00 00 00 00 00 00
  1979.     00 00 00 00 00 00
  1980.     00 00 00 00 00 00
  1981.  
  1982. code section, starting at 0x1a0:
  1983.     6A 00                    ; push      0x00000000
  1984.     68 d0 01 10 00           ; push      offset _written
  1985.     6A 0D                    ; push      0x0000000d
  1986.     68 c0 01 10 00           ; push      offset hello_string
  1987.     6A F5                    ; push      0xfffffff5
  1988.     2E FF 15 28 02 10 00     ; call      dword ptr cs:__imp__GetStdHandle@4
  1989.     50                       ; push      eax
  1990.     2E FF 15 24 02 10 00     ; call      dword ptr cs:__imp__WriteConsoleA@20
  1991.     C3                       ; ret       
  1992.  
  1993. data section, beginning at 0x1c0:
  1994.     68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A  ; "hello, world\n"
  1995.     00 00 00                                ; padding to align _written
  1996.     00 00 00 00                             ; _written
  1997. padding:
  1998.     00 00 00 00 00 00 00 00 00 00 00 00     ; padding
  1999. IMAGE_IMPORT_DESCRIPTOR, starting at 0x1e0:
  2000.     OriginalFirstThunk      18 02 00 00     ; RVA to orig. 1st thunk
  2001.     TimeDateStamp           00 00 00 00     ; unbound
  2002.     ForwarderChain          ff ff ff ff     ; no forwarders
  2003.     Name                    08 02 00 00     ; RVA to DLL name
  2004.     FirstThunk              24 02 00 00     ; RVA to 1st thunk
  2005. terminator (0x1f4):
  2006.     OriginalFirstThunk      00 00 00 00     ; terminator
  2007.     TimeDateStamp           00 00 00 00     ;
  2008.     ForwarderChain          00 00 00 00     ;
  2009.     Name                    00 00 00 00     ;
  2010.     FirstThunk              00 00 00 00     ;
  2011. The DLL name, at 0x208:
  2012.     6b 65 72 6e 65 6c 33 32 2e 64 6c 6c 00  ; "kernel32.dll"
  2013.     00 00 00                                ; padding to 32-bit-boundary
  2014. original first thunk, starting at 0x218:
  2015.     AddressOfData   30 02 00 00             ; RVA to function name "WriteConsoleA"
  2016.     AddressOfData   40 02 00 00             ; RVA to function name "GetStdHandle"
  2017.                     00 00 00 00             ; terminator
  2018. first thunk, starting at 0x224:
  2019.     AddressOfData   30 02 00 00             ; RVA to function name "WriteConsoleA"
  2020.     AddressOfData   40 02 00 00             ; RVA to function name "GetStdHandle"
  2021.                     00 00 00 00             ; terminator
  2022. IMAGE_IMPORT_BY_NAME, at byte 0x230:
  2023.     01 00                                      ; ordinal, need not be correct
  2024.     57 72 69 74 65 43 6f 6e 73 6f 6c 65 41 00  ; "WriteConsoleA"
  2025. IMAGE_IMPORT_BY_NAME, at byte 0x240:
  2026.     02 00                                      ; ordinal, need not be correct
  2027.     47 65 74 53 74 64 48 61 6e 64 6c 65 00     ; "GetStdHandle"
  2028. (padding)
  2029.     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; padding
  2030.     00
  2031. First unused byte: 0x260
  2032.  
  2033. --------------
  2034.  
  2035. Alas, this works on NT but didn't on windows 95. windows95 can't run
  2036. applications with a section alignment of 32 bytes, it needs an
  2037. alignment of 4 KB and, apparently, a file alignment of 512 bytes. So for
  2038. windows95 you'll have to insert a large number of 0-bytes (for padding)
  2039. and adjust the RVAs. Thanks go to D. Binette for testing on windows95.
  2040.  
  2041.  
  2042.         -- end of text --
  2043.  
  2044.