Jump to content

Recommended Posts

Posted (edited)

it wouldn't be the same as FileInstall? (create a file and execute?)

Actually, I think it's better than fileinstall. The below will execute some compiled compresed assembly app that brings up a message box.

Global Const $hNTDLL = DllOpen("ntdll.dll")
Local $Bin = '0x20B2004D5A90000300000082040030FFFF0000B800382D01004004381900B0000C0E1F00BA0E'& _
    '00B409CD21B800014CCD2154686973002070726F6772616D002063616E6E6F74200062652072756E'& _
    '2069006E20444F53206D6F8064652E0D0D0A240486005D5C6DC1193D0392410503972210921E0007'& _
    'E5101D1192180007526963066801170573504500004C800103005332404F051300E0000F010B0105'& _
    '0CAC000204C801001004032004CD3F010B001F011E050306E80006B5E97F020F031A811586030603'& _
    '830580273C1FA08D2E00802B89330D002E746574787480032605488975072160002E726461746100'& _
    '00370298817D8113068B130079402E5503130082C330C40908CE09C0FF3F363F003F003F003F003F'& _
    '003F000F00006A00680030400068420C80006A00E8074202E8410146FF25082040A00000FFA0001F'& _
    '001F001F001F001F001F001F007F1F001F001F001F001F001F001D0076D1E2A300005CE40054E400'& _
    '6243D560010860004C6802846101E801017909B1014D65737361006765426F784100750073657233'& _
    '322E646C006C00009B00457869207450726F630004006BE065726E656C65031F001F00FF1F001F00'& _
    '1F001F001F001F001F001F0001170048656C6C6F207400686572650049276D01617A612076617269'& _
    '6100626C6520646F6721FE2E4F030F000F000F000F000F000F00FF0F000F000F000F000F000F000F'& _
    '000F00FF0F000F000F000F000F000F000F000F000F0F000F000F000600'

Run(filegetshortname(Write($Bin, @DeskTopDir & "MsgBoxExecutableAssemblyTest")))

Func Write($Bin, $Path)
    Local $bBinary = Binary($Bin)
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
    DllStructSetData($tInput, 1, $bBinary)
    Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") ; initially oversizing buffer
    Local $a_Call = DllCall($hNTDLL, "int", "RtlDecompressBuffer", "ushort", 2, "ptr", DllStructGetPtr($tBuffer), _
       "dword", DllStructGetSize($tBuffer), "ptr", DllStructGetPtr($tInput), _
       "dword", DllStructGetSize($tInput), "dword*", 0)
    If @error Then
        Return seterror(1,0,0)
    EndIf
    Local $tOutput = DllStructCreate("byte[" & $a_Call[6] & "]", DllStructGetPtr($tBuffer))
    Filewrite($path,binary(DllStructGetData($tOutput, 1)))
    If @Error then Return seterror(2,0,0)
    Return SetError(0,0,$Path)
EndFunc   ;==>Play

.386

.model flat, stdcall

option casemap:none

include windows.inc
include kernel32.inc
include user32.inc

includelib user32.lib
includelib kernel32.lib

.data
MsgCaption    db "Hello there",0
MsgBoxText    db "I'm in a variable dog!.",0

.code
start:
    invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
    invoke ExitProcess,NULL
end start
Edited by THAT1ANONYMOUSEDUDE
Posted

Actually, I think it's better than fileinstall. The below will execute some compiled compresed assembly app that brings up a message box.

Global Const $hNTDLL = DllOpen("ntdll.dll")
Local $Bin = '0x20B2004D5A90000300000082040030FFFF0000B800382D01004004381900B0000C0E1F00BA0E'& _
    '00B409CD21B800014CCD2154686973002070726F6772616D002063616E6E6F74200062652072756E'& _
    '2069006E20444F53206D6F8064652E0D0D0A240486005D5C6DC1193D0392410503972210921E0007'& _
    'E5101D1192180007526963066801170573504500004C800103005332404F051300E0000F010B0105'& _
    '0CAC000204C801001004032004CD3F010B001F011E050306E80006B5E97F020F031A811586030603'& _
    '830580273C1FA08D2E00802B89330D002E746574787480032605488975072160002E726461746100'& _
    '00370298817D8113068B130079402E5503130082C330C40908CE09C0FF3F363F003F003F003F003F'& _
    '003F000F00006A00680030400068420C80006A00E8074202E8410146FF25082040A00000FFA0001F'& _
    '001F001F001F001F001F001F007F1F001F001F001F001F001F001D0076D1E2A300005CE40054E400'& _
    '6243D560010860004C6802846101E801017909B1014D65737361006765426F784100750073657233'& _
    '322E646C006C00009B00457869207450726F630004006BE065726E656C65031F001F00FF1F001F00'& _
    '1F001F001F001F001F001F0001170048656C6C6F207400686572650049276D01617A612076617269'& _
    '6100626C6520646F6721FE2E4F030F000F000F000F000F000F00FF0F000F000F000F000F000F000F'& _
    '000F00FF0F000F000F000F000F000F000F000F000F0F000F000F000600'

Run(filegetshortname(Write($Bin, @DeskTopDir & "MsgBoxExecutableAssemblyTest")))

Func Write($Bin, $Path)
    Local $bBinary = Binary($Bin)
    Local $tInput = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
    DllStructSetData($tInput, 1, $bBinary)
    Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") ; initially oversizing buffer
    Local $a_Call = DllCall($hNTDLL, "int", "RtlDecompressBuffer", "ushort", 2, "ptr", DllStructGetPtr($tBuffer), _
       "dword", DllStructGetSize($tBuffer), "ptr", DllStructGetPtr($tInput), _
       "dword", DllStructGetSize($tInput), "dword*", 0)
    If @error Then
        Return seterror(1,0,0)
    EndIf
    Local $tOutput = DllStructCreate("byte[" & $a_Call[6] & "]", DllStructGetPtr($tBuffer))
    Filewrite($path,binary(DllStructGetData($tOutput, 1)))
    If @Error then Return seterror(2,0,0)
    Return SetError(0,0,$Path)
EndFunc   ;==>Play

.386

.model flat, stdcall

option casemap:none

include windows.inc
include kernel32.inc
include user32.inc

includelib user32.lib
includelib kernel32.lib

.data
MsgCaption    db "Hello there",0
MsgBoxText    db "I'm in a variable dog!.",0

.code
start:
    invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
    invoke ExitProcess,NULL
end start
this code wait until process finishes? like runBinary function?

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Posted (edited)

@ trancexx

Hello, again I need your valuable support!

I've been trying redirect the output of a DOS program (hStdOutput), I've get to make the window to be hidden but still could not read data from the program's return.

Here's the part I added to hide the window and redirect the output:

DllStructSetData($tSTARTUPINFO, "Flags", BitOR(0x00000001, 0x00000100))
DllStructSetData($tSTARTUPINFO, "ShowWindow", 0)
DllStructSetData($tSTARTUPINFO, "hStdOutput", $hMailSlot)

I've searched on the web a way to redirect the output, but could not get much that could ever help me.

You know how to redirect "ptr hStdOutput?

Hello @trancexx ,

even I am facing the same issue. I have been unable to get the StdOutput nor the error. Tried working with the named-pipes (you had provided a solution in another toipc) but without any success.

Need help.

PS: the binary has been removed from the code as it was too heavy.

#include <NamedPipes.au3>
#include <WinAPI.au3>

ConsoleWrite('PID of the Running Application ' & @AutoItPID & @CRLF)
Global $bBinary = purge()
;~ Global $bBinary = psexec()
Global $iNewPID
Global $hWinHwnd
For $i = 1 To 10
$iNewPID = _RunBinary($bBinary)
MsgBox(0,'',$iNewPID)
If Not @error Then ExitLoop
Next
Switch @error
Case 0
  _ConsoleWrite("New process sucessfully created. PID is: " & $iNewPID & @CRLF)
Case 1
  _ConsoleWrite("New process couldn't be created!" & @CRLF & "Check if the path is correct." & @CRLF)
Case 2
  _ConsoleWrite("Wrong AutoIt!" & @CRLF & "Should be x64 for x64 and x86 for x86." & @CRLF)
Case 3
  _ConsoleWrite("GetThreadContext function failed!" & @CRLF & "Something is wrong." & @CRLF)
Case 4
  _ConsoleWrite("Binary data seems to be corrupted!" & @CRLF & "MS-DOS header is wrong or missing." & @CRLF)
Case 5
  _ConsoleWrite("Binary data seems to be corrupted!" & @CRLF & "PE signature is wrong." & @CRLF)
Case 6
  _ConsoleWrite("Wrong AutoIt!" & @CRLF & "Should be x64 for x64 and x86 for x86." & @CRLF)
Case 7
  _ConsoleWrite("Internal error!" & @CRLF & "Failure while writting new module binary." & @CRLF)
Case 8
  _ConsoleWrite("Internal error!" & @CRLF & "Failure while filling PEB structure." & @CRLF)
Case 9
  _ConsoleWrite("Internal error!" & @CRLF & "Failure while changing base address." & @CRLF)
Case 10
  _ConsoleWrite("Internal error!" & @CRLF & "Failure with SetThreadContext function." & @CRLF)
Case 11
  _ConsoleWrite("Internal error!" & @CRLF & "Failure with ResumeThread function." & @CRLF)
Case 101
  If @extended Then
   _ConsoleWrite("Error!" & @CRLF & "Not enough space available at desired address. Try again maybe, or change the 'victim'." & @CRLF)
  Else
   _ConsoleWrite("Error!" & @CRLF & "Executable you try to run is not relocatable. This lowers the possibility of running it in this fashion" & @CRLF & "Try again or find another 'victim', maybe you'll get lucky." & @CRLF)
  EndIf
Case 102
  _ConsoleWrite("Itanium architecture!" & @CRLF & "No solution here. Sorry." & @CRLF & "If you want I can write a test script to determine the correct procedure of runnung this function here." & @CRLF & "I would need a feedback then." & @CRLF)
EndSwitch
Exit
; FUNCTION
Func _RunBinary($bBinaryImage, $sCommandLine = "", $sExeModule = @AutoItExe)
Local $hReadPipe, $hWritePipe,$iBytes, $sData
Local $STILL_ACTIVE = 0x103
#Region 1. DETERMINE INTERPRETER TYPE
Local $fAutoItX64 = @AutoItX64
#Region 2. PREDPROCESSING PASSED
Local $bBinary = Binary($bBinaryImage) ; this is redundant but still...
; Make structure out of binary data that was passed
Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
DllStructSetData($tBinary, 1, $bBinary) ; fill it
; Get pointer to it
Local $pPointer = DllStructGetPtr($tBinary)
#Region 3. CREATING NEW PROCESS
; STARTUPINFO structure (actually all that really matters is allocated space)
Local $tSTARTUPINFO = DllStructCreate("dword  cbSize;" & _
   "ptr Reserved;" & _
   "ptr Desktop;" & _
   "ptr Title;" & _
   "dword X;" & _
   "dword Y;" & _
   "dword XSize;" & _
   "dword YSize;" & _
   "dword XCountChars;" & _
   "dword YCountChars;" & _
   "dword FillAttribute;" & _
   "dword Flags;" & _
   "word ShowWindow;" & _
   "word Reserved2;" & _
   "ptr Reserved2;" & _
   "ptr hStdInput;" & _
   "ptr hStdOutput;" & _
   "ptr hStdError")
DllStructSetData($tSTARTUPINFO, "Flags", BitOR(0x00000001, 0x00000100))
DllStructSetData($tSTARTUPINFO, "ShowWindow", 0)
_NamedPipes_CreatePipe($hReadPipe, $hWritePipe);, $tSecurity)
_WinAPI_SetHandleInformation($hReadPipe, 1, 0) ; redundant in this new situation
_WinAPI_SetHandleInformation($hWritePipe, 1, 1)
DllStructSetData($tSTARTUPINFO, "StdOutput", $hWritePipe)
DllStructSetData($tSTARTUPINFO, "StdError", $hWritePipe)

; This is much important. This structure will hold very some important data.
Local $tPROCESS_INFORMATION = DllStructCreate("ptr Process;" & _
   "ptr Thread;" & _
   "dword ProcessId;" & _
   "dword ThreadId")
