Recent

Author Topic: Windows 32-Bit Exec self made - how ?  (Read 4920 times)

paulee32

  • New Member
  • *
  • Posts: 18
Windows 32-Bit Exec self made - how ?
« on: September 19, 2021, 04:32:27 pm »
Hello,
I would like to write a windows 10 32 bit application on the fly by my project
application.
therefore I have takle out some assember stuff to pascal.
but I fail.
so I hope, you can help me.
the question is: how can I create a small windows.exe application without
assembler and linker - only on fly by the pascal application ?
thanks in advance, paule32

here is the original code https://dpaste.com/C8LDGNU93#line-280
it used yasm.exe and display a message box under windows.

Code: Pascal  [Select][+][-]
  1. ...
  2. const
  3.     x: array[1..4] of Byte = (
  4.     $90, $90, $90, $c3  // nop, nop, nop, ret
  5.     );
  6. ...
  7. var
  8.   streamSrcCode : string;
  9. ...
  10. EmitCode(x, 4);
  11. ...
  12.  
  13. unit x86code;
  14.  
  15. interface
  16. uses
  17.   Windows, Classes, SysUtils, Dialogs;
  18.  
  19.   procedure WritePEHeader;
  20.   procedure EmitCode(X: array of Byte; const Bytes: TSize);
  21. implementation
  22. uses
  23.   scanner;
  24.  
  25. const
  26.   // MZ header (start of the file)
  27.   DOSStubHeader: Array[1..64] of Byte = (
  28.   $0e, $1f, $ba, $0e, $00, $b4, $09, $cd, $21, $b8, $01, $4c, $cd, $21, $54, $68,
  29.   $69, $73, $20, $70, $72, $6f, $67, $72, $61, $6d, $20, $63, $61, $6e, $6e, $6f,
  30.   $74, $20, $62, $65, $20, $72, $75, $6e, $20, $69, $6e, $20, $44, $4f, $53, $20,
  31.   $6d, $6f, $64, $65, $2e, $0d, $0a, $24, $00, $00, $00, $00, $00, $00, $00, $00
  32.   );
  33.  
  34.   // PE header:
  35.   PEHeader: Array[0..3] of Byte = ($50, $45, $00, $00);
  36. type
  37.   TImageDosHeader = record
  38.     e_magic   : WORD;                  // $0000
  39.     e_cblp    : WORD;                  // $0002
  40.     e_cp      : WORD;                  // $0004
  41.     e_creloc  : WORD;                  // $0006
  42.     e_cparhdr : WORD;                  // $0008
  43.     e_minalloc: WORD;                  // $000a
  44.     e_maxalloc: WORD;                  // $000c
  45.     e_ss      : WORD;                  // $000e
  46.     e_sp      : WORD;                  // $0010
  47.     e_csum    : WORD;                  // $0012
  48.     e_ip      : DWORD;                 // $0014
  49.     e_reloc   : WORD;                  // $0018
  50.     e_ovno    : WORD;                  // $001a
  51.  
  52.     // new executable
  53.     e_res     : Array[1..4]  of Byte;  // $001c
  54.     e_oemid   : WORD;                  // $0020
  55.     e_res2    : Array[1..26] of Byte;  // $0022
  56.     e_start   : DWORD;                 // $003c
  57.   end;
  58. var
  59.   ImageDosHeader: TImageDosHeader;
  60. type
  61.   TImageNtHeader = record
  62.     signature: Array [1..4] of Byte;
  63.   end;
  64. var
  65.   ImageNTHeader: TImageNTHeader;
  66. type
  67.   // file image header:
  68.   TImageFileHeader = record
  69.     machine             : WORD ;
  70.     numbersOfSections   : WORD ;
  71.     timeDateStamp       : DWORD;
  72.     pointerToSymbolTable: DWORD;
  73.     numberOfSymbols     : DWORD;
  74.     sizeOfOptionalHdr   : WORD ;
  75.     characteristics     : WORD ;
  76.   end;
  77.  
  78. var
  79.   ImageFileHeader: TImageFileHeader;
  80.  
  81. const
  82.   NUMBEROFSECTIONS = 3; // 1x .text
  83.                         // 1x .rdata
  84.                         // 1x .data
  85.   BIN_IMAGEBASE    = $400000;
  86.   BIN_SECTIONALIGN = $1000;
  87.   BIN_FILEALIGN    = $200;
  88. type
  89.   TImageSectionHeader = record
  90.     name                : string[8];
  91.     virtualSize         : DWORD;
  92.     virtualAddress      : DWORD;
  93.     sizeOfRawData       : DWORD;
  94.     pointerToRawData    : DWORD;
  95.     pointerToRelocations: DWORD;
  96.     pointerToLineNumbers: DWORD;
  97.     numberOfRelocations : WORD;
  98.     numberOfLineNumbers : WORD;
  99.     characteristics     : DWORD;
  100.   end;
  101. var
  102.   ImageSectionHeader: Array [1..NUMBEROFSECTIONS] of TImageSectionHeader = (
  103.     (name: '.text' ; virtualSize: 1 * BIN_SECTIONALIGN; virtualAddress: 1 * BIN_SECTIONALIGN; sizeofRawData: 1 * BIN_FILEALIGN; pointerToRawData: 1 * BIN_FILEALIGN; characteristics: IMAGE_SCN_CNT_CODE             or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_EXECUTE),
  104.     (name: '.rdata'; virtualSize: 1 * BIN_SECTIONALIGN; virtualAddress: 2 * BIN_SECTIONALIGN; sizeofRawData: 1 * BIN_FILEALIGN; pointerToRawData: 2 * BIN_FILEALIGN; characteristics: IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_READ                         ),
  105.     (name: '.data' ; virtualSize: 1 * BIN_SECTIONALIGN; virtualAddress: 3 * BIN_SECTIONALIGN; sizeofRawData: 1 * BIN_FILEALIGN; pointerToRawData: 3 * BIN_FILEALIGN; characteristics: IMAGE_SCN_CNT_INITIALIZED_DATA or IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_WRITE  )
  106.   );
  107. type
  108.   TImageOptionalHeader32 = record
  109.     magic                      : WORD ;
  110.     majorLinkerVersion         : BYTE ;
  111.     minorLinkerVersion         : BYTE ;
  112.     sizeOfCode                 : DWORD;
  113.     sizeOfInitializedData      : DWORD;
  114.     sizeOfUninitializedData    : DWORD;
  115.     addressOfEntryPoint        : DWORD;
  116.     baseOfCode                 : DWORD;
  117.     baseOfData                 : DWORD;
  118.     imageBase                  : DWORD;
  119.     sectionAlignment           : DWORD;
  120.     fileAlignment              : DWORD;
  121.     majorOperatingSystemVersion: WORD ;
  122.     minorOperatongSystemVersion: WORD ;
  123.     majorImageVersion          : WORD ;
  124.     minorImageVersion          : WORD ;
  125.     majorSubsystemVersion      : WORD ;
  126.     minorSubsystemVersion      : WORD ;
  127.     win32VersionValue          : DWORD;
  128.     sizeOfImage                : DWORD;
  129.     sizeOfHeaders              : DWORD;
  130.     checkSum                   : DWORD;
  131.     subsystem                  : WORD ;
  132.     dllCharacteristics         : WORD ;
  133.     sizeOfStackReserve         : DWORD;
  134.     sizeOfStackCommit          : DWORD;
  135.     sizeOfHeapReserve          : DWORD;
  136.     sizeOfHeapCommit           : DWORD;
  137.     loaderFlags                : DWORD;
  138.     numberOfRVAandSizes        : DWORD;
  139.     dataDirectory              : BYTE ;
  140.   end;
  141. var
  142.   ImageOptionalHeader32: TImageOptionalHeader32;
  143. type
  144.   TImageDataDirectory16 = record
  145.     exportVA        : DWORD;
  146.     exportSize      : DWORD;
  147.     importsVA       : DWORD;
  148.     importsSize     : DWORD;
  149.     resourceVA      : DWORD;
  150.     resourceSize    : DWORD;
  151.     exception       : DWORD;
  152.     security        : DWORD;
  153.     fixupsVA        : DWORD;
  154.     fixupsSize      : DWORD;
  155.     debugVA         : DWORD;
  156.     debugSize       : DWORD;
  157.     description1    : DWORD;
  158.     descroption2    : DWORD;
  159.     mips            : DWORD;
  160.     tlsVA           : DWORD;
  161.     tlsSize         : DWORD;
  162.     load            : DWORD;
  163.     boundImportsVA  : DWORD;
  164.     boundImportsSize: DWORD;
  165.     IATVA           : DWORD;
  166.     IATSize         : DWORD;
  167.     delayImportsVA  : DWORD;
  168.     delayImportsSize: DWORD;
  169.     COM             : DWORD;
  170.     reserved1       : DWORD;
  171.     reserved2       : DWORD;
  172.   end;
  173. var
  174.   ImageDataDirectory16: TImageDataDirectory16;
  175. const
  176.   SIZEOFOPTIONALHEADER =
  177.       sizeof(TImageOptionalHeader32) +
  178.       sizeof(TImageDataDirectory16);
  179.  
  180.   IMAGE_FILE_MACHINE_I386       = $014c;
  181.   IMAGE_FILE_MACHINE_AMD64      = $8664;
  182.  
  183.   IMAGE_FILE_EXECUTABLE_IMAGE   = $2;
  184.   IMAGE_FILE_32BIT_MACHINE      = $0100;
  185.  
  186.   IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10b;
  187.   IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20b;
  188.  
  189.   IMAGE_SUBSYSTEM_WINDOWS_GUI   = 3;
  190.   IMAGE_SUBSYSTEM_WINDOWS_CUI   = 2;
  191. type
  192.   TImageImportDescriptor = record
  193.     originalFirstThunk: DWORD;
  194.     timeStamp         : DWORD;
  195.     forwarderChain    : DWORD;
  196.     name1             : DWORD;
  197.     firstThunk        : DWORD;
  198.   end;
  199.  
  200. // --------------------------------------------------------
  201. // transpile byte code to string "streamCode" ...
  202. // --------------------------------------------------------
  203. procedure EmitCode(X: array of byte; const Bytes: TSize);
  204. var
  205.   s: string;
  206. begin
  207.   SetString(s, PChar(@X), Bytes);
  208.   streamSrcCode := streamSrcCode + s;
  209. end;
  210.  
  211. // ----------------------------------------------------------
  212. // write Windows 10 32-Bit PE file image ...
  213. // ----------------------------------------------------------
  214. procedure WritePEHeader;
  215. var
  216.   stream: TStream;
  217.   p, len: Integer;
  218.   zero  : Array [1..BIN_FILEALIGN] of Byte;
  219.  
  220.   title  : string;
  221.   caption: string;
  222. begin
  223.   FillChar(ImageDosHeader       , sizeof(TImageDosHeader       ), 0);
  224.   FillChar(ImageNtHeader        , sizeof(TImageNtHeader        ), 0);
  225.   FillChar(ImageFileHeader      , sizeof(TImageFileHeader      ), 0);
  226.   FillChar(ImageOptionalHeader32, sizeof(TImageOptionalHeader32), 0);
  227.   FillChar(ImageDataDirectory16 , sizeof(TImageDataDirectory16 ), 0);
  228.  
  229.   FillChar(zero,BIN_FILEALIGN,0);
  230.  
  231.   // --------------------------------------------------------
  232.   // MZ DOS-stub header ...
  233.   // --------------------------------------------------------
  234.   with ImageDosHeader do begin
  235.     e_magic    := $5a4d; { MZ }
  236.     e_cblp     := $0090;
  237.     e_cp       := $03;
  238.     e_cparhdr  := $0004;
  239.     e_minalloc := $0000;
  240.     e_maxalloc := $ffff;
  241.     e_ss       := $0000;
  242.     e_sp       := $00b8;
  243.     e_reloc    := $0040;
  244.     e_start    := $0080;
  245.   end;
  246.  
  247.   // --------------------------------------------------------
  248.   // PE Windows 32-Bit header:
  249.   // --------------------------------------------------------
  250.   with ImageNtHeader do begin
  251.     signature[1] := Byte('P');
  252.     signature[2] := Byte('E');
  253.     signature[3] := $00;
  254.     signature[4] := $00;
  255.   end;
  256.  
  257.   with ImageFileHeader do begin
  258.     machine           := IMAGE_FILE_MACHINE_I386;
  259.     numbersOfSections := NUMBEROFSECTIONS;
  260.     sizeOfOptionalHdr := $f0;   //SIZEOFOPTIONALHEADER;
  261.     characteristics   := IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE;
  262.   end;
  263.  
  264.   with ImageOptionalHeader32 do begin
  265.     magic                 := IMAGE_NT_OPTIONAL_HDR32_MAGIC;
  266.     addressOfEntryPoint   := 480 + 13; // fixme
  267.     imageBase             := BIN_IMAGEBASE;
  268.     sectionAlignment      := BIN_SECTIONALIGN;
  269.     fileAlignment         := BIN_FILEALIGN;
  270.     majorSubsystemVersion := 4;
  271.     sizeOfImage           := 4 * BIN_SECTIONALIGN;  // 3 sections + header
  272.     sizeOfHeaders         := $400; //SIZEOFHEADERS;
  273.     Subsystem             := IMAGE_SUBSYSTEM_WINDOWS_GUI;
  274.     numberOfRvaAndSizes   := $10;
  275.   end;
  276.  
  277.   ImageDataDirectory16.importsVA := 16; // fixme
  278.  
  279.   // --------------------------------------------------------
  280.   // application 32-Bit x86 binary code:
  281.   // --------------------------------------------------------
  282.   if Length(streamSrcCode) > 0 then begin
  283.     try
  284.       stream := TFileStream.Create('a.out', fmCreate);
  285.     except
  286.       on e: Exception do begin
  287.         ShowMessage('can not open output file.');
  288.         exit;
  289.       end;
  290.     end;
  291.  
  292.     stream.WriteBuffer(ImageDosHeader       , sizeof(TImageDosHeader));
  293.     stream.WriteBuffer(DosStubHeader        , 64);
  294.     stream.WriteBuffer(ImageNtHeader        ,  4);
  295.     stream.WriteBuffer(ImageFileHeader      , sizeof(TImageFileHeader      ));
  296.     stream.WriteBuffer(ImageOptionalHeader32, sizeof(TImageOptionalHeader32));
  297.     stream.WriteBuffer(ImageDataDirectory16 , sizeof(TImageDataDirectory16 ));
  298.  
  299.     stream.WriteBuffer(ImageSectionHeader,sizeof(ImageSectionHeader));
  300.  
  301.     for p := 1 to 4 do
  302.     stream.WriteBuffer(streamSrcCode[p],1);
  303. //    Length(streamSrcCode));
  304.  
  305.     stream.WriteBuffer(zero,BIN_FILEALIGN);
  306.     stream.WriteBuffer(zero,BIN_FILEALIGN);
  307.  
  308.     // data section:
  309.     title   := 'simple PE executable.' + #$0;
  310.     caption := 'Hello World !' + #$0;
  311.  
  312.     len := 22; for p := 1 to len do stream.WriteBuffer(title  [p], 1);
  313.     len := 14; for p := 1 to len do stream.WriteBuffer(caption[p], 1);
  314.  
  315.     stream.WriteBuffer(zero,BIN_FILEALIGN);
  316.     stream.Free;
  317.  
  318.   end else begin
  319.     ShowMessage('warning: no application code.');
  320.   end;
  321.  
  322.   ShowMessage('file a.out written.');
  323. end;
  324.  
  325. end.
  326.  
  327.  

