for crafting Win95/WinXP .exe files, with form@fix

This file is valuable for crafting [32bit] Windows .exe files, with form@fix. First include this, followed by a mnemonic file, or a few -- like fix80x86.htm as well as 80386.htm.

//	\F "fixWin.htm"    \\this file
//	\F "fix80x86.htm"  \\the common instructions for all intel 80x86
//	\F "fix80386.htm"  \\new, or redefined for 80386

For referring to functions from some .dll (dynamic link library), see

//subset of Windows libraries needed for the specific application
//	\F "winLibsH.htm	

//for referring to Windows structures, such as WNDCLASS or MSG
//	\F "windef.htm"	

That "winLibsH.htm" may bind the target imports/exports, statically. Or, alternatively, list the critical info, for looping on, to dynamically-bind. The good thing in the latter case is that, one may tolerate when some non-critical function is missing. The good thing about static is that, after start, we know that all of the presumed functions are there. Static is not likely to face in-memory corruption of targeting, but less flexible, too.

If the files are not in the folder where form@fix is running, specify the target folder, too. For example,

//	\F "c:\Program files\form@fix\fixWin.htm"	\\this file
//	\F "c:\Program files\form@fix\fix80x86.htm"
//	\F "c:\Program files\form@fix\fix80386.htm"
//	\F "c:\Program files\form@fix\winLibsH.htm"
//	\F "c:\Program files\form@fix\windef.htm"



The Win32 .exe files almost always presume the four-byte int format. But if your form@fix processor is not the fixWin, the default int width may be something else. For fixDX, that is 2-bytes. Therefore, what we would like to have first, is the certainty of what we presume. Set the format-width, as well as the remz-offset, manually.

\r rOffset0	\r Win32


//To go forward more than the width of ARZ? No way.
//	Therefore, locating at the byte following ARZ.
\a+ 0xFFFFFFF	\r widthOfARZ


//From there, walk back 9 bytes,
//	because the platform-info is 9-bytes wide. 
\a- 9


//for Win32 .exe files, default format is WORD,
\r1 defaultWidth	\a+1 1 4


\r4 remzOffset	\a+4 4 0x400e00
			\a+4 4 0	\\filling

If the offset for running the Win32 .exe is 0x401000, the virtual offset. Subtract what PE fileinfo takes. If 0x200, then remainder is 0x400e00.




For scratch work, not written to the .exe file but useful toward that, we may allocate the piece of memory beyond a point. Set that at a point beyond the length of your final .exe, for the two portions not to overlap. I like to set that at 0x5000 (that is, 20480 bytes). Modify this (to less, or more), depending on the specific application.

\a 0x5000	\\toward  form@fix@RunTime_Max




format specifying

For byte data-or-remz,

\r =
\r =1	\\the platform =1
\r attr=	\\byte-width, although flexible for the future
\\r+ is 0    \a+1 4
\\width is 1 \a+1 1   1   \a+1 3

For padding from byte-width to int-width

\r fiz	\*= 3 0    0    0    \\fill with zeroes, if positive
\r -fiz	\*= 3 0xFF 0xFF 0xFF \\fill with 0xFF to sign-extend, if negative 

For word data-or-remz,

\r =2	\\the platform is =2
\\r+ is 0		\a+1 4
\\width is 2	\*= 2 0 0 0

For dword data-or-remz,

\r =.	\\the default int-width is this.
\r =4	\\the platform is =4
\\r+ is 0    \a+1 4
\\width is 4 \*= 4 0 0 0

as was

In case, we would refer to the int-width of the fix.exe that is processing this file,

//ARZ.Zero, the [platform.r+]-free offset.
//	Purely, the 0th byte of ARZ, that is.

\r RZ
\\r+ is 0    \a+1 4
\\width is 0 \a+1 4

This default format is useful for a remz (or, remz-list) like for frag. Good, because otherwise frag would have to acept only a single width for all platforms. For coding in fixDX, that is a waste to accommodate the double-width of Win32. Not to mention that, for a future support of Win64, the thing would get totally problematic.

for Win32

For output in the RVA format,