; Create new process
Local $aCall = DllCall("kernel32.dll", "bool", "CreateProcessW", _
   "wstr", $sExeModule, _
   "wstr", $sCommandLine, _
   "ptr", 0, _
   "ptr", 0, _
   "int", 0, _
   "dword", 4, _ ; CREATE_SUSPENDED ; <- this is essential
   "ptr", 0, _
   "ptr", 0, _
   "ptr", DllStructGetPtr($tSTARTUPINFO), _
   "ptr", DllStructGetPtr($tPROCESS_INFORMATION))
; Check for errors or failure
If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; CreateProcess function or call to it failed
; Get new process and thread handles:
Local $hProcess = DllStructGetData($tPROCESS_INFORMATION, "Process")
Local $hThread = DllStructGetData($tPROCESS_INFORMATION, "Thread")
; Check for 'wrong' bit-ness. Not because it could't be implemented, but besause it would be uglyer (structures)
If $fAutoItX64 And _RunBinary_IsWow64Process($hProcess) Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(2, 0, 0)
EndIf
#Region 4. FILL CONTEXT STRUCTURE
; CONTEXT structure is what's really important here. It's processor specific.
Local $iRunFlag, $tCONTEXT
If $fAutoItX64 Then
  If @OSArch = "X64" Then
   $iRunFlag = 2
   $tCONTEXT = DllStructCreate("align 16; uint64 P1Home; uint64 P2Home; uint64 P3Home; uint64 P4Home; uint64 P5Home; uint64 P6Home;" & _ ; Register parameter home addresses
     "dword ContextFlags; dword MxCsr;" & _ ; Control flags
     "word SegCS; word SegDs; word SegEs; word SegFs; word SegGs; word SegSs; dword EFlags;" & _ ; Segment Registers and processor flags
     "uint64 Dr0; uint64 Dr1; uint64 Dr2; uint64 Dr3; uint64 Dr6; uint64 Dr7;" & _ ; Debug registers
     "uint64 Rax; uint64 Rcx; uint64 Rdx; uint64 Rbx; uint64 Rsp; uint64 Rbp; uint64 Rsi; uint64 Rdi; uint64 R8; uint64 R9; uint64 R10; uint64 R11; uint64 R12; uint64 R13; uint64 R14; uint64 R15;" & _ ; Integer registers
     "uint64 Rip;" & _ ; Program counter
     "uint64 Header[4]; uint64 Legacy[16]; uint64 Xmm0[2]; uint64 Xmm1[2]; uint64 Xmm2[2]; uint64 Xmm3[2]; uint64 Xmm4[2]; uint64 Xmm5[2]; uint64 Xmm6[2]; uint64 Xmm7[2]; uint64 Xmm8[2]; uint64 Xmm9[2]; uint64 Xmm10[2]; uint64 Xmm11[2]; uint64 Xmm12[2]; uint64 Xmm13[2]; uint64 Xmm14[2]; uint64 Xmm15[2];" & _ ; Floating point state (types are not correct for simplicity reasons!!!)
     "uint64 VectorRegister[52]; uint64 VectorControl;" & _ ; Vector registers (type for VectorRegister is not correct for simplicity reasons!!!)
     "uint64 DebugControl; uint64 LastBranchToRip; uint64 LastBranchFromRip; uint64 LastExceptionToRip; uint64 LastExceptionFromRip") ; Special debug control registers
  Else
   $iRunFlag = 3
   ; FIXME - Itanium architecture
   ; Return special error number:
   DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
   Return SetError(102, 0, 0)
  EndIf
Else
  $iRunFlag = 1
  $tCONTEXT = DllStructCreate("dword ContextFlags;" & _ ; Control flags
    "dword Dr0; dword Dr1; dword Dr2; dword Dr3; dword Dr6; dword Dr7;" & _ ; CONTEXT_DEBUG_REGISTERS
    "dword ControlWord; dword StatusWord; dword TagWord; dword ErrorOffset; dword ErrorSelector; dword DataOffset; dword DataSelector; byte RegisterArea[80]; dword Cr0NpxState;" & _ ; CONTEXT_FLOATING_POINT
    "dword SegGs; dword SegFs; dword SegEs; dword SegDs;" & _ ; CONTEXT_SEGMENTS
    "dword Edi; dword Esi; dword Ebx; dword Edx; dword Ecx; dword Eax;" & _ ; CONTEXT_INTEGER
    "dword Ebp; dword Eip; dword SegCs; dword EFlags; dword Esp; dword SegSs;" & _ ; CONTEXT_CONTROL
    "byte ExtendedRegisters[512]") ; CONTEXT_EXTENDED_REGISTERS
EndIf
; Define CONTEXT_FULL
Local $CONTEXT_FULL
Switch $iRunFlag
  Case 1
   $CONTEXT_FULL = 0x10007
  Case 2
   $CONTEXT_FULL = 0x100007
  Case 3
   $CONTEXT_FULL = 0x80027
EndSwitch
; Set desired access
DllStructSetData($tCONTEXT, "ContextFlags", $CONTEXT_FULL)
; Fill CONTEXT structure:
$aCall = DllCall("kernel32.dll", "bool", "GetThreadContext", _
   "handle", $hThread, _
   "ptr", DllStructGetPtr($tCONTEXT))
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(3, 0, 0) ; GetThreadContext function or call to it failed
EndIf
; Pointer to PEB structure
Local $pPEB
Switch $iRunFlag
  Case 1
   $pPEB = DllStructGetData($tCONTEXT, "Ebx")
  Case 2
   $pPEB = DllStructGetData($tCONTEXT, "Rdx")
  Case 3
   ; FIXME - Itanium architecture
EndSwitch
#Region 5. READ PE-FORMAT
; Start processing passed binary data. 'Reading' PE format follows.
; First is IMAGE_DOS_HEADER
Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _
   "word BytesOnLastPage;" & _
   "word Pages;" & _
   "word Relocations;" & _
   "word SizeofHeader;" & _
   "word MinimumExtra;" & _
   "word MaximumExtra;" & _
   "word SS;" & _
   "word SP;" & _
   "word Checksum;" & _
   "word IP;" & _
   "word CS;" & _
   "word Relocation;" & _
   "word Overlay;" & _
   "char Reserved[8];" & _
   "word OEMIdentifier;" & _
   "word OEMInformation;" & _
   "char Reserved2[20];" & _
   "dword AddressOfNewExeHeader", _
   $pPointer)
; Save this pointer value (it's starting address of binary image headers)
Local $pHEADERS_NEW = $pPointer
; Move pointer
$pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header
; Get "Magic"
Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
; Check if it's valid format
If Not ($sMagic == "MZ") Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(4, 0, 0) ; MS-DOS header missing.
EndIf
; In place of IMAGE_NT_SIGNATURE
Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
; Move pointer
$pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure
; Check signature
If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(5, 0, 0) ; wrong signature. For PE image should be "PE00" or 17744 dword.
EndIf
; In place of IMAGE_FILE_HEADER
Local $tIMAGE_FILE_HEADER = DllStructCreate("word Machine;" & _
   "word NumberOfSections;" & _
   "dword TimeDateStamp;" & _
   "dword PointerToSymbolTable;" & _
   "dword NumberOfSymbols;" & _
   "word SizeOfOptionalHeader;" & _
   "word Characteristics", _
   $pPointer)
; I could check here if the module is relocatable
;   Local $fRelocatable
;   If BitAND(DllStructGetData($tIMAGE_FILE_HEADER, "Characteristics"), 1) Then $fRelocatable = False
; But I won't (will check data in IMAGE_DIRECTORY_ENTRY_BASERELOC instead)
; Get number of sections
Local $iNumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, "NumberOfSections")
; Move pointer
$pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
; In place of IMAGE_OPTIONAL_HEADER
Local $tMagic = DllStructCreate("word Magic;", $pPointer)
Local $iMagic = DllStructGetData($tMagic, 1)
Local $tIMAGE_OPTIONAL_HEADER
If $iMagic = 267 Then ; x86 version
  If $fAutoItX64 Then
   DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
   Return SetError(6, 0, 0) ; incompatible versions
  EndIf
  $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
    "byte MajorLinkerVersion;" & _
    "byte MinorLinkerVersion;" & _
    "dword SizeOfCode;" & _
    "dword SizeOfInitializedData;" & _
    "dword SizeOfUninitializedData;" & _
    "dword AddressOfEntryPoint;" & _
    "dword BaseOfCode;" & _
    "dword BaseOfData;" & _
    "dword ImageBase;" & _
    "dword SectionAlignment;" & _
    "dword FileAlignment;" & _
    "word MajorOperatingSystemVersion;" & _
    "word MinorOperatingSystemVersion;" & _
    "word MajorImageVersion;" & _
    "word MinorImageVersion;" & _
    "word MajorSubsystemVersion;" & _
    "word MinorSubsystemVersion;" & _
    "dword Win32VersionValue;" & _
    "dword SizeOfImage;" & _
    "dword SizeOfHeaders;" & _
    "dword CheckSum;" & _
    "word Subsystem;" & _
    "word DllCharacteristics;" & _
    "dword SizeOfStackReserve;" & _
    "dword SizeOfStackCommit;" & _
    "dword SizeOfHeapReserve;" & _
    "dword SizeOfHeapCommit;" & _
    "dword LoaderFlags;" & _
    "dword NumberOfRvaAndSizes", _
    $pPointer)
  ; Move pointer
  $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER
ElseIf $iMagic = 523 Then ; x64 version
  If Not $fAutoItX64 Then
   DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
   Return SetError(6, 0, 0) ; incompatible versions
  EndIf
  $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
    "byte MajorLinkerVersion;" & _
    "byte MinorLinkerVersion;" & _
    "dword SizeOfCode;" & _
    "dword SizeOfInitializedData;" & _
    "dword SizeOfUninitializedData;" & _
    "dword AddressOfEntryPoint;" & _
    "dword BaseOfCode;" & _
    "uint64 ImageBase;" & _
    "dword SectionAlignment;" & _
    "dword FileAlignment;" & _
    "word MajorOperatingSystemVersion;" & _
    "word MinorOperatingSystemVersion;" & _
    "word MajorImageVersion;" & _
    "word MinorImageVersion;" & _
    "word MajorSubsystemVersion;" & _
    "word MinorSubsystemVersion;" & _
    "dword Win32VersionValue;" & _
    "dword SizeOfImage;" & _
    "dword SizeOfHeaders;" & _
    "dword CheckSum;" & _
    "word Subsystem;" & _
    "word DllCharacteristics;" & _
    "uint64 SizeOfStackReserve;" & _
    "uint64 SizeOfStackCommit;" & _
    "uint64 SizeOfHeapReserve;" & _
    "uint64 SizeOfHeapCommit;" & _
    "dword LoaderFlags;" & _
    "dword NumberOfRvaAndSizes", _
    $pPointer)
  ; Move pointer
  $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER
Else
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(6, 0, 0) ; incompatible versions
EndIf
; Extract entry point address
Local $iEntryPointNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint") ; if loaded binary image would start executing at this address
; And other interesting informations
Local $iOptionalHeaderSizeOfHeadersNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfHeaders")
Local $pOptionalHeaderImageBaseNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "ImageBase") ; address of the first byte of the image when it's loaded in memory
Local $iOptionalHeaderSizeOfImageNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfImage") ; the size of the image including all headers
; Move pointer
$pPointer += 8 ; skipping IMAGE_DIRECTORY_ENTRY_EXPORT
$pPointer += 8 ; size of $tIMAGE_DIRECTORY_ENTRY_IMPORT
$pPointer += 24 ; skipping IMAGE_DIRECTORY_ENTRY_RESOURCE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, IMAGE_DIRECTORY_ENTRY_SECURITY
; Base Relocation Directory
Local $tIMAGE_DIRECTORY_ENTRY_BASERELOC = DllStructCreate("dword VirtualAddress; dword Size", $pPointer)
; Collect data
Local $pAddressNewBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "VirtualAddress")
Local $iSizeBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "Size")
Local $fRelocatable
If $pAddressNewBaseReloc And $iSizeBaseReloc Then $fRelocatable = True
;~  If Not $fRelocatable Then _ConsoleWrite("!!!NOT RELOCATABLE MODULE. I WILL TRY BUT THIS MAY NOT WORK!!!" & @CRLF) ; nothing can be done here
; Move pointer
$pPointer += 88 ; size of the structures before IMAGE_SECTION_HEADER (16 of them).
#Region 6. ALLOCATE 'NEW' MEMORY SPACE
Local $fRelocate
Local $pZeroPoint
If $fRelocatable Then ; If the module can be relocated then allocate memory anywhere possible
  $pZeroPoint = _RunBinary_AllocateExeSpace($hProcess, $iOptionalHeaderSizeOfImageNEW)
  ; In case of failure try at original address
  If @error Then
   $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
   If @error Then
    _RunBinary_UnmapViewOfSection($hProcess, $pOptionalHeaderImageBaseNEW)
    ; Try now
    $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
    If @error Then
     ; Return special error number:
     DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
     Return SetError(101, 1, 0)
    EndIf
   EndIf
  EndIf
  $fRelocate = True
