Option Explicit
Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" ( _
ByVal dwFlags As Long, _
ByVal th32ProcessID As Long _
) As Long
'dwFlags
Public Const TH32CS_INHERIT = &H80000000
Public Const TH32CS_SNAPHEAPLIST = &H1
Public Const TH32CS_SNAPMODULE = &H8
Public Const TH32CS_SNAPPROCESS = &H2
Public Const TH32CS_SNAPTHREAD = &H4
Public Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or _
TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Public Const INVALID_HANDLE_VALUE = -1&
'------------------------------------------------------------------
Public Const MAX_PATH = 260
Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile(1 To MAX_PATH) As Byte
End Type
Public Declare Function Process32First Lib "kernel32" ( _
ByVal hSnapshot As Long, _
lppe As PROCESSENTRY32 _
) As Boolean
Public Declare Function Process32Next Lib "kernel32" ( _
ByVal hSnapshot As Long, _
lppe As PROCESSENTRY32 _
) As Boolean
'------------------------------------------------------------------
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const SYNCHRONIZE = &H100000
Public Const PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)
Public Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long _
) As Long
'------------------------------------------------------------------
Public Declare Function VirtualAllocEx Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal flAllocationType As Long, _
ByVal flProtect As Long _
) As Long
'Allocation Types
Public Const MEM_COMMIT = &H1000
Public Const MEM_RESERVE = &H2000
Public Const MEM_RESET = &H80000
Public Const MEM_TOP_DOWN = &H100000
'memory protection
Public Const PAGE_NOACCESS = &H1
Public Const PAGE_READONLY = &H2
Public Const PAGE_READWRITE = &H4
Public Const PAGE_WRITECOPY = &H8
Public Const PAGE_EXECUTE = &H10
Public Const PAGE_EXECUTE_READ = &H20
Public Const PAGE_EXECUTE_READWRITE = &H40
Public Const PAGE_EXECUTE_WRITECOPY = &H80
Public Const PAGE_GUARD = &H100
Public Const PAGE_NOCACHE = &H200
Public Const PAGE_WRITECOMBINE = &H400
'------------------------------------------------------------------
Public Declare Function WriteProcessMemory Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpBaseAddress As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
lpNumberOfBytesWritten As Long _
) As Long
'------------------------------------------------------------------
Public Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Public Declare Function CreateRemoteThread Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpThreadAttributes As Long, _
ByVal dwStackSize As Long, _
ByVal lpStartAddress As Long, _
ByVal lpParameter As Long, _
ByVal dwCreationFlags As Long, _
lpThreadId As Long _
) As Long
'------------------------------------------------------------------
Public Declare Function GetProcAddress Lib "kernel32" ( _
ByVal hModule As Long, _
ByVal lpProcName As String _
) As Long
Public Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" ( _
ByVal lpModuleName As String _
) As Long
Public Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long _
) As Long
'-------------------------------------------------------------------------
' used for GetAPIErrorText
Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200
Private Declare Function GetLastError Lib "kernel32" () As Long
Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _
ByVal dwFlags As Long, _
lpSource As Any, _
ByVal dwMessageId As Long, _
ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
Arguments As Long _
) As Long
Public Function InjectDLL(szTarget As String, szdlltoinject As String) As Boolean
Dim still_injected As Boolean
Dim isInjected As Boolean
Dim result As Long
Dim hSnapshot As Long, hModule As Long, hProcess As Long, hThread As Long
Dim PE32 As PROCESSENTRY32
isInjected = False
still_injected = False
PE32.dwSize = Len(PE32)
'Take a snapshot of all processes in the system.
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
If hSnapshot = INVALID_HANDLE_VALUE Then
Debug.Print "CreateToolhelp32Snapshot Error: "; GetAPIErrorText(GetLastError)
InjectDLL = False
Exit Function
End If
'Retrieve information about the first process encountered in the system snapshot.
If Process32First(hSnapshot, PE32) = False Then
Debug.Print "Process32First Error: "; GetAPIErrorText(GetLastError)
GoTo ExitOnError
End If
Do 'walk the snapshot of processes to find our target
'If executable file name of process matches our target’s name then...
If StrFromByteArray(PE32.szExeFile) = szTarget Then
If isInjected Then 'If already injected don’t do again
still_injected = True
Else
'open an existing process object.
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, PE32.th32ProcessID)
If hProcess = 0 Then
Debug.Print "OpenProcess Error: "; GetAPIErrorText(GetLastError)
GoTo ExitOnError
End If
Debug.Print "Process Handle: "; Hex(hProcess)
'Commit a region of memory within the virtual address space of the specified process.
hModule = VirtualAllocEx(hProcess, 0, Len(szdlltoinject), MEM_COMMIT, _
PAGE_EXECUTE_READWRITE)
If hModule = 0 Then
Debug.Print "VirtualAllocEx Error: "; GetAPIErrorText(GetLastError)
GoTo ExitOnError
End If
Debug.Print "Virtual Allocation: "; Hex(hModule)
'writes name of dll to an area of memory in the process.
result = WriteProcessMemory(hProcess, hModule, szdlltoinject, _
Len(szdlltoinject), ByVal 0)
If result = 0 Then
Debug.Print "WriteProcessMemory Error: "; GetAPIErrorText(GetLastError)
GoTo ExitOnError
End If
Debug.Print "Write Process Memory: "; result
'create a thread that runs in the virtual address space of the other process.
hThread = CreateRemoteThread(hProcess, 0, 0, GetProcAddress(GetModuleHandle("kernel32"), _
"LoadLibraryA"), hModule, 0, ByVal 0)
If hThread = 0 Then
Debug.Print "CreateRemoteThread Error: "; GetAPIErrorText(GetLastError)
GoTo ExitOnError
End If
'This Runs LoadLibraryA with parameter hModule(pointer to name of dll) in the
'other process which in turn, maps the specified DLL file into the address space
'of the calling process.
isInjected = True
still_injected = True
End If
Exit Do 'found our target
End If 'end if found target
'Retrieve information about the next process recorded in the system snapshot.
Loop While (Process32Next(hSnapshot, PE32))
Debug.Print "Process32Next Error: "; GetAPIErrorText(GetLastError)
GoTo ExitOnError
'if our target wasn't found, then isinjected=false
ExitOnError:
Call CloseHandle(hProcess)
InjectDLL = isInjected
End Function
Public Function StrFromByteArray(bArray() As Byte) As String
Dim i As Integer
Dim x As String
x = ""
For i = 1 To MAX_PATH
If bArray(i) = 0 Then Exit For
x = x & Chr(bArray(i))
Next i
StrFromByteArray = x
End Function
'Return the text of the API error denoted by lError
Public Function GetAPIErrorText(ByVal lError As Long) As String
Dim sOut As String
Dim sMsg As String
Dim lret As Long
GetAPIErrorText = ""
sMsg = String(256, 0)
lret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, _
0&, lError, 0&, sMsg, Len(sMsg), 0&)
sOut = lError & " (&H" & Hex(lError) & "): "
If lret <> 0 Then
sMsg = Trim(sMsg)
If Right(sMsg, 2) = vbCrLf Then sMsg = Left(sMsg, Len(sMsg) - 2)
sOut = sOut & Trim(sMsg)
Else
sOut = sOut & "<no such error> "
End If
GetAPIErrorText = sOut
End Function