Sign in to follow this  
Followers 0

CreateProcessEx - Run and Inject a Dll

7 posts in this topic

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

Share this post


Link to post
Share on other sites



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

Posted

First post updated.

- Using struct* instead of DllStructGetPtr.

- Added support of WorkingDirectory as parameter.

Share this post


Link to post
Share on other sites

Posted

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

Br,

UEZ

Share this post


Link to post
Share on other sites

Posted

CreateRemoteThread fails.

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

Share this post


Link to post
Share on other sites

Posted

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

Br,

UEZ

Share this post


Link to post
Share on other sites

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

  • Recently Browsing   0 members

    No registered users viewing this page.