paulee32

  • New Member
  • *
  • Posts: 18
Re: Windows 32-Bit Exec self made - how ?
« Reply #1 on: September 20, 2021, 09:29:35 pm »
Hello,
I found a solution, the produced stream file does nothing at the moment, but
the stream is written correctly, to start, and end a win32 executable under
Windows 10 Pro. 64-Bit.
It has cost me some time, to check against the binary, but it works.
I working on, to load DLL functions, but later ...
Here is the working code, feel free to ask on.
Thank you for your patient.

Code: Pascal  [Select][+][-]
  1. // ----------------------------------------------------------
  2. // file:   x86code.pas
  3. // autor:  Jens Kallup - paule32
  4. // policy: (c) 2021 by kallup.net - non-profit
  5. //
  6. // desc:   if scan/lexem, and parse ok, try to create x86
  7. //         32-bit binary code for using under Windows 10 Pro.
  8. // ----------------------------------------------------------
  9. unit x86code;
  10.  
  11. interface
  12. uses
  13.   Windows, Classes, SysUtils, Dialogs;
  14.  
  15.   type TSize = type Cardinal;
  16.  
  17.   procedure WritePEHeader;
  18.   procedure EmitCode(X: array of Byte; const Bytes: TSize);
  19. implementation
  20. uses
  21.   scanner;
  22.  
  23. type
  24.   TX86Register = (
  25.     regEAX, regECX, regEDX, regEBX, regESP, regEBP, regESI, regEDI,
  26.     regAX , regCX , regDX , regBX , regSP , regBP , regSI , regDI ,
  27.     regAL , regCL , regDL , regBL , regAH , regCH , regDH , regBH);
  28.  
  29. const
  30.   // MZ header (start of the file)
  31.   DOSStubHeader: Array[1..64] of Byte = (
  32.   $0e, $1f, $ba, $0e, $00, $b4, $09, $cd, $21, $b8, $01, $4c, $cd, $21, $54, $68,
  33.   $69, $73, $20, $70, $72, $6f, $67, $72, $61, $6d, $20, $63, $61, $6e, $6e, $6f,
  34.   $74, $20, $62, $65, $20, $72, $75, $6e, $20, $69, $6e, $20, $44, $4f, $53, $20,
  35.   $6d, $6f, $64, $65, $2e, $0d, $0a, $24, $00, $00, $00, $00, $00, $00, $00, $00
  36.   );
  37.  
  38.   // PE header:
  39.   PEHeader: Array[0..3] of Byte = ($50, $45, $00, $00);
  40. type
  41.   TImageDosHeader = record
  42.     e_magic   : WORD;                  // $0000
  43.     e_cblp    : WORD;                  // $0002
  44.     e_cp      : WORD;                  // $0004
  45.     e_creloc  : WORD;                  // $0006
  46.     e_cparhdr : WORD;                  // $0008
  47.     e_minalloc: WORD;                  // $000a
  48.     e_maxalloc: WORD;                  // $000c
  49.     e_ss      : WORD;                  // $000e
  50.     e_sp      : WORD;                  // $0010
  51.     e_csum    : WORD;                  // $0012
  52.     e_ip      : DWORD;                 // $0014
  53.     e_lfarlc  : WORD;                  // $0018
  54.     e_ovno    : WORD;                  // $001a
  55.  
  56.     // new executable
  57.     e_res     : Array[1..4]  of Byte;  // $001c
  58.     e_oemid   : WORD;                  // $0020
  59.     e_oeminfo : WORD;                  // $0022
  60.     e_res2    : Array[1..22] of Char;  //
  61.     e_lfanew  : DWORD;                 //
  62.   end;
  63. var
  64.   ImageDosHeader: TImageDosHeader;
  65. type
  66.   TImageNtHeader = record
  67.     signature: Array [1..4] of Byte;
  68.   end;
  69. var
  70.   ImageNTHeader: TImageNTHeader;
  71. type
  72.   // file image header:
  73.   TImageFileHeader = record
  74.     machine             : WORD ;
  75.     numbersOfSections   : WORD ;
  76.     timeDateStamp       : DWORD;
  77.     pointerToSymbolTable: DWORD;
  78.     numberOfSymbols     : DWORD;
  79.     sizeOfOptionalHdr   : WORD ;
  80.     characteristics     : WORD ;
  81.   end;
  82.  
  83. var
  84.   ImageFileHeader: TImageFileHeader;
  85.  
  86. const
  87.   NUMBEROFSECTIONS = 3; // 1x .text
  88.                         // 1x .rdata
  89.                         // 1x .data
  90.   BIN_IMAGEBASE    = $400000;
  91.   BIN_SECTIONALIGN = $1000;
  92.   BIN_FILEALIGN    = $200;
  93. type
  94.   TImageSectionHeader = record
  95.     name     : Array[1..8] of Char;   // .text .data .rdata
  96.     vsize    : DWORD;
  97.     voffset  : DWORD;
  98.     rsize    : DWORD;
  99.     roffset  : DWORD;
  100.     ptrReloc : DWORD;
  101.     ptrLines : DWORD;
  102.     numReloc : WORD ;
  103.     numLines : WORD ;
  104.     flags    : DWORD;
  105.   end;
  106. var
  107.   ImageSectionHeaderTEXT: TImageSectionHeader =
  108.     ( name   : '.text' + #0#0#0;
  109.       vsize  : $00001000    ;
  110.       voffset: $00001000 * 1;
  111.       rsize  : $00000200    ;
  112.       roffset: $00000200 * 1;
  113.       flags  : $60000020);
  114.   ImageSectionHeaderRDATA: TImageSectionHeader =
  115.     ( name   : '.rdata' + #0#0;
  116.       vsize  : $00001000    ;
  117.       voffset: $00001000 * 2;
  118.       rsize  : $00000200    ;
  119.       roffset: $00000200 * 2;
  120.       flags  : $40000040);
  121.   ImageSectionHeaderDATA: TImageSectionHeader =
  122.     ( name   : '.data' + #0#0#0;
  123.       vsize  : $00001000    ;
  124.       voffset: $00001000 * 3;
  125.       rsize  : $00000200    ;
  126.       roffset: $00000200 * 3;
  127.       flags  : $C0000040);
  128. type
  129.   TImageOptionalHeader32 = record
  130.     magic                      : WORD ;
  131.     majorLinkerVersion         : BYTE ;
  132.     minorLinkerVersion         : BYTE ;
  133.     sizeOfCode                 : DWORD;
  134.     sizeOfInitializedData      : DWORD;
  135.     sizeOfUninitializedData    : DWORD;
  136.     addressOfEntryPoint        : DWORD;
  137.     baseOfCode                 : DWORD;
  138.     baseOfData                 : DWORD;
  139.     imageBase                  : DWORD;
  140.     sectionAlignment           : DWORD;
  141.     fileAlignment              : DWORD;
  142.     majorOperatingSystemVersion: WORD ;
  143.     minorOperatongSystemVersion: WORD ;
  144.     majorImageVersion          : WORD ;
  145.     minorImageVersion          : WORD ;
  146.     majorSubsystemVersion      : WORD ;
  147.     minorSubsystemVersion      : WORD ;
  148.     win32VersionValue          : DWORD;
  149.     sizeOfImage                : DWORD;
  150.     sizeOfHeaders              : DWORD;
  151.     checkSum                   : DWORD;
  152.     subsystem                  : WORD ;
  153.     dllCharacteristics         : WORD ;
  154.     sizeOfStackReserve         : DWORD;
  155.     sizeOfStackCommit          : DWORD;
  156.     sizeOfHeapReserve          : DWORD;
  157.     sizeOfHeapCommit           : DWORD;
  158.     loaderFlags                : DWORD;
  159.     numberOfRVAandSizes        : DWORD;
  160.   end;
  161. var
  162.   ImageOptionalHeader32: TImageOptionalHeader32;
  163. type
  164.   TImageDataDirectory16 = record
  165.     exportRVA       : DWORD;    // export table
  166.     exportSize      : DWORD;    // size
  167.     importsRVA      : DWORD;    // import table
  168.     importsSize     : DWORD;
  169.     resourceVA      : DWORD;
  170.     resourceSize    : DWORD;
  171.     exception       : DWORD;
  172.     exceptionSize   : DWORD;
  173.     security        : DWORD;
  174.     securitySize    : DWORD;
  175.     relocation      : DWORD;
  176.     relocationSize  : DWORD;
  177.     debug           : DWORD;
  178.     debugSize       : DWORD;
  179.     Copyright       : DWORD;
  180.     CopyrightSize   : DWORD;
  181.     globalPtr       : DWORD;
  182.     globalPtrSize   : DWORD;
  183.     TLSTable        : DWORD;
  184.     TLSTableSize    : DWORD;
  185.     LoadConfig      : DWORD;
  186.     LoadConfigSize  : DWORD;
  187.     boundImport     : DWORD;
  188.     boundImportSize : DWORD;
  189.     IAT             : DWORD;
  190.     IATSize         : DWORD;
  191.     delayImportsVA  : DWORD;
  192.     delayImportsSize: DWORD;
  193.     COM             : DWORD;
  194.     COMSize         : DWORD;
  195.     reserved        : DWORD;
  196.     reservedSize    : DWORD;
  197.   end;
  198. var
  199.   ImageDataDirectory16: TImageDataDirectory16;
  200. const
  201.   IMAGE_FILE_MACHINE_I386       = $014c;
  202.   IMAGE_FILE_MACHINE_AMD64      = $8664;
  203.  
  204.   IMAGE_FILE_EXECUTABLE_IMAGE   = $2;
  205.   IMAGE_FILE_32BIT_MACHINE      = $100;
  206.  
  207.   IMAGE_NT_OPTIONAL_HDR32_MAGIC = $10b;
  208.   IMAGE_NT_OPTIONAL_HDR64_MAGIC = $20b;
  209.  
  210.   IMAGE_SUBSYSTEM_WINDOWS_GUI   = 3;
  211.   IMAGE_SUBSYSTEM_WINDOWS_CUI   = 2;
  212. type
  213.   TImageImportDescriptor = record
  214.     originalFirstThunk: DWORD;
  215.     timeStamp         : DWORD;
  216.     forwarderChain    : DWORD;
  217.     name1             : DWORD;
  218.     firstThunk        : DWORD;
  219.   end;
  220.  
  221. // --------------------------------------------------------
  222. // transpile byte code to string "streamCode" ...
  223. // --------------------------------------------------------
  224. procedure EmitCode(X: array of byte; const Bytes: TSize);
  225. var
  226.   s: string;
  227. begin
  228.   SetString(s, PChar(@X), Bytes);
  229.   streamSrcCode := streamSrcCode + s;
  230. end;
  231.  
  232. // ----------------------------------------------------------
  233. // write Windows 10 32-Bit PE file image ...
  234. // ----------------------------------------------------------
  235. procedure WritePEHeader;
  236. var
  237.   stream: TStream;
  238.   p, len: Integer;
  239.   zero  : Array [1..BIN_FILEALIGN] of Byte;
  240.   c     : Char;
  241.  
  242.   title  : string;
  243.   caption: string;
  244. begin
  245.   FillChar(ImageDosHeader       , sizeof(TImageDosHeader       ), 0);
  246.   FillChar(ImageNtHeader        , sizeof(TImageNtHeader        ), 0);
  247.   FillChar(ImageFileHeader      , sizeof(TImageFileHeader      ), 0);
  248.   FillChar(ImageOptionalHeader32, sizeof(TImageOptionalHeader32), 0);
  249.   FillChar(ImageDataDirectory16 , sizeof(TImageDataDirectory16 ), 0);
  250.  
  251.   FillChar(zero,BIN_FILEALIGN,0);
  252.  
  253.   // --------------------------------------------------------
  254.   // MZ DOS-stub header ...
  255.   // --------------------------------------------------------
  256.   with ImageDosHeader do begin
  257.     e_magic    := $5a4d; { MZ }
  258.     e_cblp     := $0090;
  259.     e_cp       := $0003;
  260.     e_cparhdr  := $0004;
  261.     e_minalloc := $0000;
  262.     e_maxalloc := $ffff;
  263.     e_ss       := $0000;
  264.     e_sp       := $0000;
  265.     e_lfanew   := $0080;  // PE (after MZ header)
  266.   end;
  267.  
  268.   // --------------------------------------------------------
  269.   // PE Windows 32-Bit header:
  270.   // --------------------------------------------------------
  271.   with ImageNtHeader do begin
  272.     signature[1] := Byte('P');
  273.     signature[2] := Byte('E');
  274.     signature[3] := $00;
  275.     signature[4] := $00;
  276.   end;
  277.  
  278.   with ImageFileHeader do begin
  279.     machine           := IMAGE_FILE_MACHINE_I386;
  280.     numbersOfSections := NUMBEROFSECTIONS;
  281.     sizeOfOptionalHdr := $e0;   //SIZEOFOPTIONALHEADER;
  282.     characteristics   := IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE;
  283.   end;
  284.  
  285.   with ImageOptionalHeader32 do begin
  286.     magic                 := IMAGE_NT_OPTIONAL_HDR32_MAGIC;
  287.     addressOfEntryPoint   := $1000; // fixme
  288.     imageBase             := BIN_IMAGEBASE;
  289.     sectionAlignment      := BIN_SECTIONALIGN;
  290.     fileAlignment         := BIN_FILEALIGN;
  291.     majorSubsystemVersion := 4 ;
  292.     sizeOfImage           := 4 * BIN_SECTIONALIGN;  // 3 * sections + header
  293.     sizeOfHeaders         := $0200; //SIZEOFHEADERS;
  294.     Subsystem             := IMAGE_SUBSYSTEM_WINDOWS_CUI;
  295.     numberOfRvaAndSizes   := $10;
  296.   end;
  297.  
  298. //  ImageDataDirectory16.importSize := BIN_SECTIONALIGN * 2; // fixme import table size
  299.  
  300.   // --------------------------------------------------------
  301.   // application 32-Bit x86 binary code:
  302.   // --------------------------------------------------------
  303.   if Length(streamSrcCode) > 0 then begin
  304.     try
  305.       stream := TFileStream.Create('a.out', fmCreate);
  306.     except
  307.       on e: Exception do begin
  308.         ShowMessage('can not open output file.');
  309.         exit;
  310.       end;
  311.     end;
  312.  
  313.     stream.WriteBuffer(ImageDosHeader       , sizeof(TImageDosHeader));
  314.     stream.WriteBuffer(DosStubHeader        , 64);
  315.     stream.WriteBuffer(ImageNtHeader        ,  4);
  316.     stream.WriteBuffer(ImageFileHeader      , sizeof(TImageFileHeader      ));
  317.     stream.WriteBuffer(ImageOptionalHeader32, sizeof(TImageOptionalHeader32));
  318.     stream.WriteBuffer(ImageDataDirectory16 , sizeof(TImageDataDirectory16 ));
  319.  
  320.     stream.WriteBuffer(ImageSectionHeaderTEXT,sizeof(ImageSectionHeaderTEXT  ));
  321.     stream.WriteBuffer(ImageSectionHeaderRDATA,sizeof(ImageSectionHeaderRDATA));
  322.     stream.WriteBuffer(ImageSectionHeaderDATA,sizeof(ImageSectionHeaderDATA  ));
  323.  
  324.     for p := 1 to 80 do
  325.     stream.WriteBuffer(zero[p],1);
  326.  
  327.     for p := 1 to 4 do
  328.     stream.WriteBuffer(streamSrcCode[p],1);
  329.  
  330.     // data section:
  331.     title   := 'simple PE executable.' + #$0;
  332.     caption := 'Hello World !' + #$0;
  333.  
  334.     len := 22; for p := 1 to len do stream.WriteBuffer(title  [p], 1);
  335.     len := 14; for p := 1 to len do stream.WriteBuffer(caption[p], 1);
  336.  
  337.     len := stream.Position;
  338.     if len < 2048 then begin
  339.       len := (2048 - len);
  340.       for p := 1 to len do
  341.       stream.WriteBuffer(zero,1);
  342.     end;
  343.  
  344. //    stream.WriteBuffer(zero,BIN_FILEALIGN);
  345.  
  346.     stream.Free;
  347.  
  348.   end else begin
  349.     ShowMessage('warning: no application code.');
  350.   end;
  351.  
  352.   ShowMessage('file a.out written.');
  353. end;
  354.  
  355. end.
  356.  

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Windows 32-Bit Exec self made - how ?
« Reply #2 on: September 20, 2021, 09:59:42 pm »
What are you actually trying to do?

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