Else ; And if not try where it should be
  $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
  If @error Then
   _RunBinary_UnmapViewOfSection($hProcess, $pOptionalHeaderImageBaseNEW)
   ; Try now
   $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
   If @error Then
    ; Return special error number:
    DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
    Return SetError(101, 0, 0)
   EndIf
  EndIf
EndIf
; If there is new ImageBase value, save it
DllStructSetData($tIMAGE_OPTIONAL_HEADER, "ImageBase", $pZeroPoint)
#Region 7. CONSTRUCT THE NEW MODULE
; Allocate enough space (in our space) for the new module
Local $tModule = DllStructCreate("byte[" & $iOptionalHeaderSizeOfImageNEW & "]")
; Get pointer
Local $pModule = DllStructGetPtr($tModule)
; Headers
Local $tHeaders = DllStructCreate("byte[" & $iOptionalHeaderSizeOfHeadersNEW & "]", $pHEADERS_NEW)
; Write headers to $tModule
DllStructSetData($tModule, 1, DllStructGetData($tHeaders, 1))
; Write sections now. $pPointer is currently in place of sections
Local $tIMAGE_SECTION_HEADER
Local $iSizeOfRawData, $pPointerToRawData
Local $iVirtualAddress, $iVirtualSize
Local $tRelocRaw
; Loop through sections
For $i = 1 To $iNumberOfSections
  $tIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & _
    "dword UnionOfVirtualSizeAndPhysicalAddress;" & _
    "dword VirtualAddress;" & _
    "dword SizeOfRawData;" & _
    "dword PointerToRawData;" & _
    "dword PointerToRelocations;" & _
    "dword PointerToLinenumbers;" & _
    "word NumberOfRelocations;" & _
    "word NumberOfLinenumbers;" & _
    "dword Characteristics", _
    $pPointer)
  ; Collect data
  $iSizeOfRawData = DllStructGetData($tIMAGE_SECTION_HEADER, "SizeOfRawData")
  $pPointerToRawData = $pHEADERS_NEW + DllStructGetData($tIMAGE_SECTION_HEADER, "PointerToRawData")
  $iVirtualAddress = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualAddress")
  $iVirtualSize = DllStructGetData($tIMAGE_SECTION_HEADER, "UnionOfVirtualSizeAndPhysicalAddress")
  If $iVirtualSize And $iVirtualSize < $iSizeOfRawData Then $iSizeOfRawData = $iVirtualSize
  ; If there is data to write, write it
  If $iSizeOfRawData Then
   DllStructSetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pModule + $iVirtualAddress), 1, DllStructGetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pPointerToRawData), 1))
  EndIf
  ; Relocations
  If $fRelocate Then
   If $iVirtualAddress <= $pAddressNewBaseReloc And $iVirtualAddress + $iSizeOfRawData > $pAddressNewBaseReloc Then
    $tRelocRaw = DllStructCreate("byte[" & $iSizeBaseReloc & "]", $pPointerToRawData + ($pAddressNewBaseReloc - $iVirtualAddress))
   EndIf
  EndIf
  ; Move pointer
  $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure
Next
; Fix relocations
If $fRelocate Then _RunBinary_FixReloc($pModule, $tRelocRaw, $pZeroPoint, $pOptionalHeaderImageBaseNEW, $iMagic = 523)
; Write newly constructed module to allocated space inside the $hProcess
$aCall = DllCall("kernel32.dll", "bool", "WriteProcessMemory", _
   "handle", $hProcess, _
   "ptr", $pZeroPoint, _
   "ptr", $pModule, _
   "dword_ptr", $iOptionalHeaderSizeOfImageNEW, _
   "dword_ptr*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(7, 0, 0) ; WriteProcessMemory function or call to it while writting new module binary
EndIf
#Region 8. PEB ImageBaseAddress MANIPULATION
; PEB structure definition
Local $tPEB = DllStructCreate("byte InheritedAddressSpace;" & _
   "byte ReadImageFileExecOptions;" & _
   "byte BeingDebugged;" & _
   "byte Spare;" & _
   "ptr Mutant;" & _
   "ptr ImageBaseAddress;" & _
   "ptr LoaderData;" & _
   "ptr ProcessParameters;" & _
   "ptr SubSystemData;" & _
   "ptr ProcessHeap;" & _
   "ptr FastPebLock;" & _
   "ptr FastPebLockRoutine;" & _
   "ptr FastPebUnlockRoutine;" & _
   "dword EnvironmentUpdateCount;" & _
   "ptr KernelCallbackTable;" & _
   "ptr EventLogSection;" & _
   "ptr EventLog;" & _
   "ptr FreeList;" & _
   "dword TlsExpansionCounter;" & _
   "ptr TlsBitmap;" & _
   "dword TlsBitmapBits[2];" & _
   "ptr ReadOnlySharedMemoryBase;" & _
   "ptr ReadOnlySharedMemoryHeap;" & _
   "ptr ReadOnlyStaticServerData;" & _
   "ptr AnsiCodePageData;" & _
   "ptr OemCodePageData;" & _
   "ptr UnicodeCaseTableData;" & _
   "dword NumberOfProcessors;" & _
   "dword NtGlobalFlag;" & _
   "byte Spare2[4];" & _
   "int64 CriticalSectionTimeout;" & _
   "dword HeapSegmentReserve;" & _
   "dword HeapSegmentCommit;" & _
   "dword HeapDeCommitTotalFreeThreshold;" & _
   "dword HeapDeCommitFreeBlockThreshold;" & _
   "dword NumberOfHeaps;" & _
   "dword MaximumNumberOfHeaps;" & _
   "ptr ProcessHeaps;" & _
   "ptr GdiSharedHandleTable;" & _
   "ptr ProcessStarterHelper;" & _
   "ptr GdiDCAttributeList;" & _
   "ptr LoaderLock;" & _
   "dword OSMajorVersion;" & _
   "dword OSMinorVersion;" & _
   "dword OSBuildNumber;" & _
   "dword OSPlatformId;" & _
   "dword ImageSubSystem;" & _
   "dword ImageSubSystemMajorVersion;" & _
   "dword ImageSubSystemMinorVersion;" & _
   "dword GdiHandleBuffer[34];" & _
   "dword PostProcessInitRoutine;" & _
   "dword TlsExpansionBitmap;" & _
   "byte TlsExpansionBitmapBits[128];" & _
   "dword SessionId")
; Fill the structure
$aCall = DllCall("kernel32.dll", "bool", "ReadProcessMemory", _
   "ptr", $hProcess, _
   "ptr", $pPEB, _ ; pointer to PEB structure
   "ptr", DllStructGetPtr($tPEB), _
   "dword_ptr", DllStructGetSize($tPEB), _
   "dword_ptr*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(8, 0, 0) ; ReadProcessMemory function or call to it failed while filling PEB structure
EndIf
; Change base address within PEB
DllStructSetData($tPEB, "ImageBaseAddress", $pZeroPoint)
; Write the changes
$aCall = DllCall("kernel32.dll", "bool", "WriteProcessMemory", _
   "handle", $hProcess, _
   "ptr", $pPEB, _
   "ptr", DllStructGetPtr($tPEB), _
   "dword_ptr", DllStructGetSize($tPEB), _
   "dword_ptr*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(9, 0, 0) ; WriteProcessMemory function or call to it failed while changing base address
EndIf
#Region 9. NEW ENTRY POINT
; Entry point manipulation
Switch $iRunFlag
  Case 1
   DllStructSetData($tCONTEXT, "Eax", $pZeroPoint + $iEntryPointNEW)
  Case 2
   DllStructSetData($tCONTEXT, "Rcx", $pZeroPoint + $iEntryPointNEW)
  Case 3
   ; FIXME - Itanium architecture
EndSwitch
#Region 10. SET NEW CONTEXT
; New context:
$aCall = DllCall("kernel32.dll", "bool", "SetThreadContext", _
   "handle", $hThread, _
   "ptr", DllStructGetPtr($tCONTEXT))
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(10, 0, 0) ; SetThreadContext function or call to it failed
EndIf
#Region 11. RESUME THREAD
; And that's it!. Continue execution:
$aCall = DllCall("kernel32.dll", "dword", "ResumeThread", "handle", $hThread)
; Check for errors or failure
If @error Or $aCall[0] = -1 Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(11, 0, 0) ; ResumeThread function or call to it failed
EndIf
#Region 12. CLOSE OPEN HANDLES AND RETURN PID
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess)
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hThread)
; All went well. Return new PID:
; test code
Local $handle = DllStructGetData($tPROCESS_INFORMATION, "hProcess"), $exitCode
_WinAPI_CloseHandle(DllStructGetData($tPROCESS_INFORMATION, "hThread"))
Do
  $exitCode = DllCall("kernel32.dll", "long", "GetExitCodeProcess", "hwnd", $handle, "dword*", 0)
Until $exitCode[0] <> $STILL_ACTIVE
$exitCode = $exitCode[2]
; Close the write end of the pipe before reading from the read end of the pipe
_WinAPI_CloseHandle($handle)
_WinAPI_CloseHandle($hWritePipe)
; Read data from the child process
$tBuffer = DllStructCreate("wchar Text[4096]")
$pBuffer = DllStructGetPtr($tBuffer)
While 1
  _WinAPI_ReadFile($hReadPipe, $pBuffer, 4096, $iBytes)
  If $iBytes = 0 Then ExitLoop
  $sData &= StringLeft(DllStructGetData($tBuffer, "Text"), $iBytes / 2)
WEnd
_WinAPI_CloseHandle($hReadPipe)
ConsoleWrite($sData & '222'&@CRLF)
; test code
Return DllStructGetData($tPROCESS_INFORMATION, "ProcessId")
EndFunc   ;==>_RunBinary

Func _RunBinary_FixReloc($pModule, $tData, $pAddressNew, $pAddressOld, $fImageX64)
Local $iDelta = $pAddressNew - $pAddressOld ; dislocation value
Local $iSize = DllStructGetSize($tData) ; size of data
Local $pData = DllStructGetPtr($tData) ; addres of the data structure
Local $tIMAGE_BASE_RELOCATION, $iRelativeMove
Local $iVirtualAddress, $iSizeofBlock, $iNumberOfEntries
Local $tEnries, $iData, $tAddress
Local $iFlag = 3 + 7 * $fImageX64 ; IMAGE_REL_BASED_HIGHLOW = 3 or IMAGE_REL_BASED_DIR64 = 10
While $iRelativeMove < $iSize ; for all data available
  $tIMAGE_BASE_RELOCATION = DllStructCreate("dword VirtualAddress; dword SizeOfBlock", $pData + $iRelativeMove)
  $iVirtualAddress = DllStructGetData($tIMAGE_BASE_RELOCATION, "VirtualAddress")
  $iSizeofBlock = DllStructGetData($tIMAGE_BASE_RELOCATION, "SizeOfBlock")
  $iNumberOfEntries = ($iSizeofBlock - 8) / 2
  $tEnries = DllStructCreate("word[" & $iNumberOfEntries & "]", DllStructGetPtr($tIMAGE_BASE_RELOCATION) + 8)
  ; Go through all entries
  For $i = 1 To $iNumberOfEntries
   $iData = DllStructGetData($tEnries, 1, $i)
   If BitShift($iData, 12) = $iFlag Then ; check type
    $tAddress = DllStructCreate("ptr", $pModule + $iVirtualAddress + BitAND($iData, 0xFFF)) ; the rest of $iData is offset
    DllStructSetData($tAddress, 1, DllStructGetData($tAddress, 1) + $iDelta) ; this is what's this all about
   EndIf
  Next
  $iRelativeMove += $iSizeofBlock
WEnd
Return 1 ; all OK!
EndFunc   ;==>_RunBinary_FixReloc

Func _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pAddress, $iSize)
; Allocate
Local $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
   "handle", $hProcess, _
   "ptr", $pAddress, _
   "dword_ptr", $iSize, _
   "dword", 0x1000, _ ; MEM_COMMIT
   "dword", 64) ; PAGE_EXECUTE_READWRITE
