Sign in to follow this  
Followers 0

CreateProcessEx - Run and Inject a Dll

7 posts in this topic

#1 ·  Posted (edited)

Here is what I wrote recently for one of my own projects, a function to run a program with suspend flag, inject our own module into it and resume the target process with the loaded module.

CreateProcessEx:

Func CreateProcessEx(Const $sExecutablePath, Const $sDllPath, Const $sCommandLine = '', Const $sWorkingDirectory = 0)
If Not FileExists($sDllPath) Then Return SetError(1, 0, False)
Local $tagSTARTUPINFO = DllStructCreate( _
   'DWORD cb;' & _
   '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 cbReserved2;' & _
   'ptr Reserved2;' & _
   'HANDLE StdInput;' & _
   'HANDLE StdOutput;' & _
   'HANDLE StdError')
Local Const $tagPROCESS_INFORMATION = DllStructCreate( _
   'HANDLE hProcess;' & _
   'HANDLE hThread;' & _
   'DWORD ProcessId;' & _
   'DWORD ThreadId')
DllStructSetData($tagSTARTUPINFO, 'cb', DllStructGetSize($tagSTARTUPINFO))
Local $sWorkingDirectoryType = 'ptr'
If $sWorkingDirectory Then $sWorkingDirectoryType = 'str'
Local Const $bCreateProcess = DllCall('kernel32.dll', 'BOOL', 'CreateProcess', _
   'str', $sExecutablePath, _
   'str', $sCommandLine, _
   'ptr', 0, _
   'ptr', 0, _
   'BOOL', False, _
   'DWORD', 0x00000004, _ ;CREATE_SUSPENDED
   'ptr', 0, _
   $sWorkingDirectoryType, $sWorkingDirectory, _
   'struct*', $tagSTARTUPINFO, _
   'struct*', $tagPROCESS_INFORMATION)
If @error Or $bCreateProcess[0] = 0 Then Return SetError(2, 0, False)
$tagSTARTUPINFO = 0
Local Const $pRemoteAddress = DllCall('kernel32.dll', 'ptr', 'VirtualAllocEx', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
   'ptr', 0, _
   'int', 1, _
   'DWORD', 0x00001000, _ ;MEM_COMMIT
   'DWORD', 0x04) ;PAGE_READWRITE
If @error Or $pRemoteAddress[0] = 0 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(3, 0, False)
EndIf
Local Const $tagBuffer = DllStructCreate('CHAR[' & StringLen($sDllPath) & ']')
DllStructSetData($tagBuffer, 1, $sDllPath)
Local Const $bWPM = DllCall('kernel32.dll', 'BOOL', 'WriteProcessMemory', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
   'ptr', $pRemoteAddress[0], _
   'struct*', $tagBuffer, _
   'int', StringLen($sDllPath), _
   'int*', 0)
If @error Or $bWPM[0] = 0 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(4, 0, False)
EndIf
Local Const $hKernel32 = DllCall('kernel32.dll', 'HANDLE', 'GetModuleHandle', _
   'str', 'kernel32.dll')
If @error Or $hKernel32[0] = 0 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(5, 0, False)
EndIf
Local Const $pLoadLibraryA = DllCall('kernel32.dll', 'DWORD', 'GetProcAddress', _
   'HANDLE', $hKernel32[0], _
   'str', 'LoadLibraryA')
If @error Or $pLoadLibraryA[0] = 0 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(6, 0, False)
EndIf
Local Const $hRemoteThread = DllCall('kernel32.dll', 'HANDLE', 'CreateRemoteThread', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
   'ptr', 0, _
   'int', 0, _
   'DWORD', $pLoadLibraryA[0], _
   'ptr', $pRemoteAddress[0], _
   'DWORD', 0, _
   'DWORD*', 0)
If @error Or $hRemoteThread[0] = 0 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(7, 0, False)
EndIf
Local Const $dwEvent = DllCall('kernel32.dll', 'DWORD', 'WaitForSingleObject', _
   'HANDLE', $hRemoteThread[0], _
   'DWORD', 0xFFFFFFFF) ;INFINITE
