Below is code for a simple utility .dll injector i've been playing with. The injection portion is the simple injection code presented by hipy001 in this thread  with a few minor changes and the addition of code for getting the PID for use in the injection code from hipy001.
Works in Vista 32 bit. I've only tested with non-native windows processes which are running with admin permissions. I have not tested with x64 or XP, and although I have Windows 7 installed on another drive i've not tested with Windows 7.
Code: Select all
Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Procedure GetPidByName(p_name$) 
    Protected hDLL.i, process_name$ 
    Protected PEntry.PROCESSENTRY32, hTool32.i 
    Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot 
    Protected pProcess32First.PFNProcess32First 
    Protected pProcess32Next.PFNProcess32Next 
    Protected pid.i 
    
    hDLL = OpenLibrary(#PB_Any,"kernel32.dll") 
    
    If hDLL 
        pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot") 
        pProcess32First = GetFunction(hDLL,"Process32First") 
        pProcess32Next = GetFunction(hDLL,"Process32Next") 
    Else 
        ProcedureReturn 0 
    EndIf 
    
    PEntry\dwSize = SizeOf(PROCESSENTRY32) 
    hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0) 
    pProcess32First(hTool32, @PEntry) 
    process_name$ = Space(#MAX_PATH) 
    CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH) 
    
    If  UCase(process_name$) = UCase(p_name$) 
        ProcedureReturn PEntry\th32ProcessID 
    EndIf 
    
    While pProcess32Next(hTool32, @PEntry) > 0 
        process_name$ = Space(#MAX_PATH) 
        CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH) 
        
        If  UCase(process_name$) = UCase(p_name$) 
            ProcedureReturn PEntry\th32ProcessID 
        EndIf 
    
    Wend 
    
    CloseLibrary(hDLL) 
    
    ProcedureReturn 0 
EndProcedure
Procedure InjectLibA(dwProcessId.i, pszLibFile$) 
  hProcess.i 
  hThread.i 
  lzLibFileRemote.i 
  lSize.i 
  endSize.i 
  lsThreadRtn.i 
  
  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId) 
  
  If hProcess = 0 : Goto ErrHandle : EndIf 
  lSize = 1 + Len(pszLibFile$) 
  endSize = lSize 
  
  lzLibFileRemote = VirtualAllocEx_(hProcess, #Null, endSize, #MEM_COMMIT, #PAGE_READWRITE) 
  
  If lzLibFileRemote = 0 : Goto ErrHandle : EndIf 
  
  If (WriteProcessMemory_(hProcess, lzLibFileRemote, pszLibFile$, endSize, #Null) = 0) : Goto ErrHandle : EndIf 
  
  OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0) 
  
  If lsThreadRtn = 0 : Goto ErrHandle : EndIf 
  
  hThread = CreateRemoteThread_(hProcess, #Null, #Null, lsThreadRtn, lzLibFileRemote, #Null, #Null) 
  
  If (hThread = 0) : Goto ErrHandle : EndIf 
  
  WaitForSingleObject_(hThread, #INFINITE) 
  
  If lzLibFileRemote<>0 
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE) 
    MessageRequester("Inject Status", "Injection Suceeded", 0)
    Else
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE) 
    MessageRequester("Inject Status", "Injection Failed !!!", 0)
  EndIf 
  End 
  
  ErrHandle: 
      CloseHandle_(hThread) 
      CloseHandle_(hProcess) 
EndProcedure
Input_proc$ = InputRequester("Simple DLL injector", "Please enter target process name (.exe):", "") ;enter process name i.e...notepad.exe
val_pid.i = GetPidByName(Input_proc$)
Delay(10)
File_dll$ = OpenFileRequester("Choose .dll file to inject", "C:\", "DLL File (*.dll)|*.dll;*.dll", 0)
Delay(10)
InjectLibA(val_pid, File_dll$)
Maybe adding something to browse and select the running process instead of manually entering a process .exe name would make it more user friendly but this is OK just to play around with. And...if you wanted to use Srod's fine COMate you can get the PID (and other information about the process). I used the above because its been sort of one of my staples...but here is a COMate version for use with the injector code:
Code: Select all
XIncludeFile "COMate.pbi"
Procedure Proces_Now(p_name$)
Define.COMateObject objWMIService, objProcess
colProcessList.COMateEnumObject
strComputer.s = "."
objWMIService = COMate_GetObject("winmgmts:{impersonationLevel=impersonate}!\\" + strComputer + "\root\cimv2")
If objWMIService
  colProcessList = objWMIService\CreateEnumeration("ExecQuery('Select * from Win32_Process')")
  
  If colProcessList
    objProcess = colProcessList\GetNextObject()
    While objProcess
    
    Process_name$ = objProcess\GetStringProperty("Name")
    Process_Id$ = Str(objProcess\GetIntegerProperty("ProcessId"))
    Process_handle$ = Str(objProcess\GetIntegerProperty("Handle"))
    Executable_Path$ = objProcess\GetStringProperty("ExecutablePath")
        
    If  UCase(Process_name$) = UCase(p_name$)
    Process_name_PID.i = Val(Process_Id$)  
    EndIf
        
      objProcess\Release()
      objProcess = colProcessList\GetNextObject()
    Wend
    colProcessList\Release()
  EndIf
  objWMIService\Release()
Else
  MessageRequester("Error", "ProcInfo")
EndIf
ProcedureReturn Process_name_PID
EndProcedure
Procedure InjectLibA(dwProcessId.i, pszLibFile$) 
  hProcess.i 
  hThread.i 
  lzLibFileRemote.i 
  lSize.i 
  endSize.i 
  lsThreadRtn.i 
  
  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId) 
  
  If hProcess = 0 : Goto ErrHandle : EndIf 
  lSize = 1 + Len(pszLibFile$) 
  endSize = lSize 
  
  lzLibFileRemote = VirtualAllocEx_(hProcess, #Null, endSize, #MEM_COMMIT, #PAGE_READWRITE) 
  
  If lzLibFileRemote = 0 : Goto ErrHandle : EndIf 
  
  If (WriteProcessMemory_(hProcess, lzLibFileRemote, pszLibFile$, endSize, #Null) = 0) : Goto ErrHandle : EndIf 
  
  OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0) 
  
  If lsThreadRtn = 0 : Goto ErrHandle : EndIf 
  
  hThread = CreateRemoteThread_(hProcess, #Null, #Null, lsThreadRtn, lzLibFileRemote, #Null, #Null) 
  
  If (hThread = 0) : Goto ErrHandle : EndIf 
  
  WaitForSingleObject_(hThread, #INFINITE) 
  
  If lzLibFileRemote<>0 
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE) 
    MessageRequester("Inject Status", "Injection Suceeded", 0)
    Else
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE) 
    MessageRequester("Inject Status", "Injection Failed !!!", 0)
  EndIf 
  End 
  
  ErrHandle: 
      CloseHandle_(hThread) 
      CloseHandle_(hProcess) 
EndProcedure
Input_proc$ = InputRequester("Simple Utility Injector", "Please enter target process name (.exe):", "")
val_pid.i = Proces_Now(Input_proc$)
Delay(10)
File_dll$ = OpenFileRequester("Choose .dll file to inject", "C:\", "DLL File (*.dll)|*.dll;*.dll", 0)
Delay(10)
InjectLibA(val_pid, File_dll$)
I'm going to use COMate in a more advanced version of an injector tool.