\r =RVA
\\r+ is 		\*=4 0xe00
\\width is 4	\*= 4 0 0 0
\r WX  \\for a VA (RVA+ImageBase) of Win
\\The default r+ for a WinExe is this.
\\However, this page is for a format-study.
\\Therefore, every r+ is explicit.
\\r+ is the ImageBase	\*=4 0x400e00
\\width is 4		\*= 4 0 0 0
\r WW  \\for pointer@abs, add the ImageBase, only.
\\r+ is the ImageBase	\*=4 0x400000
\\width is 4		\*= 4 0 0 0
\r WinLibsH	\\from rX w.r.t. the offset 0
\\r+ is 		\*=4  0	\\== 0 - f@f@r
\\width is 1	\*=4  1



A few run-time only conveniences. Although referrable while fixing the .exe, do not refer to such a run-time-only remz, from within your .exe, because that would be what is known as dangling-pointer problem.

\r [?]	\'?'	\*= 0	\\frag for not returning a result
\r {/}	\*=4 0	\\empty set

f0 is only a fancier name, to fill with zeroes, at byte-width, e.g: with \a+f0 20 to fill with 20 zeroes. i.e: "1" is the fill-width, not the filler-value. Filler is zero, if not explicitly specified.

\r f0	\*=4 1



A few for conveniently referring to a macro type. Macro-flag is 0x80. The letter 'F' plus 0x80 is 0xC6.

\r mid80.macro
	\a 0xD0	\r Pm	\\Petri transition
	\a 0xD5	\r Um	\\UCLA control-node
	\a 0xC6	\r Fm	\\Nutt F-transition
	\a 0xCA	\r Jm	\\Nutt J-transition
	\a 0xD4	\r Tm	\\Nutt T-transition
	\a 0xD8	\r Xm	\\Nutt X-transition
	\a 0xD9	\r Ym	\\Nutt Y-transition
	.\a 0xCB	\r Km
	\a 0xC4	\r Dm	\\Danthine mod for  X-transition
	\a 0xE2	\r bm	\\binary loc
	\a 0xF0	\r pm \\Petri loc
\a mid80.macro
\r- mid80.macro



\r width(formal)
	\*RZ 0 0 0 0 0 0 0 0 0 0
\* width(formal)\-f
\a width(formal)
\a+ 1
\*= 0 0 0	\\pad width(formal) to four-bytes

For a frozen@mid80 style fragging, for form@fix, we may think a single-transition "net." This T-transition is running the frag (predicate) that is to follow immediately after the "\F@ @FragFun" statement.

\r @FragFun
	

\'\\r .fm'

	//allocating the formal-list width, for returning-to afterward
	\'\\a+ width(formal)'

	\'\\r b1\\\'b\'\\*= 1\\*attr= 0'
	\'\\r b2\\\'b\'\\*= 2\\*attr= 0'


	\'\\r .L'
		\'\\*RZ b1 b2 0'


	\'\\r .M0'
	 	\'\\*RZ b1\\*= 1'
		\'\\*RZ 0'


	\'\\r a1'
		\'\\\'T\'\\*= 1'	\\T1
		\'\\*RZ b1 b2'
		\'\\*RZ {/}'	\\ immediately finishing
		\'\\r .t\\*RZ 0'	\\ activity/transition procedure

	\'\\r .A'
		\'\\*RZ a1 0'


	\'\\r .z'
	\'\\a .fm'
	\'\\*RZ .A {/} {/} .M0 .L .L {/} {/}' \\formal net.
	\'\\a .t\\*RZ .z'
	\'\\a .z'


\'\\r/ .fm'
\'\\r- .fm'
\*= 0



To tell Windows, where to start running the .exe, the next frame is handy. This frame is in a null-terminated array. Notice that, the a \\ within a quoted range, is not for commentary. The quote will replace that. i.e: They are not double.

To start a function at a 4-bytes boundary, is a well-known optimization. Therefore, even when not otherwise needed, the DWORD-residence is wanted.

\r fixStArt.htm
   \'\\a/f0 4'      \\the next double-word boundary 
   \'\\r! z'
   \'\\a CodeOffsetRVA  \\*=RVA z'
   \'\\a EntryPointRVA  \\*=RVA z'
   \'\\a z'
   \'\0'
//Frame this, where wanted, with a	\F@ fixStArt.htm



