Simple: 'DLL injection'

Share your advanced PureBasic knowledge/code with the community.
hipy001
New User
New User
Posts: 5
Joined: Tue May 26, 2009 3:25 pm

Simple: 'DLL injection'

Post by hipy001 »

Injecting a DLL into Another Process's

Code: Select all

Procedure InjectLibA(dwProcessId.l, pszLibFile$)
  hProcess.l
  hThread.l
  lzLibFileRemote.l
  lSize.l
  endSize.l
  lsThreadRtn.l
  
  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("Hi", "Hi", 0)
  EndIf
  End
  
  ErrHandle:
      CloseHandle_(hThread)
      CloseHandle_(hProcess)
EndProcedure

InjectLibA('PiD - > ' 3680, "C:\test.dll")
cas
Enthusiast
Enthusiast
Posts: 597
Joined: Mon Nov 03, 2008 9:56 pm

Post by cas »

Is there any practical use of this?
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Simple: 'DLL injection'

Post by PB »

Got an example on what you'd use this for?
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

Read the contents of a pwd textbox! :P

Just the example sited by wikipedia

http://en.wikipedia.org/wiki/DLL_injection

I think this breaks on Vista and above anyway due to Address Space Layout Randomization or (ASLR)
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

nah, it works in Vista but just not in all cases.
Last edited by SFSxOI on Mon Jun 01, 2009 1:57 pm, edited 2 times in total.
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

sounds reliable :P
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
hipy001
New User
New User
Posts: 5
Joined: Tue May 26, 2009 3:25 pm

Post by hipy001 »

works And Windows 7.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

you injecting into games?
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

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.
User avatar
Michael Vogel
Addict
Addict
Posts: 2677
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Simple: 'DLL injection'

Post by Michael Vogel »

PB wrote:Got an example on what you'd use this for?
Would this routine allow to do the following:

I have an old windows game named Civ2 which uses obviously the PeekMessageA function for checking messages. The result is a high CPU load for the whole time, the game is played.

What about doing a hack to inject(?) a modified PeekMessageA routine which does not use that high amount of CPU load into the civ2.exe?

Thanks,
Michael
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: Simple: 'DLL injection'

Post by SFSxOI »

Michael Vogel wrote:
PB wrote:Got an example on what you'd use this for?
Would this routine allow to do the following:

I have an old windows game named Civ2 which uses obviously the PeekMessageA function for checking messages. The result is a high CPU load for the whole time, the game is played.

What about doing a hack to inject(?) a modified PeekMessageA routine which does not use that high amount of CPU load into the civ2.exe?

Thanks,
Michael
Yep, you can do that. I borrowed a game from a friend who's out of town right now to experiment with this on, Call of Duty 4, and I injected a game cheat I found on the 'net just to see if everything would work and if it was possible to do 'modifications' to things, worked like a charm. I even created a small dll that toggles a memory location in the game and turns the mini-map on and off. So i'm sure you could do your PeekMessageA thing if you simply found the memory location of it and bypassed by NOop'ong it out and then directing to your own.
User avatar
Michael Vogel
Addict
Addict
Posts: 2677
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Simple: 'DLL injection'

Post by Michael Vogel »

SFSxOI wrote:[...]So i'm sure you could do your PeekMessageA thing if you simply found the memory location of it and bypassed by NOop'ong it out and then directing to your own.[...]
Oooh :shock:
I've to search the memory for the opcode? :evil: Sounds not that easy for me, I thought it acts like catching a certain call :oops:

So this is the first "solution", which works fine - maybe there's also a way to replace the CPUThrottle.dll by a Purebasic made one (I have no idea what's inside the dll which I have downloaded from the internet :evil:)

Code: Select all

PID.i=GetPidByName("ntvdm.exe")
If PID
	InjectLibA(PID,"CPUThrottle.dll")
Else
	MessageRequester("Achtung!","CIV does not run!")
EndIf
Michael
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Very basically from the way I understand it, leading to the way I did it experimentally; you NO'op the one function (PeekMessageA in your case) by placing the NOOP code 90's in the command line then you have a jump to your function and when the function use is finished it returns back to where the main program picks up again originally where it would have continued if the PeekMessageA was still in place . Or....you replace the original function with a jump to your routine so the original function is bypassed and do it all again. Or....I guess that if you just did not want the PeekMessageA to work at all you could just NOOP it and leave it at that.

I don't really do games myself and had just borrowed the COD 4 to have something else to experiment with. But while searching around for ways to do this I came across this > http://www.codeproject.com/KB/cpp/codecave.aspx < which explains it all pretty much using something called Code Caves. And also this one > http://www.codeproject.com/KB/cpp/funccaller.aspx
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Simple: 'DLL injection'

Post by Lunasole »

Here is some update of @SFSxOI utility (slightly modified for unicode support + few "cosmetic" changes).
I wondered if it will work on Win7 or newer, but it worked fine :mrgreen:

Code: Select all

EnableExplicit