If @error Or $dwEvent[0] <> 0x00000000 Then ;WAIT_OBJECT_0
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(8, 0, False)
EndIf
DllCall('kernel32.dll', 'BOOL', 'CloseHandle', _
   'HANDLE', $hRemoteThread[0])
Local Const $bVirtualFreeEx = DllCall('kernel32.dll', 'BOOL', 'VirtualFreeEx', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
   'ptr', $pRemoteAddress[0], _
   'int', 0, _
   'DWORD', 0x8000) ;MEM_RELEASE
If @error Or $bVirtualFreeEx[0] = 0 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(9, 0, False)
EndIf
Local Const $dwResumeThread = DllCall('kernel32.dll', 'DWORD', 'ResumeThread', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hThread'))
If @error Or $dwResumeThread[0] = -1 Then
  DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
    'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
    'DWORD', 0)
  Return SetError(10, 0, False)
EndIf
DllCall('kernel32.dll', 'BOOL', 'CloseHandle', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hThread'))
DllCall('kernel32.dll', 'BOOL', 'CloseHandle', _
   'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'))
Return SetError(0, 0, DllStructGetData($tagPROCESS_INFORMATION, 'ProcessId'))
EndFunc

Tested on Windows 7 32-bit and everything goes well, would be nice if anyone give it a try on Windows XP as well.

Example of usage:

CreateProcessEx(@WindowsDir & '\notepad.exe', _
  @ScriptDir & '\MessageBox.dll')
If @error Then MsgBox(16, 'CreateProcessEx', 'Error Value:' & @TAB & @error)

And here is a simple Dll that you may need for testing, it will show a MessageBox once it gets injected.

Edited by D4RKON3

I felt in love with AutoItObject [and the new Map type!].

Share this post


Link to post
Share on other sites



#2 ·  Posted

This is pretty good!

Finally I can fix one of my old scripts where the injection sometimes came to late to of any use.

Only problem I can see so far is a lack of parameter to set the working directory, you have to have that in a function that start programs!

It was a quick fix using Null, and after that I could aswell remove DllStructGetPtr()s since I'm now guaranteed to be using a version of AutoIt after struct type was added.

Here's my mod:

Func CreateProcessEx(Const $sExecutablePath, Const $sDllPath, Const $sCommandLine = '', Const $vWorkingDir = Null)
    If Not FileExists($sDllPath) Then Return SetError(1, 0, False)
    Local $tagSTARTUPINFO = DllStructCreate( _
            'DWORD cb;' & _
            '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 cbReserved2;' & _
            'ptr Reserved2;' & _
            'HANDLE StdInput;' & _
            'HANDLE StdOutput;' & _
            'HANDLE StdError')
    Local Const $tagPROCESS_INFORMATION = DllStructCreate( _
            'HANDLE hProcess;' & _
            'HANDLE hThread;' & _
            'DWORD ProcessId;' & _
            'DWORD ThreadId')
    DllStructSetData($tagSTARTUPINFO, 'cb', DllStructGetSize($tagSTARTUPINFO))
    Local Const $bCreateProcess = DllCall('kernel32.dll', 'BOOL', 'CreateProcess', _
            'str', $sExecutablePath, _
            'str', $sCommandLine, _
            'ptr', 0, _
            'ptr', 0, _
            'BOOL', False, _
            'DWORD', 0x00000004, _ ;CREATE_SUSPENDED
            'ptr', 0, _
            'str', $vWorkingDir, _
            'struct*', $tagSTARTUPINFO, _
            'struct*', $tagPROCESS_INFORMATION)
    If @error Or $bCreateProcess[0] = 0 Then Return SetError(2, 0, False)
    $tagSTARTUPINFO = 0
    Local Const $pRemoteAddress = DllCall('kernel32.dll', 'ptr', 'VirtualAllocEx', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
            'ptr', 0, _
            'int', 1, _
            'DWORD', 0x00001000, _ ;MEM_COMMIT
            'DWORD', 0x04) ;PAGE_READWRITE
    If @error Or $pRemoteAddress[0] = 0 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(3, 0, False)
    EndIf
    Local Const $tagBuffer = DllStructCreate('CHAR[' & StringLen($sDllPath) & ']')
    DllStructSetData($tagBuffer, 1, $sDllPath)
    Local Const $bWPM = DllCall('kernel32.dll', 'BOOL', 'WriteProcessMemory', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
            'ptr', $pRemoteAddress[0], _
            'struct*', $tagBuffer, _
            'int', StringLen($sDllPath), _
            'int*', 0)
    If @error Or $bWPM[0] = 0 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(4, 0, False)
    EndIf
    Local Const $hKernel32 = DllCall('kernel32.dll', 'HANDLE', 'GetModuleHandle', _
            'str', 'kernel32.dll')
    If @error Or $hKernel32[0] = 0 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(5, 0, False)
    EndIf
    Local Const $pLoadLibraryA = DllCall('kernel32.dll', 'DWORD', 'GetProcAddress', _
            'HANDLE', $hKernel32[0], _
            'str', 'LoadLibraryA')
    If @error Or $pLoadLibraryA[0] = 0 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(6, 0, False)
    EndIf
    Local Const $hRemoteThread = DllCall('kernel32.dll', 'HANDLE', 'CreateRemoteThread', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
            'ptr', 0, _
            'int', 0, _
            'DWORD', $pLoadLibraryA[0], _
            'ptr', $pRemoteAddress[0], _
            'DWORD', 0, _
            'DWORD*', 0)
    If @error Or $hRemoteThread[0] = 0 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(7, 0, False)
    EndIf
    Local Const $dwEvent = DllCall('kernel32.dll', 'DWORD', 'WaitForSingleObject', _
            'HANDLE', $hRemoteThread[0], _
            'DWORD', 0xFFFFFFFF) ;INFINITE
    If @error Or $dwEvent[0] <> 0x00000000 Then ;WAIT_OBJECT_0
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(8, 0, False)
    EndIf
    DllCall('kernel32.dll', 'BOOL', 'CloseHandle', _
            'HANDLE', $hRemoteThread[0])
    Local Const $bVirtualFreeEx = DllCall('kernel32.dll', 'BOOL', 'VirtualFreeEx', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
            'ptr', $pRemoteAddress[0], _
            'int', 0, _
            'DWORD', 0x8000) ;MEM_RELEASE
    If @error Or $bVirtualFreeEx[0] = 0 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(9, 0, False)
    EndIf
    Local Const $dwResumeThread = DllCall('kernel32.dll', 'DWORD', 'ResumeThread', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hThread'))
    If @error Or $dwResumeThread[0] = -1 Then
        DllCall('kernel32.dll', 'BOOL', 'TerminateProcess', _
                'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'), _
                'DWORD', 0)
        Return SetError(10, 0, False)
    EndIf
    DllCall('kernel32.dll', 'BOOL', 'CloseHandle', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hThread'))
    DllCall('kernel32.dll', 'BOOL', 'CloseHandle', _
            'HANDLE', DllStructGetData($tagPROCESS_INFORMATION, 'hProcess'))
    Return SetError(0, 0, DllStructGetData($tagPROCESS_INFORMATION, 'ProcessId'))
EndFunc   ;==>CreateProcessEx

Share this post


Link to post
Share on other sites

#3 ·  Posted

First post updated.

- Using struct* instead of DllStructGetPtr.

- Added support of WorkingDirectory as parameter.


I felt in love with AutoItObject [and the new Map type!].

Share this post


Link to post
Share on other sites

#4 ·  Posted

Getting an error when running it on Win7 x64 -> em: 7

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#5 ·  Posted

CreateRemoteThread fails.

I'm not sure why, try to compile the script as x64 and let me know if it still fail.


I felt in love with AutoItObject [and the new Map type!].

Share this post


Link to post
Share on other sites

#6 ·  Posted

Running it as x64 it is running but no message box appears.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#7 ·  Posted

XP SP3 Pro: Failed @error = 2

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0