For finishing a Win32 .exe file, we pad the memory-image until the next multiple of file-alignment.

\r fixFinish	\\unnecessary (for all win32? win95 to Vista?)
\r win@end.htm
   \'\\a/f0 AlignFile2'
   \'\\r @End'
 
   \'\\a- @FirstAfter'
   \'\\a/ SectionAlignment'
   \'\\a+ @FirstAfter'
   \'\\r! z'
   .\'  \\a RAM_VirtualAddress  \\*=RVA z'
   \'\\a @End'
   \'\0'



\r form@fix@RunTime_Max  \\to keep in mind, the high-ARZ remz



\a 0

\'MZ'         \\ MSDOS signature at file start.
\*=2    512 \\ Bytes on last page of file
\*=2     16 \\ Pages in file (each 512 bytes)
\*=2      0 \\ Relocations
\*=2      4 \\ Size of header in paragraphs 
\*=2      0 \\ Minimum-extra-needed /16
\*=2 0xffff \\ Maximum-extra-needed /16
\*=2      0 \\ Initial (relative) SS
\*=2  0x100 \\ Initial eSP
\*=2      0 \\ Checksum
\*=2      0 \\ Initial IP value
\*=2      0 \\ Initial (relative) CS
\*=2   0x40 \\ File address of relocation table
\*=2      0 \\ Overlay number
\a+f0 8   0 \\ Reserved words
\*=2      0 \\ OEM identifier (for e_oeminfo)
\*=2      0 \\ OEM information; e_oemid specific
\a+f0 20  0 \\ Reserved
\r PortExe  \*=4 0x80\\ point at PE header

The file-address-of-relocation-table is critical for Win95 to accept this executable as a Windoes-executable. Although the .exe is run as a Windows executable, the Win95 Quickview, does list it as if an MS-DOS executable. That is especially strange, as here, and as in pedump.exe, the value 0x40 does not really point to a table, at all. i.e: That is not really a needed information for the loader. A NULL (zero) value would suffice.


DOS Stub Code_n_Data

After the DOS header, comes the DOS-based application's code/data/etc.

\\@64: Let DS=CS
    \*=  0xe 0x1f                        

//@66: Write azMess to stdout
//   through DOS-int21h (AH=0x40)
    \*= 0xb4 0x40  0xbb 1 0
    \*= 0xb9 19 0  0xba 19 0  0xcd 0x21

\\@79: Quit to DOS w/ DOS-int21h(AH=0x4c).
    \*=  0xb4 0x4c    0xcd 0x21

\\@83: azMessage (strlen=17+2=19)
    \'This Ain\'t 4 DOS!\r\n\0'



Portable Executable (PE) File Header

In the listings that follow, not every field is identified with a remz. In many cases, only there is a commentary. To have a remz, with \r is to refer to that offset later, as a variable or constant. It indicates that the variable/setting that follows, at that offset, is meaningfully modifiable, based on what the program content/configuration is. The other "variable"s are rarely modified, if at all.

Two representative cases of label-omissions are the Date (TimeStamp) and the SizeOfOptionalHeader fields in the PE file header. The former does not matter. It is for your own reference, if you care. The latter, at least for an exe file, is always 224. Hence, even the name "optional" is out of context.

As a result, I omitted labels for them, to take attention to what is, in deed, a variable.

\a 0x80

\\PE_signature           \'PE' \a+f0 2
\\Intel i386             \*=2 0x14c
\r NumberOfSections      \*=2 2 \\rdata&code, & runtime  3 if there were .rsrc
\\Date=Mar 14,2006 :-)  \*=4 0x03142006
\r PointerToSymbolTable  \*=4 0 \\NULL  Not 4 .exe
\r NumberOfSymbols       \*=4 0 \\NULL  Not 4 .exe
\\SizeOfOptionalHeader.  \*=2 224         

\r ExeCharacteristics    \*=2 0x30f

The next is informative. A few flag definitions (from Microsoft documentation) ...

\\ IMAGE_FILE_EXECUTABLE_IMAGE             0x0002
\\    Image only. Indicates that the image file is
\\    valid and can be run. If this flag is not set,
\\    it generally indicates a linker error.

\\ IMAGE_FILE_LINE_NUMS_STRIPPED           0x0004
\\    COFF line numbers have been removed.