Procedure GetPidByName(p_name$) 
	Protected process_name$ 
	Protected PEntry.PROCESSENTRY32
	Protected hTool32, pid
	
	PEntry\dwSize = SizeOf(PROCESSENTRY32) 
	hTool32 = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0) 
	p_name$ = UCase(p_name$) 
	
	Process32First_(hTool32, @PEntry) 
	process_name$ = Space(#MAX_PATH) 
	CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH) 
	
	If UCase(process_name$) = p_name$
		pid = PEntry\th32ProcessID 
	Else
		While Process32Next_(hTool32, @PEntry) > 0 
			process_name$ = Space(#MAX_PATH) 
			CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH) 
			If UCase(process_name$) = p_name$
				pid = PEntry\th32ProcessID
				Break
			EndIf 
		Wend     
	EndIf 
	CloseHandle_(hTool32)
	
	ProcedureReturn pid
EndProcedure

; This one injects library to a target process
; Both DLL and process must be unicode
; For ASCII: change LoadLibraryW > LoadLibraryA, and modify strings related to pszLibFile$
Procedure InjectLibW(dwProcessId, pszLibFile$) 
	Protected hProcess, hThread, lzLibFileRemote, endSize, lsThreadRtn
	
	hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId) 
	
	If hProcess = 0 : Goto ErrHandle : EndIf 
	endSize = 1 + StringByteLength(pszLibFile$) 
	
	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, "LoadLibraryW") : 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


;------------------------------------
Define Input_proc$ = InputRequester("Simple DLL injector", "Please enter target process name (.exe):", "") ;enter process name i.e...notepad.exe
Define val_pid = GetPidByName(Input_proc$)
Define File_dll$

Delay(10)
If val_pid
	File_dll$ = OpenFileRequester("Choose .dll file to inject", "C:\", "DLL File (*.dll)|*.dll;*.dll", 0)
	Delay(10)
	InjectLibW(val_pid, File_dll$)
Else
	MessageRequester("Inject Status", "val_pid = 0", 0)
EndIf
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Opcode
Enthusiast
Enthusiast
Posts: 137
Joined: Thu Jul 18, 2013 4:58 am

Re: Simple: 'DLL injection'

Post by Opcode »

Lunasole wrote:Here is some update of @SFSxOI utility (slightly modified for unicode support + few "cosmetic" changes).
I wondered if it will work on Win7 or newer, but it worked fine :mrgreen:

Code: Select all

- snip -
Works fine on Windows 10 x64 with PB 5.31 in both unicode and ascii with a simple compiler if statement. Here's my quick tidy and edit with a few improvements.

Code: Select all

EnableExplicit

Procedure GetPidByName(pName.s)
  
  Protected.s processName.s = Space(#MAX_PATH)
  Protected pEntry.PROCESSENTRY32
  Protected.i hTool32, pId
  
  pEntry\dwSize = SizeOf(PROCESSENTRY32)
  hTool32 = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
  pName = UCase(pName)
  
  Process32First_(hTool32, @pEntry)
  CopyMemory(@pEntry\szExeFile, @processName, #MAX_PATH)
  
  If UCase(processName) = pName
    pId = pEntry\th32ProcessID
  Else
    While Process32Next_(hTool32, @pEntry) > 0
      CopyMemory(@pEntry\szExeFile, @processName, #MAX_PATH)
      If UCase(processName) = pName
        pId = PEntry\th32ProcessID
        Break
      EndIf
    Wend
  EndIf
  
  CloseHandle_(hTool32)
  
  ProcedureReturn pId
  
EndProcedure

; Inject Library To A Target Process
; Both DLL And Process Must Be Unicode
; For ASCII: Change LoadLibraryW > LoadLibraryA And Modify Strings Related To pszLibFile
Procedure LoadLibrary(dwProcessId.i, pszLibFile.s)
  
  Protected.i hProcess, hThread, lzLibFileRemote, endSize, lsThreadRtn
  
  hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId)
  
  If hProcess = 0 : Goto ErrHandle : EndIf
  endSize = 1 + StringByteLength(pszLibFile)
  
  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
  
  CompilerIf #PB_Compiler_Unicode
    OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryW") : CloseLibrary(0) 
  CompilerElse
    OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0) 
  CompilerEndIf
  
  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!", #MB_ICONINFORMATION)
  Else
    VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
    MessageRequester("Inject Status", "Injection Failed!", #MB_ICONERROR)
  EndIf
  End
  
  ErrHandle:
  CloseHandle_(hThread)
  CloseHandle_(hProcess)
  
EndProcedure

; ----- Main Program -----

CompilerIf #PB_Compiler_IsMainFile
  
  Define.s nDLL, procName = InputRequester("Simple DLL Injector", "Enter Target Process Name (*.exe):", "")
  Define.i pId = GetPidByName(procName)
  
  If pId
    nDLL = OpenFileRequester("Choose DLL File To Inject", "C:\", "DLL File (*.dll)|*.dll;*.dll", 0)
    LoadLibrary(pId, nDLL)
  Else
    MessageRequester("Error", "Process ID Not Found!", #MB_ICONERROR)
  EndIf
  
CompilerEndIf
Post Reply