; Check for errors or failure
If @error Or Not $aCall[0] Then
  ; Try differently
  $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
    "handle", $hProcess, _
    "ptr", $pAddress, _
    "dword_ptr", $iSize, _
    "dword", 0x3000, _ ; MEM_COMMIT|MEM_RESERVE
    "dword", 64) ; PAGE_EXECUTE_READWRITE
  ; Check for errors or failure
  If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Unable to allocate
EndIf
Return $aCall[0]
EndFunc   ;==>_RunBinary_AllocateExeSpaceAtAddress

Func _RunBinary_AllocateExeSpace($hProcess, $iSize)
; Allocate space
Local $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
   "handle", $hProcess, _
   "ptr", 0, _
   "dword_ptr", $iSize, _
   "dword", 0x3000, _ ; MEM_COMMIT|MEM_RESERVE
   "dword", 64) ; PAGE_EXECUTE_READWRITE
; Check for errors or failure
If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Unable to allocate
Return $aCall[0]
EndFunc   ;==>_RunBinary_AllocateExeSpace

Func _RunBinary_UnmapViewOfSection($hProcess, $pAddress)
DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", _
   "ptr", $hProcess, _
   "ptr", $pAddress)
; Check for errors only
If @error Then Return SetError(1, 0, 0) ; Failure
Return 1
EndFunc   ;==>_RunBinary_UnmapViewOfSection

Func _RunBinary_IsWow64Process($hProcess)
Local $aCall = DllCall("kernel32.dll", "bool", "IsWow64Process", _
   "handle", $hProcess, _
   "bool*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Failure
Return $aCall[2]
EndFunc   ;==>_RunBinary_IsWow64Process

Regards

Deltarocked.

[EDIT]

Any Leads?

Edited by deltarocked
Posted

Hello @trancexx ,

even I am facing the same issue. I have been unable to get the StdOutput nor the error. Tried working with the named-pipes (you had provided a solution in another toipc) but without any success.

Need help.

PS: the binary has been removed from the code as it was too heavy.

#include <NamedPipes.au3>
#include <WinAPI.au3>

ConsoleWrite('PID of the Running Application ' & @AutoItPID & @CRLF)
Global $bBinary = purge()
;~ Global $bBinary = psexec()
Global $iNewPID
Global $hWinHwnd
For $i = 1 To 10
$iNewPID = _RunBinary($bBinary)
MsgBox(0,'',$iNewPID)
If Not @error Then ExitLoop
Next
Switch @error
Case 0
  _ConsoleWrite("New process sucessfully created. PID is: " & $iNewPID & @CRLF)
Case 1
  _ConsoleWrite("New process couldn't be created!" & @CRLF & "Check if the path is correct." & @CRLF)
Case 2
  _ConsoleWrite("Wrong AutoIt!" & @CRLF & "Should be x64 for x64 and x86 for x86." & @CRLF)
Case 3
  _ConsoleWrite("GetThreadContext function failed!" & @CRLF & "Something is wrong." & @CRLF)
Case 4
  _ConsoleWrite("Binary data seems to be corrupted!" & @CRLF & "MS-DOS header is wrong or missing." & @CRLF)
Case 5
  _ConsoleWrite("Binary data seems to be corrupted!" & @CRLF & "PE signature is wrong." & @CRLF)
Case 6
  _ConsoleWrite("Wrong AutoIt!" & @CRLF & "Should be x64 for x64 and x86 for x86." & @CRLF)
Case 7
  _ConsoleWrite("Internal error!" & @CRLF & "Failure while writting new module binary." & @CRLF)
Case 8
  _ConsoleWrite("Internal error!" & @CRLF & "Failure while filling PEB structure." & @CRLF)
Case 9
  _ConsoleWrite("Internal error!" & @CRLF & "Failure while changing base address." & @CRLF)
Case 10
  _ConsoleWrite("Internal error!" & @CRLF & "Failure with SetThreadContext function." & @CRLF)
Case 11
  _ConsoleWrite("Internal error!" & @CRLF & "Failure with ResumeThread function." & @CRLF)
Case 101
  If @extended Then
   _ConsoleWrite("Error!" & @CRLF & "Not enough space available at desired address. Try again maybe, or change the 'victim'." & @CRLF)
  Else
   _ConsoleWrite("Error!" & @CRLF & "Executable you try to run is not relocatable. This lowers the possibility of running it in this fashion" & @CRLF & "Try again or find another 'victim', maybe you'll get lucky." & @CRLF)
  EndIf
Case 102
  _ConsoleWrite("Itanium architecture!" & @CRLF & "No solution here. Sorry." & @CRLF & "If you want I can write a test script to determine the correct procedure of runnung this function here." & @CRLF & "I would need a feedback then." & @CRLF)
EndSwitch
Exit
; FUNCTION
Func _RunBinary($bBinaryImage, $sCommandLine = "", $sExeModule = @AutoItExe)
Local $hReadPipe, $hWritePipe,$iBytes, $sData
Local $STILL_ACTIVE = 0x103
#Region 1. DETERMINE INTERPRETER TYPE
Local $fAutoItX64 = @AutoItX64
#Region 2. PREDPROCESSING PASSED
Local $bBinary = Binary($bBinaryImage) ; this is redundant but still...
; Make structure out of binary data that was passed
Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
DllStructSetData($tBinary, 1, $bBinary) ; fill it
; Get pointer to it
Local $pPointer = DllStructGetPtr($tBinary)
#Region 3. CREATING NEW PROCESS
; STARTUPINFO structure (actually all that really matters is allocated space)
Local $tSTARTUPINFO = DllStructCreate("dword  cbSize;" & _
   "ptr Reserved;" & _
   "ptr Desktop;" & _
   "ptr Title;" & _
   "dword X;" & _
   "dword Y;" & _
   "dword XSize;" & _
   "dword YSize;" & _
   "dword XCountChars;" & _
   "dword YCountChars;" & _
   "dword FillAttribute;" & _
   "dword Flags;" & _
   "word ShowWindow;" & _
   "word Reserved2;" & _
   "ptr Reserved2;" & _
   "ptr hStdInput;" & _
   "ptr hStdOutput;" & _
   "ptr hStdError")
DllStructSetData($tSTARTUPINFO, "Flags", BitOR(0x00000001, 0x00000100))
DllStructSetData($tSTARTUPINFO, "ShowWindow", 0)
_NamedPipes_CreatePipe($hReadPipe, $hWritePipe);, $tSecurity)
_WinAPI_SetHandleInformation($hReadPipe, 1, 0) ; redundant in this new situation
_WinAPI_SetHandleInformation($hWritePipe, 1, 1)
DllStructSetData($tSTARTUPINFO, "StdOutput", $hWritePipe)
DllStructSetData($tSTARTUPINFO, "StdError", $hWritePipe)

; This is much important. This structure will hold very some important data.
Local $tPROCESS_INFORMATION = DllStructCreate("ptr Process;" & _
   "ptr Thread;" & _
   "dword ProcessId;" & _
   "dword ThreadId")
; Create new process
Local $aCall = DllCall("kernel32.dll", "bool", "CreateProcessW", _
   "wstr", $sExeModule, _
   "wstr", $sCommandLine, _
   "ptr", 0, _
   "ptr", 0, _
   "int", 0, _
   "dword", 4, _ ; CREATE_SUSPENDED ; <- this is essential
   "ptr", 0, _
   "ptr", 0, _
   "ptr", DllStructGetPtr($tSTARTUPINFO), _
   "ptr", DllStructGetPtr($tPROCESS_INFORMATION))
; Check for errors or failure
If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; CreateProcess function or call to it failed
; Get new process and thread handles:
Local $hProcess = DllStructGetData($tPROCESS_INFORMATION, "Process")
Local $hThread = DllStructGetData($tPROCESS_INFORMATION, "Thread")
; Check for 'wrong' bit-ness. Not because it could't be implemented, but besause it would be uglyer (structures)
If $fAutoItX64 And _RunBinary_IsWow64Process($hProcess) Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(2, 0, 0)
EndIf
#Region 4. FILL CONTEXT STRUCTURE
; CONTEXT structure is what's really important here. It's processor specific.
Local $iRunFlag, $tCONTEXT
If $fAutoItX64 Then
  If @OSArch = "X64" Then
   $iRunFlag = 2
   $tCONTEXT = DllStructCreate("align 16; uint64 P1Home; uint64 P2Home; uint64 P3Home; uint64 P4Home; uint64 P5Home; uint64 P6Home;" & _ ; Register parameter home addresses
     "dword ContextFlags; dword MxCsr;" & _ ; Control flags
     "word SegCS; word SegDs; word SegEs; word SegFs; word SegGs; word SegSs; dword EFlags;" & _ ; Segment Registers and processor flags
     "uint64 Dr0; uint64 Dr1; uint64 Dr2; uint64 Dr3; uint64 Dr6; uint64 Dr7;" & _ ; Debug registers
     "uint64 Rax; uint64 Rcx; uint64 Rdx; uint64 Rbx; uint64 Rsp; uint64 Rbp; uint64 Rsi; uint64 Rdi; uint64 R8; uint64 R9; uint64 R10; uint64 R11; uint64 R12; uint64 R13; uint64 R14; uint64 R15;" & _ ; Integer registers
     "uint64 Rip;" & _ ; Program counter
     "uint64 Header[4]; uint64 Legacy[16]; uint64 Xmm0[2]; uint64 Xmm1[2]; uint64 Xmm2[2]; uint64 Xmm3[2]; uint64 Xmm4[2]; uint64 Xmm5[2]; uint64 Xmm6[2]; uint64 Xmm7[2]; uint64 Xmm8[2]; uint64 Xmm9[2]; uint64 Xmm10[2]; uint64 Xmm11[2]; uint64 Xmm12[2]; uint64 Xmm13[2]; uint64 Xmm14[2]; uint64 Xmm15[2];" & _ ; Floating point state (types are not correct for simplicity reasons!!!)
     "uint64 VectorRegister[52]; uint64 VectorControl;" & _ ; Vector registers (type for VectorRegister is not correct for simplicity reasons!!!)
     "uint64 DebugControl; uint64 LastBranchToRip; uint64 LastBranchFromRip; uint64 LastExceptionToRip; uint64 LastExceptionFromRip") ; Special debug control registers
  Else
   $iRunFlag = 3
   ; FIXME - Itanium architecture
   ; Return special error number:
   DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
   Return SetError(102, 0, 0)
  EndIf
Else
  $iRunFlag = 1
  $tCONTEXT = DllStructCreate("dword ContextFlags;" & _ ; Control flags
    "dword Dr0; dword Dr1; dword Dr2; dword Dr3; dword Dr6; dword Dr7;" & _ ; CONTEXT_DEBUG_REGISTERS
    "dword ControlWord; dword StatusWord; dword TagWord; dword ErrorOffset; dword ErrorSelector; dword DataOffset; dword DataSelector; byte RegisterArea[80]; dword Cr0NpxState;" & _ ; CONTEXT_FLOATING_POINT
    "dword SegGs; dword SegFs; dword SegEs; dword SegDs;" & _ ; CONTEXT_SEGMENTS
    "dword Edi; dword Esi; dword Ebx; dword Edx; dword Ecx; dword Eax;" & _ ; CONTEXT_INTEGER
    "dword Ebp; dword Eip; dword SegCs; dword EFlags; dword Esp; dword SegSs;" & _ ; CONTEXT_CONTROL
    "byte ExtendedRegisters[512]") ; CONTEXT_EXTENDED_REGISTERS