\\ IMAGE_FILE_LOCAL_SYMS_STRIPPED          0x0008
\\    COFF symbol table entries for local symbols
\\    have been removed.

\\ IMAGE_FILE_BYTES_REVERSED_LO            0x0080
\\    Little endian: LSB precedes MSB in memory.

\\ IMAGE_FILE_32BIT_MACHINE                0x0100
\\    Machine based on 32-bit-word architecture.

\\ IMAGE_FILE_DEBUG_STRIPPED               0x0200
\\    Debugging information removed from image file.

\\The DLL'ness is not true for the current one.
\\The next flag is handy here for info & switching.
\\  IMAGE_FILE_DLL                          0x2000
\\    The image file is a dynamic-link library (DLL).
\\    Such files are considered executable files for
\\    almost all purposes, although they cannot be
\\    directly run.



Portable Executable (PE) "Optional" Header

Here, for Windows95-exe crafting,

\\ PE32 "magic" constant                       \*=2 0x10b
\\ MajorLinkerVersion. FYI                     \*=  5
\\ MinorLinkerVersion. FYI                     \*=  5
\r SizeOfCode                           \*=4 0x2000 \\0x3000 for Media-tangle
\r SizeOfInit                           \*=4 0x2000 \\0x3000 if there were .rsrc
\r SizeOfUnInit    \\@RAM               \*=4 0x1000 \\0xAF000 for Media-tangle

\r EntryPointRVA   \\ .exe start @      \*=4 0x1000
\r CodeOffsetRVA   \\ code section      \*=4 0x1000
\r DataOffsetRVA   \\ initialized-data  \*=4 0x1000

\r ImageBase       \\ for Win95 .exe    \*=4 0x400000
\r SectionAlignment\\at multiples of    \*=4 0x1000
\r AlignFile2      \\at multiples of    \*=4 0x200
\\ MajorNo of Required Operating System        \*=2 4
\\ MinorNo of Required Operating System        \*=2 0
\\ MajorImageVersion: version 0.0              \*=2 0 \\ 5
\\ MinorImageVersion: version 0.0              \*=2 0
\\ MajorSubsystemVersion: (Win32 4.0)          \*=2 4
\\ MinorSubsystemVersion: (Win32 4.0)          \*=2 0
\\ Reserved                                    \*=4 0
\r SizeOfImage     \\memory-aligned     \*=4 0x4000 \\0xb3000 for Media-tangle
\r @FirstAfter
\r SizeOfHeaders   \\file-rounded2      \*=4 0 \\0x200
\\ CheckSum (for drivers)                      \*=4 0
\r WinSubsystem \\for CUI(console) ==   \*=2 3 \\2 (GUI) for Media-tangle
\r DllCharacter \\ Not 4 .exe           \*=2 0
\r StackReserveSize                     \*=4 0x100000
\\ SizeOfStackCommit (at start)                \*=4 0x1000
\\ SizeOfHeapReserve                           \*=4 0x100000
\\ SizeOfHeapCommit (at start)                 \*=4 0x1000
\\ LoaderFlags: Obsolete.                      \*=4 0

PE data directories

\\NumberOfRvaAndSizes. Always 16.    \*=4 16
\\pad 16*8 zeroes  \r! z   \a+f0 128 \a z
                    Address (RVA)   Size
                    -------------  --------
\r ExportDir        \a+ 8
\r ImportDir        \a+ 8
\r ResourceDir      \a+ 8
\r ExceptionDir     \a+ 8
\r SecurityDir      \a+ 8
\r BaseRelocDir     \a+ 8
\r DebugDir         \a+ 8
\r CopyrightDir     \a+ 8
\r GlobalPtrDir     \a+ 8
\r TLSDir           \a+ 8
\r LoadConfigDir    \a+ 8
\r BoundImportDir   \a+ 8
\r IATDir           \a+ 8
\\Three unused directories \a+ 24

the section headers

Notice that, for each section,

The virtual address of a section is (SectionOffsetInFile/AlignFile2)*MemAlignment.