paulee32

  • New Member
  • *
  • Posts: 18
Re: Windows 32-Bit Exec self made - how ?
« Reply #3 on: September 20, 2021, 10:45:13 pm »
Making a Compiler, that can produce binary files for 32-bit (eventually 64-bit, too)
for the Windows 10 64-Bit Pro. Edition.
I had thinking over Linux Version, too.
But I don't have a Linux on road there at my Home PC.
So, I was happy, that Windows binary code works, without using Assembler + Linker
as fast as possible.
Like you can see, that is Delphi Code.
A second goal is, to have a executable with minimal binary code.
So, you could save space, because using DLL files.
I working on this project:
- a Visual Source Editor (exists, to test the Compiler)
- a Visual Designer (to design Forms with Buttons, ...) have a todo

Because, the Forum there I can't upload binary .exe file, to show the process,
I have to push it onto my server, so you could download it
here: https://www.kallup.net/pub/tmp/pas/wincom.zip

paulee32

  • New Member
  • *
  • Posts: 18
Re: Windows 32-Bit Exec self made - how ?
« Reply #4 on: September 20, 2021, 10:59:34 pm »
forget to say:

at the moment, only the command "define" is supported.
so, when you type "define" (without the quotes), and press F2-key, the a.out file will be produce.

 

TinyPortal © 2005-2018