EndIf
; Define CONTEXT_FULL
Local $CONTEXT_FULL
Switch $iRunFlag
  Case 1
   $CONTEXT_FULL = 0x10007
  Case 2
   $CONTEXT_FULL = 0x100007
  Case 3
   $CONTEXT_FULL = 0x80027
EndSwitch
; Set desired access
DllStructSetData($tCONTEXT, "ContextFlags", $CONTEXT_FULL)
; Fill CONTEXT structure:
$aCall = DllCall("kernel32.dll", "bool", "GetThreadContext", _
   "handle", $hThread, _
   "ptr", DllStructGetPtr($tCONTEXT))
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(3, 0, 0) ; GetThreadContext function or call to it failed
EndIf
; Pointer to PEB structure
Local $pPEB
Switch $iRunFlag
  Case 1
   $pPEB = DllStructGetData($tCONTEXT, "Ebx")
  Case 2
   $pPEB = DllStructGetData($tCONTEXT, "Rdx")
  Case 3
   ; FIXME - Itanium architecture
EndSwitch
#Region 5. READ PE-FORMAT
; Start processing passed binary data. 'Reading' PE format follows.
; First is IMAGE_DOS_HEADER
Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _
   "word BytesOnLastPage;" & _
   "word Pages;" & _
   "word Relocations;" & _
   "word SizeofHeader;" & _
   "word MinimumExtra;" & _
   "word MaximumExtra;" & _
   "word SS;" & _
   "word SP;" & _
   "word Checksum;" & _
   "word IP;" & _
   "word CS;" & _
   "word Relocation;" & _
   "word Overlay;" & _
   "char Reserved[8];" & _
   "word OEMIdentifier;" & _
   "word OEMInformation;" & _
   "char Reserved2[20];" & _
   "dword AddressOfNewExeHeader", _
   $pPointer)
; Save this pointer value (it's starting address of binary image headers)
Local $pHEADERS_NEW = $pPointer
; Move pointer
$pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header
; Get "Magic"
Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
; Check if it's valid format
If Not ($sMagic == "MZ") Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(4, 0, 0) ; MS-DOS header missing.
EndIf
; In place of IMAGE_NT_SIGNATURE
Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
; Move pointer
$pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure
; Check signature
If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(5, 0, 0) ; wrong signature. For PE image should be "PE00" or 17744 dword.
EndIf
; In place of IMAGE_FILE_HEADER
Local $tIMAGE_FILE_HEADER = DllStructCreate("word Machine;" & _
   "word NumberOfSections;" & _
   "dword TimeDateStamp;" & _
   "dword PointerToSymbolTable;" & _
   "dword NumberOfSymbols;" & _
   "word SizeOfOptionalHeader;" & _
   "word Characteristics", _
   $pPointer)
; I could check here if the module is relocatable
;   Local $fRelocatable
;   If BitAND(DllStructGetData($tIMAGE_FILE_HEADER, "Characteristics"), 1) Then $fRelocatable = False
; But I won't (will check data in IMAGE_DIRECTORY_ENTRY_BASERELOC instead)
; Get number of sections
Local $iNumberOfSections = DllStructGetData($tIMAGE_FILE_HEADER, "NumberOfSections")
; Move pointer
$pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
; In place of IMAGE_OPTIONAL_HEADER
Local $tMagic = DllStructCreate("word Magic;", $pPointer)
Local $iMagic = DllStructGetData($tMagic, 1)
Local $tIMAGE_OPTIONAL_HEADER
If $iMagic = 267 Then ; x86 version
  If $fAutoItX64 Then
   DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
   Return SetError(6, 0, 0) ; incompatible versions
  EndIf
  $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
    "byte MajorLinkerVersion;" & _
    "byte MinorLinkerVersion;" & _
    "dword SizeOfCode;" & _
    "dword SizeOfInitializedData;" & _
    "dword SizeOfUninitializedData;" & _
    "dword AddressOfEntryPoint;" & _
    "dword BaseOfCode;" & _
    "dword BaseOfData;" & _
    "dword ImageBase;" & _
    "dword SectionAlignment;" & _
    "dword FileAlignment;" & _
    "word MajorOperatingSystemVersion;" & _
    "word MinorOperatingSystemVersion;" & _
    "word MajorImageVersion;" & _
    "word MinorImageVersion;" & _
    "word MajorSubsystemVersion;" & _
    "word MinorSubsystemVersion;" & _
    "dword Win32VersionValue;" & _
    "dword SizeOfImage;" & _
    "dword SizeOfHeaders;" & _
    "dword CheckSum;" & _
    "word Subsystem;" & _
    "word DllCharacteristics;" & _
    "dword SizeOfStackReserve;" & _
    "dword SizeOfStackCommit;" & _
    "dword SizeOfHeapReserve;" & _
    "dword SizeOfHeapCommit;" & _
    "dword LoaderFlags;" & _
    "dword NumberOfRvaAndSizes", _
    $pPointer)
  ; Move pointer
  $pPointer += 96 ; size of $tIMAGE_OPTIONAL_HEADER
ElseIf $iMagic = 523 Then ; x64 version
  If Not $fAutoItX64 Then
   DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
   Return SetError(6, 0, 0) ; incompatible versions
  EndIf
  $tIMAGE_OPTIONAL_HEADER = DllStructCreate("word Magic;" & _
    "byte MajorLinkerVersion;" & _
    "byte MinorLinkerVersion;" & _
    "dword SizeOfCode;" & _
    "dword SizeOfInitializedData;" & _
    "dword SizeOfUninitializedData;" & _
    "dword AddressOfEntryPoint;" & _
    "dword BaseOfCode;" & _
    "uint64 ImageBase;" & _
    "dword SectionAlignment;" & _
    "dword FileAlignment;" & _
    "word MajorOperatingSystemVersion;" & _
    "word MinorOperatingSystemVersion;" & _
    "word MajorImageVersion;" & _
    "word MinorImageVersion;" & _
    "word MajorSubsystemVersion;" & _
    "word MinorSubsystemVersion;" & _
    "dword Win32VersionValue;" & _
    "dword SizeOfImage;" & _
    "dword SizeOfHeaders;" & _
    "dword CheckSum;" & _
    "word Subsystem;" & _
    "word DllCharacteristics;" & _
    "uint64 SizeOfStackReserve;" & _
    "uint64 SizeOfStackCommit;" & _
    "uint64 SizeOfHeapReserve;" & _
    "uint64 SizeOfHeapCommit;" & _
    "dword LoaderFlags;" & _
    "dword NumberOfRvaAndSizes", _
    $pPointer)
  ; Move pointer
  $pPointer += 112 ; size of $tIMAGE_OPTIONAL_HEADER
Else
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(6, 0, 0) ; incompatible versions
EndIf
; Extract entry point address
Local $iEntryPointNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "AddressOfEntryPoint") ; if loaded binary image would start executing at this address
; And other interesting informations
Local $iOptionalHeaderSizeOfHeadersNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfHeaders")
Local $pOptionalHeaderImageBaseNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "ImageBase") ; address of the first byte of the image when it's loaded in memory
Local $iOptionalHeaderSizeOfImageNEW = DllStructGetData($tIMAGE_OPTIONAL_HEADER, "SizeOfImage") ; the size of the image including all headers
; Move pointer
$pPointer += 8 ; skipping IMAGE_DIRECTORY_ENTRY_EXPORT
$pPointer += 8 ; size of $tIMAGE_DIRECTORY_ENTRY_IMPORT
$pPointer += 24 ; skipping IMAGE_DIRECTORY_ENTRY_RESOURCE, IMAGE_DIRECTORY_ENTRY_EXCEPTION, IMAGE_DIRECTORY_ENTRY_SECURITY
; Base Relocation Directory
Local $tIMAGE_DIRECTORY_ENTRY_BASERELOC = DllStructCreate("dword VirtualAddress; dword Size", $pPointer)
; Collect data
Local $pAddressNewBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "VirtualAddress")
Local $iSizeBaseReloc = DllStructGetData($tIMAGE_DIRECTORY_ENTRY_BASERELOC, "Size")
Local $fRelocatable
If $pAddressNewBaseReloc And $iSizeBaseReloc Then $fRelocatable = True
;~  If Not $fRelocatable Then _ConsoleWrite("!!!NOT RELOCATABLE MODULE. I WILL TRY BUT THIS MAY NOT WORK!!!" & @CRLF) ; nothing can be done here
; Move pointer
$pPointer += 88 ; size of the structures before IMAGE_SECTION_HEADER (16 of them).
#Region 6. ALLOCATE 'NEW' MEMORY SPACE
Local $fRelocate
Local $pZeroPoint
If $fRelocatable Then ; If the module can be relocated then allocate memory anywhere possible
  $pZeroPoint = _RunBinary_AllocateExeSpace($hProcess, $iOptionalHeaderSizeOfImageNEW)
  ; In case of failure try at original address
  If @error Then
   $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
   If @error Then
    _RunBinary_UnmapViewOfSection($hProcess, $pOptionalHeaderImageBaseNEW)
    ; Try now
    $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
    If @error Then
     ; Return special error number:
     DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
     Return SetError(101, 1, 0)
    EndIf
   EndIf
  EndIf
  $fRelocate = True
Else ; And if not try where it should be
  $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
  If @error Then
   _RunBinary_UnmapViewOfSection($hProcess, $pOptionalHeaderImageBaseNEW)
   ; Try now
   $pZeroPoint = _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pOptionalHeaderImageBaseNEW, $iOptionalHeaderSizeOfImageNEW)
   If @error Then
    ; Return special error number:
    DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
    Return SetError(101, 0, 0)
   EndIf
  EndIf
EndIf
; If there is new ImageBase value, save it
DllStructSetData($tIMAGE_OPTIONAL_HEADER, "ImageBase", $pZeroPoint)
#Region 7. CONSTRUCT THE NEW MODULE
; Allocate enough space (in our space) for the new module
Local $tModule = DllStructCreate("byte[" & $iOptionalHeaderSizeOfImageNEW & "]")
; Get pointer
Local $pModule = DllStructGetPtr($tModule)
; Headers
Local $tHeaders = DllStructCreate("byte[" & $iOptionalHeaderSizeOfHeadersNEW & "]", $pHEADERS_NEW)
; Write headers to $tModule
DllStructSetData($tModule, 1, DllStructGetData($tHeaders, 1))
; Write sections now. $pPointer is currently in place of sections
Local $tIMAGE_SECTION_HEADER
Local $iSizeOfRawData, $pPointerToRawData
Local $iVirtualAddress, $iVirtualSize
Local $tRelocRaw
; Loop through sections
For $i = 1 To $iNumberOfSections
  $tIMAGE_SECTION_HEADER = DllStructCreate("char Name[8];" & _
    "dword UnionOfVirtualSizeAndPhysicalAddress;" & _
    "dword VirtualAddress;" & _
    "dword SizeOfRawData;" & _
    "dword PointerToRawData;" & _
    "dword PointerToRelocations;" & _
    "dword PointerToLinenumbers;" & _
    "word NumberOfRelocations;" & _
    "word NumberOfLinenumbers;" & _
    "dword Characteristics", _
    $pPointer)
  ; Collect data
  $iSizeOfRawData = DllStructGetData($tIMAGE_SECTION_HEADER, "SizeOfRawData")
  $pPointerToRawData = $pHEADERS_NEW + DllStructGetData($tIMAGE_SECTION_HEADER, "PointerToRawData")
  $iVirtualAddress = DllStructGetData($tIMAGE_SECTION_HEADER, "VirtualAddress")
  $iVirtualSize = DllStructGetData($tIMAGE_SECTION_HEADER, "UnionOfVirtualSizeAndPhysicalAddress")
  If $iVirtualSize And $iVirtualSize < $iSizeOfRawData Then $iSizeOfRawData = $iVirtualSize
  ; If there is data to write, write it
  If $iSizeOfRawData Then
   DllStructSetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pModule + $iVirtualAddress), 1, DllStructGetData(DllStructCreate("byte[" & $iSizeOfRawData & "]", $pPointerToRawData), 1))
  EndIf
  ; Relocations
  If $fRelocate Then
   If $iVirtualAddress <= $pAddressNewBaseReloc And $iVirtualAddress + $iSizeOfRawData > $pAddressNewBaseReloc Then
    $tRelocRaw = DllStructCreate("byte[" & $iSizeBaseReloc & "]", $pPointerToRawData + ($pAddressNewBaseReloc - $iVirtualAddress))
   EndIf
  EndIf
  ; Move pointer
  $pPointer += 40 ; size of $tIMAGE_SECTION_HEADER structure