\\"rdcode" section: ReadableData&Code
\\r RDCode_Name               \'rdcode' \a+1 2 \\6+2=8
\r RDCode_VirtualSize  \@4 SizeOfInit \\Unused?
\\r RDCode_VirtualAddress     \@4 DataOffsetRVA
\r RDCode_SizeOfRawData\*=4 0x2000
\\r RDCode_PtrToRawData       \*=4 0x200
\\r RDCode_PtrToRelocs        \*=4 0
\\PtrToLineNums, for .OBJ     \*=4 0
\\r RDCode_NumberOfRelocs     \*=2 0
\\NumOfLineNums, for .OBJ     \*=2 0
\\r RDCode_Flags              \*=4 0x60000040
  \\ 0x00000040 container for initialized data
  \\ 0x20000000 can be executed as code
  \\ 0x40000000 readable
..
..\\".rsrc" section:  RAM/Run-time-only data
..\\Does not exist in file. FlushZero at load time.
..\\r rsrc_Name              \'.rsrc' \a+1 3
..\\r rsrc_AllocMemory\*=4 0x1000
..\r rsrc_VirtualAddress     \*=4 0x3000
..\r rsrc_SizeOfRawData      \*=4 0x400
..\r rsrc_PtrToRawData       \*=4 0x1600
..\r rsrc_PtrToRelocs        \*=4 0
..\\PtrToLineNums, for .OBJ \*=4 0
..\r rsrc_NumberOfRelocs     \*=2 0
..\\NumOfLineNums, for .OBJ \*=2 0
..\r rsrc_Characteristics    \*=4 0x40000040
..  \\ 0x00000040 container for initialized data
..  \\ 0x40000000 readable


..\r! z  \a form@fix@RunTime_Max
..\r RSRC	\\RVA  w.r.t. the RSRC section
..\\r+ is 0    \*=4 0x1a00	\\rsrc_VirtualAddress - rsrc_PtrToRawData
..\\width is 4 \@1 Four \@1 Zero
..\r! form@fix@RunTime_Max    \a z
\\"@RAM" section:  RAM/Run-time-only data
\\Does not exist in file. FlusZero at load time.
\\r RAM_Name                \'@RAM' \*=4 0
\r RAM_AllocMemory   \@4 SizeOfUnInit
\r RAM_VirtualAddress\*=4 0x3000	\\0x4000 if there were .rsrc
\\r RAM_SizeOfRawData       \*=4 0x200	\\WinXP joke?!? (Read the next note.)
\\r RAM_PtrToRawData        \*=4 0
\\r RAM_PtrToRelocs         \*=4 0
\\PtrToLineNums, for .OBJ   \*=4 0
\\r RAM_NumberOfRelocs      \*=2 0
\\NumOfLineNums, for .OBJ   \*=2 0
\\r RAM_Characteristics     \*=4 0xc0000080
  \\ 0x00000080 container for uninitialized (all-zeroes) data
  \\ 0x40000000 readable
  \\ 0x80000000 writeable


\r! z  \a form@fix@RunTime_Max
\r @RAM	\\for a  VA (not RVA)  @ the @RAM section  (ImageBase+@RAM)
\\r+ is 0    \*=4 0x403000	\\0x404000 if there were .rsrc
\\width is 4 \a+1 1   4   \_ fiz
\r! form@fix@RunTime_Max    \a z

WinXP does not accept RAM_SizeOfRawData==0x1000. Informed me that, this was "not a valid Win32" although Win95 was happily running. For a file-based section, the file-alignment size is fitting. That is no-need here, though, because the @RAM section is only in RAM, not recorded.

\a/f0 AlignFile2
\r! z   \a @FirstAfter  \*=4 z  \a z

\r! z   \a DataOffsetRVA  \*=RVA z   \a z

\r? first@	\a first@
..\r? @first	\F@ @first


Forum: . . (Fair Menu . . . . . Fault Report? . . . . . Remedy for your case . . . . . Noticed Plagiarism?)

Referring#: 0.1
following the good old style of mid80.net/formFix/fixDX.htm, formerly http://www.geocities.com/ferzenr/fixDX.htm
Last-Revised (text) on Aug. 18, 2008
Written by: Ahmed Ferzan/Ferzen R Midyat-Zila (or, Earth)
Copyright (c) 2003, 2005, 2008 Ferzan Midyat. All rights reserved.