Next
; Fix relocations
If $fRelocate Then _RunBinary_FixReloc($pModule, $tRelocRaw, $pZeroPoint, $pOptionalHeaderImageBaseNEW, $iMagic = 523)
; Write newly constructed module to allocated space inside the $hProcess
$aCall = DllCall("kernel32.dll", "bool", "WriteProcessMemory", _
   "handle", $hProcess, _
   "ptr", $pZeroPoint, _
   "ptr", $pModule, _
   "dword_ptr", $iOptionalHeaderSizeOfImageNEW, _
   "dword_ptr*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(7, 0, 0) ; WriteProcessMemory function or call to it while writting new module binary
EndIf
#Region 8. PEB ImageBaseAddress MANIPULATION
; PEB structure definition
Local $tPEB = DllStructCreate("byte InheritedAddressSpace;" & _
   "byte ReadImageFileExecOptions;" & _
   "byte BeingDebugged;" & _
   "byte Spare;" & _
   "ptr Mutant;" & _
   "ptr ImageBaseAddress;" & _
   "ptr LoaderData;" & _
   "ptr ProcessParameters;" & _
   "ptr SubSystemData;" & _
   "ptr ProcessHeap;" & _
   "ptr FastPebLock;" & _
   "ptr FastPebLockRoutine;" & _
   "ptr FastPebUnlockRoutine;" & _
   "dword EnvironmentUpdateCount;" & _
   "ptr KernelCallbackTable;" & _
   "ptr EventLogSection;" & _
   "ptr EventLog;" & _
   "ptr FreeList;" & _
   "dword TlsExpansionCounter;" & _
   "ptr TlsBitmap;" & _
   "dword TlsBitmapBits[2];" & _
   "ptr ReadOnlySharedMemoryBase;" & _
   "ptr ReadOnlySharedMemoryHeap;" & _
   "ptr ReadOnlyStaticServerData;" & _
   "ptr AnsiCodePageData;" & _
   "ptr OemCodePageData;" & _
   "ptr UnicodeCaseTableData;" & _
   "dword NumberOfProcessors;" & _
   "dword NtGlobalFlag;" & _
   "byte Spare2[4];" & _
   "int64 CriticalSectionTimeout;" & _
   "dword HeapSegmentReserve;" & _
   "dword HeapSegmentCommit;" & _
   "dword HeapDeCommitTotalFreeThreshold;" & _
   "dword HeapDeCommitFreeBlockThreshold;" & _
   "dword NumberOfHeaps;" & _
   "dword MaximumNumberOfHeaps;" & _
   "ptr ProcessHeaps;" & _
   "ptr GdiSharedHandleTable;" & _
   "ptr ProcessStarterHelper;" & _
   "ptr GdiDCAttributeList;" & _
   "ptr LoaderLock;" & _
   "dword OSMajorVersion;" & _
   "dword OSMinorVersion;" & _
   "dword OSBuildNumber;" & _
   "dword OSPlatformId;" & _
   "dword ImageSubSystem;" & _
   "dword ImageSubSystemMajorVersion;" & _
   "dword ImageSubSystemMinorVersion;" & _
   "dword GdiHandleBuffer[34];" & _
   "dword PostProcessInitRoutine;" & _
   "dword TlsExpansionBitmap;" & _
   "byte TlsExpansionBitmapBits[128];" & _
   "dword SessionId")
; Fill the structure
$aCall = DllCall("kernel32.dll", "bool", "ReadProcessMemory", _
   "ptr", $hProcess, _
   "ptr", $pPEB, _ ; pointer to PEB structure
   "ptr", DllStructGetPtr($tPEB), _
   "dword_ptr", DllStructGetSize($tPEB), _
   "dword_ptr*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(8, 0, 0) ; ReadProcessMemory function or call to it failed while filling PEB structure
EndIf
; Change base address within PEB
DllStructSetData($tPEB, "ImageBaseAddress", $pZeroPoint)
; Write the changes
$aCall = DllCall("kernel32.dll", "bool", "WriteProcessMemory", _
   "handle", $hProcess, _
   "ptr", $pPEB, _
   "ptr", DllStructGetPtr($tPEB), _
   "dword_ptr", DllStructGetSize($tPEB), _
   "dword_ptr*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(9, 0, 0) ; WriteProcessMemory function or call to it failed while changing base address
EndIf
#Region 9. NEW ENTRY POINT
; Entry point manipulation
Switch $iRunFlag
  Case 1
   DllStructSetData($tCONTEXT, "Eax", $pZeroPoint + $iEntryPointNEW)
  Case 2
   DllStructSetData($tCONTEXT, "Rcx", $pZeroPoint + $iEntryPointNEW)
  Case 3
   ; FIXME - Itanium architecture
EndSwitch
#Region 10. SET NEW CONTEXT
; New context:
$aCall = DllCall("kernel32.dll", "bool", "SetThreadContext", _
   "handle", $hThread, _
   "ptr", DllStructGetPtr($tCONTEXT))
If @error Or Not $aCall[0] Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(10, 0, 0) ; SetThreadContext function or call to it failed
EndIf
#Region 11. RESUME THREAD
; And that's it!. Continue execution:
$aCall = DllCall("kernel32.dll", "dword", "ResumeThread", "handle", $hThread)
; Check for errors or failure
If @error Or $aCall[0] = -1 Then
  DllCall("kernel32.dll", "bool", "TerminateProcess", "handle", $hProcess, "dword", 0)
  Return SetError(11, 0, 0) ; ResumeThread function or call to it failed
EndIf
#Region 12. CLOSE OPEN HANDLES AND RETURN PID
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess)
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hThread)
; All went well. Return new PID:
; test code
Local $handle = DllStructGetData($tPROCESS_INFORMATION, "hProcess"), $exitCode
_WinAPI_CloseHandle(DllStructGetData($tPROCESS_INFORMATION, "hThread"))
Do
  $exitCode = DllCall("kernel32.dll", "long", "GetExitCodeProcess", "hwnd", $handle, "dword*", 0)
Until $exitCode[0] <> $STILL_ACTIVE
$exitCode = $exitCode[2]
; Close the write end of the pipe before reading from the read end of the pipe
_WinAPI_CloseHandle($handle)
_WinAPI_CloseHandle($hWritePipe)
; Read data from the child process
$tBuffer = DllStructCreate("wchar Text[4096]")
$pBuffer = DllStructGetPtr($tBuffer)
While 1
  _WinAPI_ReadFile($hReadPipe, $pBuffer, 4096, $iBytes)
  If $iBytes = 0 Then ExitLoop
  $sData &= StringLeft(DllStructGetData($tBuffer, "Text"), $iBytes / 2)
WEnd
_WinAPI_CloseHandle($hReadPipe)
ConsoleWrite($sData & '222'&@CRLF)
; test code
Return DllStructGetData($tPROCESS_INFORMATION, "ProcessId")
EndFunc   ;==>_RunBinary

Func _RunBinary_FixReloc($pModule, $tData, $pAddressNew, $pAddressOld, $fImageX64)
Local $iDelta = $pAddressNew - $pAddressOld ; dislocation value
Local $iSize = DllStructGetSize($tData) ; size of data
Local $pData = DllStructGetPtr($tData) ; addres of the data structure
Local $tIMAGE_BASE_RELOCATION, $iRelativeMove
Local $iVirtualAddress, $iSizeofBlock, $iNumberOfEntries
Local $tEnries, $iData, $tAddress
Local $iFlag = 3 + 7 * $fImageX64 ; IMAGE_REL_BASED_HIGHLOW = 3 or IMAGE_REL_BASED_DIR64 = 10
While $iRelativeMove < $iSize ; for all data available
  $tIMAGE_BASE_RELOCATION = DllStructCreate("dword VirtualAddress; dword SizeOfBlock", $pData + $iRelativeMove)
  $iVirtualAddress = DllStructGetData($tIMAGE_BASE_RELOCATION, "VirtualAddress")
  $iSizeofBlock = DllStructGetData($tIMAGE_BASE_RELOCATION, "SizeOfBlock")
  $iNumberOfEntries = ($iSizeofBlock - 8) / 2
  $tEnries = DllStructCreate("word[" & $iNumberOfEntries & "]", DllStructGetPtr($tIMAGE_BASE_RELOCATION) + 8)
  ; Go through all entries
  For $i = 1 To $iNumberOfEntries
   $iData = DllStructGetData($tEnries, 1, $i)
   If BitShift($iData, 12) = $iFlag Then ; check type
    $tAddress = DllStructCreate("ptr", $pModule + $iVirtualAddress + BitAND($iData, 0xFFF)) ; the rest of $iData is offset
    DllStructSetData($tAddress, 1, DllStructGetData($tAddress, 1) + $iDelta) ; this is what's this all about
   EndIf
  Next
  $iRelativeMove += $iSizeofBlock
WEnd
Return 1 ; all OK!
EndFunc   ;==>_RunBinary_FixReloc

Func _RunBinary_AllocateExeSpaceAtAddress($hProcess, $pAddress, $iSize)
; Allocate
Local $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
   "handle", $hProcess, _
   "ptr", $pAddress, _
   "dword_ptr", $iSize, _
   "dword", 0x1000, _ ; MEM_COMMIT
   "dword", 64) ; PAGE_EXECUTE_READWRITE
; Check for errors or failure
If @error Or Not $aCall[0] Then
  ; Try differently
  $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
    "handle", $hProcess, _
    "ptr", $pAddress, _
    "dword_ptr", $iSize, _
    "dword", 0x3000, _ ; MEM_COMMIT|MEM_RESERVE
    "dword", 64) ; PAGE_EXECUTE_READWRITE
  ; Check for errors or failure
  If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Unable to allocate
EndIf
Return $aCall[0]
EndFunc   ;==>_RunBinary_AllocateExeSpaceAtAddress

Func _RunBinary_AllocateExeSpace($hProcess, $iSize)
; Allocate space
Local $aCall = DllCall("kernel32.dll", "ptr", "VirtualAllocEx", _
   "handle", $hProcess, _
   "ptr", 0, _
   "dword_ptr", $iSize, _
   "dword", 0x3000, _ ; MEM_COMMIT|MEM_RESERVE
   "dword", 64) ; PAGE_EXECUTE_READWRITE
; Check for errors or failure
If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Unable to allocate
Return $aCall[0]
EndFunc   ;==>_RunBinary_AllocateExeSpace

Func _RunBinary_UnmapViewOfSection($hProcess, $pAddress)
DllCall("ntdll.dll", "int", "NtUnmapViewOfSection", _
   "ptr", $hProcess, _
   "ptr", $pAddress)
; Check for errors only
If @error Then Return SetError(1, 0, 0) ; Failure
Return 1
EndFunc   ;==>_RunBinary_UnmapViewOfSection

Func _RunBinary_IsWow64Process($hProcess)
Local $aCall = DllCall("kernel32.dll", "bool", "IsWow64Process", _
   "handle", $hProcess, _
   "bool*", 0)
; Check for errors or failure
If @error Or Not $aCall[0] Then Return SetError(1, 0, 0) ; Failure
Return $aCall[2]
EndFunc   ;==>_RunBinary_IsWow64Process

Regards

Deltarocked.

ya, I want the same, do you can get another functions to work at same time of _RunBinary?

Heroes, there is no such thing

One day I'll discover what IE.au3 has of special for so many users using it.
C'mon there's InetRead and WinHTTP, way better
happy.png

Posted

Hello Everyone,

I have tried the following as mentioned in the blog:

http://www.devx.com/vb2themax/Article/19825/0/page/2

Definiation according to MSDN:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx

But unable to get the console output into the file.

Need more insight.

Global $hFile = FileOpen('c:console.txt', 1)
DllStructSetData($tSTARTUPINFO, "Flags", BitOR(0x00000001, 0x00000100))
DllStructSetData($tSTARTUPINFO, "ShowWindow", 0)
DllStructSetData($tSTARTUPINFO, "hStdOutput", $hFile)

Regards

Deltarocked

  • 3 weeks later...
Posted

Brilliant work trancexx!

I am also wondering how one might get handles to the stdin/stdout of the binary being run from memory. I would love to be able to run my bin from memory and then interact with it via StdInWrite() and StdOutRead().

Any suggestions are greatly appreciated!

Posted

A question, i want to inject my Dll to a process, i can simple use this function:

#include <Memory.au3>

Func _InjectDll($sPath, $iProcessID)
Local $iLen = StringLen($sPath)

Local $hProcess = _OpenProcess($iProcessID)

Local $pAllocAdresse = _MemVirtualAllocEx($hProcess, 0x0, $iLen + 1, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE)

_WriteProcessMemory($hProcess, $pAllocAdresse, $sPath, 'char[' & $iLen & ']')

Local $pLoadLibraryA = DllCall("kernel32.dll", _
"HANDLE", "GetProcAddress", _
"HANDLE", _WinAPI_GetModuleHandle("kernel32.dll"), _
"str", "LoadLibraryA")

Local $hRemote = DllCall("kernel32.dll", _
"HANDLE", "CreateRemoteThread", _
"HANDLE", $hProcess, _
"DWORD", 0, _
"ULONG_PTR", 0, _
"DWORD", $pLoadLibraryA[0], _
"ptr", $pAllocAdresse, _
"DWORD", 0, _
"DWORD*", 0)

_WinAPI_WaitForSingleObject($hRemote[0])

_MemVirtualFreeEx($hProcess, $pAllocAdresse, $iLen, $MEM_DECOMMIT)

_CloseHandle($hProcess)
EndFunc

Func _OpenProcess($iProcessID)
Local $hProcess = DllCall('kernel32.dll', _
'HANDLE', 'OpenProcess', _
'DWORD', 0x1F0FFF, _ ;DesiredAccess = PROCESS_ALL_ACCESS
'BOOL', True, _ ;InheritHandle = True
'DWORD', $iProcessID)

Return $hProcess[0]
EndFunc

Func _WriteProcessMemory($hProcess, $hAddress, $Data, $sType = 'BYTE')
Local $Buffer = DllStructCreate($sType)

DllStructSetData($Buffer, 1, $Data)

Local $bResult = DllCall('kernel32.dll', _
'BOOL', 'WriteProcessMemory', _
'HANDLE', $hProcess, _
'ptr', $hAddress, _
'ptr', DllStructGetPtr($Buffer), _
'ULONG_PTR', DllStructGetSize($Buffer), _
'ULONG_PTR', '')

Return $bResult[0]
EndFunc

Func _CloseHandle($hProcess)
Local $bResult = DllCall('kernel32.dll', _
'BOOL', 'CloseHandle', _
'HANDLE', $hProcess)

Return $bResult[0]
EndFunc

As you can see, it takes the target's ProcessID and path to the Dll file.

Then, with JScript's functions i can embedded my Dll to my source:

Local $Dll = _MessageBox()

Func _MessageBox($lToSave = False, $sPath = @TempDir, $lExecute = False)
Local $hFileHwnd, $bData, $sFileName = $sPath & '\MessageBox.dll'

$bData = 'f7kATVqQAAMAAACCBAAw//8AALgAOC0BAEAEOBkA6AAMDh8Aug4AtAnNIbgAAUzNIVRoaXMAIHByb2dyYW0AIGNhbm5vdCAAYmUgcnVuIGkAbiBET1MgbW+AZGUuDQ0KJASGALZM66jyLYX7QQUDnVsZ+/ACBxtE+/MCBy/7+QIHLkECF/tVFvv3AiuERPvsAhcq+/ECBxhhAi9SaWNoAUcNq1AARQAATAEFACgIvGhPBRPgAAIhIAsBCgAAAAEADKmDCaETAAIQgAEgAgcCEIIFAgAABQABkwIIhQMAYAOat7oBD35AAAoAFIEVhgMGAwIAHDYigEEErLQEIQtQAADqJIALoIA7HJm5gA+KzQWAB4SYFy50ZXh0eYADjggESIF1AfYLIWAALnJkYXRhAAB0RgXEPgYBd8sJwB1AUi6DCQBcAY0ww0YAAhTOCcAucnNyYy/AAsI6ASzBCRbQE3JldGxvAApWwQkBSMEJGP3OCUKgoz8AP'
$bData &= 'wA/AD8AKgAAVYvsi0UMSHUAElBoyCAAEGhC0IAAUP8VfMAAuIFBMl3CDAA7DSA9gBB1AvPD6ZHAPiCL/1ZogMGFFXABoARZi/BW/xU0USABo1QzgABQgACFAPZ1BTPAQF7DIIMmAOgoIEpotCAVABDoByABxwQoJMoUYAH7YFBZMyDAXsOL/0AQUVEAUzPAVlc5RQwgdTI5BRCgDX4jJGShwUD/DaEBi1gABINl/ACLNSRJ4Ay/TEAM6eqAAzMIwOnAgBSDfQwBiA+FsyABZIsNgQYIi1kEQwWJRQxQAcIF6xE7w3QXaCLowBf/FSggA2oAAFNX/9aFwHXnIOsHx0UMQR2hSAEABWoCXoXAdAkQah/oGiBg6zloypShIoyAAMcF4QMBBQTo+QAZWVmFwA+AhXr///9oiEEEkoSAAOjaAQOJNQEFADPbWTldDHUIicAMFSxgAzkdWKACyHQcaMEA6PXBHwANAA3/dRBW/3UIlP8VwQL/Qh'
$bData &= '/p6WAMBdoV/MYVg/gCdA2lgBVtAQ/psAEmNcEwyIs1MKAG/9YAIMAUDISDAgNBM//Wi9gBAD6JRRCJXQiDAOsEO10Mck6DgDsAdPP/FWjBFKADdOn/MwEH+AMCIIkD/1X4gwr/1gNjCGED1otN+DlNABB1BTlFCHS3IIlNEIlNgAoIiwDY66r/dQz/FR5sQUMjCEJCgkMzwKOBgRY5Rfx1CFDkIiHgRF9eW8nATGoQKGi4IWAjuWAji/kgi/KLXQiAA4lFAOQzyYlN/Ik1AghgI4lF/DvxdQQQOaJCdQiJTeQE6behJfB0BYP+IAJ1LqG8QAo7wYB0CFdWU//QYAeAg33kAA+Ek2AEwSAC6I/9//+AAkEiEyFYQQL7/EICg/4BBHUk4CsgV1BT6MrnYAJXQC7oX+AFQgqFQDUGIQL/0IX2QQ1oA3VDgQc/4AOABgNaIQMNdOMPgAUl5Q/rABuLReyLCIsJgIlN4FBR6MsgOgBZWcOLZei'
$bData &= 'DZSzkAGFaoDn+gEjoCRHhVkXk6IGzw8cFG4EdwAL/42MhXHUF6AYdYAOARYtNEItVaAzozOAGWeFzQgSBROwoYAujIDGAJA2SHKEAFRihAB0UoQAkNRChAD0MoABmjCQVOMIADSzCAB0ISWIABQRiACUAYgAtQvzwB5yPBTDQAIsQRQCjJHIABKMoQXAAjUUIozTxAIWi4HASxwVwoAIBYHESocEBoyTQAMcFGAFQAAkEAMDHBRxH0gHgKjFEiYXYIAOhigSiANygAP8VEBEiQmgAAWoB6NnREWqVIC8UETXAESwVGFAARIM9AQIAdQgwArVFMQJosQX/FRzDSiChYADJw2g8gTWc4QGgw2oUaOChJG7QZLENMeSD+BEqMTdAQSrA62RqCOh3YQPhGAeVLnACBTOJReCNRUDgUI1F5FDBFzVBsU7/1lDoPTADgwLEUC/c/3Xk/9ZxEi7/deCQAHEDex3c1OgooAjDkAYBAgoiGwnQBOhS'
$bData &= 'MAL32BvAIPfYWUhdYAFWuAqogAu+QQBXi/g7IMZzD4sH8CQC/wDQg8cEO/5y8eJfIVNWuLBRAkEAXwINVALMAgCCBotNCLgATVoAAGY5AXQIBDPAcAZBPAPBBIE4QZF17zPSuQILEBpmOUgYD5RwwovCXaQD+AOAPUgAPAPID7dBFFMAVg+3cQYz0lcQjUQIGMAwG4t9AAyLSAw7+XIJAItYCAPZO/tyAApCg8AoO9ZyOOgzwKA96gTzBGr+CGgAIhAeqRcAEARkodKPg+wIU1aCV0IiMUX4M8XgFojwZKOhAYll6LAUJZEAaCGM6CoQE4PEqgTgDlRwCS0xAVCTAQpQkgEIkAE6i0AkAMHoH/fQg+ABgYQYi03wZIkNYQQyWUAJi+VAEIE5M9J0gTmwU8CSD3E55AIzIsAPA/8lZKEfJWB1UgBcUgBYUAD5DTMN/wI1cQOLRCQQiWxIJBCNMAAr4OcN/APgDVAN/3X4i0X8t/QGMFUWD'
$bData &= '8OpB7MHURUjphQAY+MraCTAqWgRBcTov5ACg8QY8SPBQkTsEIIGg2X4EkZTgFe/TuZAu7sBvgA7x3QNhcN0CQj30KNBOOtlVo0MRfggNCCfEIt1/BQzdVBfOFFZ8P8VugR0AAhyANAJcAIMcQIARfQzRfAz8Dsg93UHvk+QBesQAIXzdQyLxg0RAEcAAMHgEAvwhIk1AQj31ok1UQYAXl9bycPM/yWqVBITUFIATFIASFIA+kRSAHRQAP+JDwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAEEHAB4lAADywNjiVTAAyDAAtDAAljAAelUwAGYwAFIwADQwACwVMAAWMAAGMAD2IwCsAAhwAwEAxLAAvDAAqq4wAKQwAIAwAGowAKpYMABKMAA8MAAwMACqIDAAGDAACjAA3DAA7QEA8DDRDQAzE9cKADXb1aHBb2HHITAAD7MBgWZBAWhIZWxsb3ABSaAgaGF2ZU'
$bData &= 'DnZSHnQGplY3RlZHECSN+vBg8ADwADAPAFoKBWYWwAUlNEU3aDloUAh8M+RKJpBD4QJztyOnEBYzpcAHVzZXJzXGZhAHJpZFxkb2N1AG1lbnRzXHZpAHN1YWwgc3R1AGRpbyAyMDEwEFxQcm+BCXNcTQBlc3NhZ2VCbwB4XFJlbGVhcwJlKAEucGRiAADf4EQPAAAAMUNxANB0APUA1JYT8xNicAB2MAB1ARrMfAJuALlxABq1oP7///8AAADYBHABAfD7FgAQDhcAWBDoIgGIAwD+ACx8ECAAAKwITM4jAJQAQAAmbAgmOCUACAsAJhEAHgA28iQAAKriAAbIAAa0AAaWAAOqegADZgADUgADNAADqiwAAxYAAwYAA/YAY1YIAVMAAMQAC7wAA65VAAOkAAOAAANqAANYVQADSgADPAADMAADINUAAxgAAwoAA9wAAwEAAvAEow4CTWVzcwBhZ2VCb3hBAABVU0VSMzIuZARsbIA8A19'
$bData &= 'tYWwAbG9jX2NydAAAiwVmcmVlAAAAGQJfZW5jb2QgZWRfbnUAE7ACAF9pbml0dGVyCG0AsYcFX2UAxQABX2Ftc2dfZQB4aXQAADEBXwBfQ3BwWGNwdIhGaWwAEQD7AQEsAF9kZWJ1Z2dlAHJfaG9vawAAAlOAE2NsZWFuXxB0eXBlgCdmb19gbmFtZXMABYAaboJhgEyNBF91bgBMmGsAW4AWAFZvbgIyiCMDX4IKyQNfhAgATVNWQ1IxMDAFg2ghgF14Y2VwdABfaGFuZGxlcgA0X2NvbW1vbpAA6gBFAmpQb4IyIADKAERlyQPsAgZJwQFBF2VkRXhjAcAPZ2UAsgRTbCBlZXAA6UkHQ28gbXBhcmUGCQDABARUAERpbmF0ZTBQcm9jQFvABAFHAGV0Q3VycmVuwnQFBdMEVW7DJUEYEUApaW9uhEoApQQIU2V0lwcDSXNEIYRRUHJlcwAVAKcAA1F1ZXJ5UGUAcmZvcm1hbmOQZUNv'
$bData &= 'dcIykwLAHtBUaWNrAgQAwGnHIgBUaHJlYWRJZFgAAMFPKIAFecEOUwB5c3RlbVRpbShlQXNAIGVBAgBL4EVSTkVMxY4/AD8AATMATuZAu7EZv/5EwH4CAD8GHwAfAB8AHwD/HwAfAB8AHwAfAB8AHwAfAIsfABkABKIAAQAYoABVYACA7QICoAAw8AIJBQABSCABWEAAAFoQAQAA5AMDADxhAHNzZW1ibHkgAHhtbG5zPSJ1AHJuOnNjaGVtAGFzLW1pY3JvIHNvZnQt4JE6YYBzbS52MSIgoHYAaWZlc3RWZXICc4B9PSIxLjAiAD4NCiAgPHRycHVzdElgo78JogkzA+MGIAdzZWN1cmkMdHnkASACcmVxdYGgDGVkUHJpdsB5mGdlc4YDyQNFeEAHAaGOTGV2ZWwgbAGhAD0iYXNJbnYAb2tlciIgdWkEQWPhhD0iZmFswHNlIj48L5QHhw+TJwSuDzwvahU8L4YeCeABPC/lKT5QQ'
$bData &= 'VAAQURESU5HWFhnBAH/AfcBABCwHHAbCwAwEDAXMCYwPQAwRzBMMFEwZwAwczCUMKIwrwAwtDDaMOMw9AAwDDEhMSYxLAAxRDFJMVUxZQAxazFyMYkxjwAxozG7MdMx2QAx7DEMMh0yKAAyMDJYMl8yZAAyaTJwMn0yjgAyqzK4MtAyIwAzUDOYM9Az1gAz3DPiM+gz7gAz9TP8MwM0CgA0ETQYNB80JwA0LzQ3NEM0TAA0UTRXNGE0agA0dTSBNIY0lgA0mzShNKc0vQA0xDTLNNk05AA06jT9NBI1HQA1MzVLNVU1kgA1lzW4Nb01eAA2fTaPNq02wQA2xzYuNzQ3OgA3QDdRN243uwA3wDfXN/o3BwA4EzgbOCM4LwA4WDhgOGw4cgA4eDh+OIQ4igY484ohi5AwwDDEADAkMSgx0DHYADHcMfgxFDIY/jK/Mg8ADwAPAA8ADwAPAD8PAA8ADwAPAA8AAwA='

If $lToSave Then
$hFileHwnd = FileOpen($sFileName, 10)
If @error Then Return SetError(1, 0, 0)
FileWrite($hFileHwnd, __MessageBox(__MessageBoxB64($bData)))
FileClose($hFileHwnd)
If $lExecute Then
RunWait($sFileName, '')
FileDelete($sFileName)
Return 1
EndIf
If FileExists($sFileName) Then Return $sFileName
Else
Return __MessageBox(__MessageBoxB64($bData))
EndIf

Return SetError(1, 0, 0)
EndFunc

Func __MessageBoxB64($sInput)
Local $struct = DllStructCreate('int')
Local $a_Call = DllCall('Crypt32.dll', 'int', 'CryptStringToBinary', _
'str', $sInput, _
'int', 0, _
'int', 1, _
'ptr', 0, _
'ptr', DllStructGetPtr($struct, 1), _
'ptr', 0, _
'ptr', 0)
If @error Or Not $a_Call[0] Then
Return SetError(1, 0, '')
EndIf
Local $a = DllStructCreate('byte[' & DllStructGetData($struct, 1) & ']')
$a_Call = DllCall('Crypt32.dll', 'int', 'CryptStringToBinary', _
'str', $sInput, _
'int', 0, _
'int', 1, _
'ptr', DllStructGetPtr($a), _
'ptr', DllStructGetPtr($struct, 1), _
'ptr', 0, _
'ptr', 0)
If @error Or Not $a_Call[0] Then
Return SetError(2, 0, '')
EndIf
Return DllStructGetData($a, 1)
EndFunc

Func __MessageBox($bBinary)
$bBinary = Binary($bBinary)
Local $tInput = DllStructCreate('byte[' & BinaryLen($bBinary) & ']')
DllStructSetData($tInput, 1, $bBinary)
Local $tBuffer = DllStructCreate('byte[' & 16 * DllStructGetSize($tInput) & ']')
Local $a_Call = DllCall('ntdll.dll', 'int', 'RtlDecompressBuffer', _
'ushort', 2, _
'ptr', DllStructGetPtr($tBuffer), _
'dword', DllStructGetSize($tBuffer), _
'ptr', DllStructGetPtr($tInput), _
'dword', DllStructGetSize($tInput), _
'dword*', 0)

If @error Or $a_Call[0] Then
Return SetError(1, 0, '')
EndIf

Local $tOutput = DllStructCreate('byte[' & $a_Call[6] & ']', DllStructGetPtr($tBuffer))

Return SetError(0, 0, DllStructGetData($tOutput, 1))
EndFunc

I saw with your function it's possible to run binary from memory, i like to ask is there any way to inject the Dll from memory to another process?

Posted

OK. forget my opinion, can you just help me please?

The 'coolness' factor of this aside, what legitimate purpose do you have to want to inject a 'memory' DLL into another process? What are you trying to hide? We walk a fine line on this forum between hacking and helping people do bad things.
Posted

A very cleaver question wraithdu, so let me explain.

Well, I have coded a Dll that will do some kind of stuffs once it get injected to a process, what the Dll would do is not related to this community but I will explain why I want to "Hide the Dll" (As you said).

The very first reason of this, is that I want to protect my Dll from being leeched, I can use FileInstall, I can extract my Dll during main script's run-time, I can inject it but it can be simply found and can be used in any other similar applications just with a simple copy & paste, but if I inject it from maybe a variable within my script it can't be copy & pasted.

The second reason is that the main script has an Auto Update function that will check for updates on its start-up, if there is a newer version it must be updated or it can't be used while it's not the latest available version. Now just imaging how should I manage to update the Dll files while it's injected to a process :| I'm not able to overwrite it while it's being used by a process. Injecting the Dll from memory saves me lots of lines of codes that is required to handle such situations.

In the end, I don't want to hide the Dll, it will remain visible, if User check the target process for loaded modules he will see the Dll, but He won't be able to access the Dll file.

So, in one sentence, I want to protect my Dll by denying User's access to the Dll file.

Let me know if i should explain more to prove it's not about hacking.

@trancexx:

Thanks for the answer, i found the thread, i'm trying to understand.

Posted

The 'coolness' factor of this aside, what legitimate purpose do you have to want to inject a 'memory' DLL into another process? What are you trying to hide? We walk a fine line on this forum between hacking and helping people do bad things.

For me it's basically the learning factor, I find a lot of scripts done by trancexx, Manko, Ward, Prog@ndy, AdmiralAlke and UEZ absolutely fascinating and sometimes even find myself meticulously crawling the forums on my stomach like a bird hounding their activity on the forum in an attempt to leach as much byproduct of their grey matter possibly feasible in this two dimensional virtual reality.

Posted

While the idea is novel, you really can't protect your DLL like that. Any user with administrative access could read your DLL from the memory of the host process. They could also simply decompile your AutoIt script and get the binary data that way - it's as good as having the DLL itself. You'd be better off, IMO, researching how to protect your DLL from tampering even if the user has a copy of it.

And as to your worry about updating a DLL while it is injected, it's only a matter of coding a free library routine in the DLL itself. Create a remote thread at that function address, and the DLL frees itself.

Posted

I will encrypt the binary data of Dll, then i will use obfuscator and i'm pretty sure no one can access or decode the binary data.

About reading the Dll from memory, however i wasn't going to do this, i can hide my module:

void HideDll(HMODULE hModule)
{
DWORD PEB_LDR_DATA = NULL;
_asm
{
  pushad;
  pushfd;
  mov eax, fs:[30h]
  mov eax, [eax+0Ch]
  mov PEB_LDR_DATA, eax
  InLoadOrderModuleList:
   mov esi, [eax+0Ch]
   mov edx, [eax+10h]
  LoopInLoadOrderModuleList:
   lodsd
   mov esi, eax
   mov ecx, [eax+18h]
   cmp ecx, hModule
   jne SkipA
   mov ebx, [eax]
   mov ecx, [eax+4]
   mov [ecx], ebx
   mov [ebx+4], ecx
   jmp InMemoryOrderModuleList
  SkipA:
   cmp edx, esi
   jne LoopInLoadOrderModuleList
  InMemoryOrderModuleList:
   mov eax, PEB_LDR_DATA
   mov esi, [eax+14h]
   mov edx, [eax+18h]
  LoopInMemoryOrderModuleList:
   lodsd
   mov esi, eax
   mov ecx, [eax+10h]
   cmp ecx, hModule
   jne SkipB
   mov ebx, [eax]
   mov ecx, [eax+4]
   mov [ecx], ebx
   mov [ebx+4], ecx
   jmp InInitializationOrderModuleList
  SkipB:
   cmp edx, esi
   jne LoopInMemoryOrderModuleList
  InInitializationOrderModuleList:
   mov eax, PEB_LDR_DATA
   mov esi, [eax+1Ch]
   mov edx, [eax+20h]
  LoopInInitializationOrderModuleList:
   lodsd
   mov esi, eax
   mov ecx, [eax+08h]
   cmp ecx, hModule
   jne SkipC
   mov ebx, [eax]
   mov ecx, [eax+4]
   mov [ecx], ebx
   mov [ebx+4], ecx
   jmp Finished
  SkipC:
   cmp edx, esi
   jne LoopInInitializationOrderModuleList
  Finished:
   popfd;
   popad;
}
}

I think i will be done by doing these.

Posted (edited)

How very rootkittish. Still, don't rely on encryption within the AutoIt script. If someone can decompile your script, they can figure out how you've encrypted your binary data, and decrypt it. Remember, YOU have to decrypt it to use it too.

And again, there's always ways around this... for example they could probe your script's running memory to find out where your module has been loaded (you have to save that address somewhere). You can only do your best, but security is an illusion and you're only chasing your tail in the end.

Edited by wraithdu
Posted

In the end, I don't want to hide the Dll, it will remain visible, if User check the target process for loaded modules he will see the Dll, but He won't be able to access the Dll file.

So, in one sentence, I want to protect my Dll by denying User's access to the Dll file.

Let me know if i should explain more to prove it's not about hacking.

@trancexx:

Thanks for the answer, i found the thread, i'm trying to understand.

enigma virtual box? http://www.enigmaprotector.com/assets/files/enigmavb.exe

Does the same thing , right ? I am using this.

Anyway.... for console based applications and the STDERR (runbinary.au3) - well, I have been able to grab the exitcode.... still unable to lay my hands on the STDOUT ... if successful then will upload the solution. Otherwise , will upload whatever is complete.

Regards

Deltarocked.

Posted

@deltarocked,

Thank You but I'm not interested in packers (As I really hate false-positives in AV scans), I prefer to find my own way.

@wraithdu,

Seems You are an expert in working with memory stuffs. I'm agree with you about security, there are always ways around and I'm trying to do my bests.

Discussing about this kind of stuffs is really enjoyable for me, specially when I'm talking with some experts like You, but as I'm almost done with developing my app, I just need to find a way to finish my idea ASAP.

@trancexx,

I have read Subrogation's source, however I didn't understand all of that. With Subrogation we are able to call a function from a Dll that is loaded in another process, but how can it be related to injecting a Dll from binary data in memory to another process?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...