Wenn ihr das testen wollt mit einer DLL, welche eine MessageBox ausgibt, dann vergesst nicht folgende Zeile am Ende auszukommentieren:
Code: Alles auswählen
VirtualFreeEx_(hTarget,CodeAddr,0,#MEM_RELEASE)
Wenn die Injektion geklappt hat gibt die Prozedur 1 zurück andernfalls 0.
Code: Alles auswählen
;Written by Thorium
;PureBasic 4.02 Code
EnableExplicit
#THREAD_ALL_ACCESS = $1F03FF
Procedure.l InjectDLL(idTarget.l,FileName.s)
Define.l FileNameLen,FileNameAddr,CodeAddr,BytesWritten,hKernel32,LoadLibraryAAddr,CodeBuffer,Position,idThread,hThread,hSnapshot,RetVal,LibKernel32,hTarget
Define.CONTEXT ThreadContext
Define.THREADENTRY32 ThreadInfo
;Zielprozess öffnen
hTarget = OpenProcess_(#PROCESS_ALL_ACCESS,0,IdTarget)
If hTarget = 0
ProcedureReturn 0
EndIf
;ID des Hauptthreads ermitteln
ThreadInfo\dwSize = SizeOf(ThreadInfo)
hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD,0)
If hSnapshot <> 0
RetVal = Thread32First_(hSnapshot,@ThreadInfo)
If RetVal <> 0
If ThreadInfo\th32OwnerProcessID = idTarget
idThread = ThreadInfo\th32ThreadID
Else
Repeat
RetVal = Thread32Next_(hSnapshot,@ThreadInfo)
If RetVal = 0
Break
Else
If ThreadInfo\th32OwnerProcessID = idTarget
idThread = ThreadInfo\th32ThreadID
Break
EndIf
EndIf
Until RetVal = 0
EndIf
CloseHandle_(hSnapshot)
EndIf
EndIf
If idThread = 0
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;Addresse von LoadLibraryA ermitteln
hKernel32 = GetModuleHandle_("Kernel32.dll")
If hKernel32 = 0
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
LoadLibraryAAddr = GetProcAddress_(hKernel32,"LoadLibraryA")
If LoadLibraryAAddr = 0
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;Thread öffnen
LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
hThread = CallFunction(LibKernel32,"OpenThread",#THREAD_ALL_ACCESS,0,idThread)
If hThread = 0
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;Dateiname der DLL in den Zielprozess schreiben
FileNameLen = Len(FileName) + 1
FileNameAddr = VirtualAllocEx_(hTarget,0,FileNameLen,#MEM_COMMIT | #MEM_RESERVE,#PAGE_READWRITE)
If FileNameAddr = 0
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
If WriteProcessMemory_(hTarget,FileNameAddr,FileName,FileNameLen,@BytesWritten) = 0
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
If BytesWritten <> FileNameLen
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;Speicher im Zielprozess für den Code allokieren
CodeAddr = VirtualAllocEx_(hTarget,0,22,#MEM_COMMIT | #MEM_RESERVE,#PAGE_EXECUTE_READWRITE)
If CodeAddr = 0
CloseHandle_(hThread)
VirtualFreeEx_(hTarget,FileNameAddr,0,#MEM_RELEASE)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;Speicher für die Codegenerierung allokieren
CodeBuffer = AllocateMemory(22)
;Hauptthread anhalten
If SuspendThread_(hThread) = -1
CloseHandle_(hThread)
VirtualFreeEx_(hTarget,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hTarget,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;EIP-Register des Hauptthreads besorgen
ThreadContext\ContextFlags = #CONTEXT_CONTROL
If GetThreadContext_(hThread,@ThreadContext) = 0
VirtualFreeEx_(hTarget,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hTarget,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
ResumeThread_(hThread)
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;Code generieren
PokeB(CodeBuffer,$68) ;push
Position + 1
PokeL(CodeBuffer + Position,ThreadContext\Eip)
Position + 4
PokeB(CodeBuffer + Position,$9C) ;pushfd
Position + 1
PokeB(CodeBuffer + Position,$60) ;pushad
Position + 1
PokeB(CodeBuffer + Position,$68) ;push
Position + 1
PokeL(CodeBuffer + Position,FileNameAddr)
Position + 4
PokeB(CodeBuffer + Position,$B8) ;mov eax,const
Position + 1
PokeL(CodeBuffer + Position,LoadLibraryAAddr)
Position + 4
PokeW(CodeBuffer + Position,$D0FF) ;call eax
Position + 2
PokeB(CodeBuffer + Position,$61) ;popad
Position + 1
PokeB(CodeBuffer + Position,$9D) ;popfd
Position + 1
PokeB(CodeBuffer + Position,$C3) ;ret
;Code in den Zielprozess schreiben
If WriteProcessMemory_(hTarget,CodeAddr,CodeBuffer,22,@BytesWritten) = 0
VirtualFreeEx_(hTarget,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hTarget,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
ResumeThread_(hThread)
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
If BytesWritten <> 22
VirtualFreeEx_(hTarget,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hTarget,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
ResumeThread_(hThread)
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 0
EndIf
;EIP-Register auf den Code setzen
ThreadContext\Eip = CodeAddr
ThreadContext\ContextFlags = #CONTEXT_CONTROL
SetThreadContext_(hThread,@ThreadContext)
;Zielprozess weiterlaufen lassen
ResumeThread_(hThread)
;Aufräumen
Delay(1000)
VirtualFreeEx_(hTarget,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hTarget,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
CloseHandle_(hThread)
CloseHandle_(hTarget)
ProcedureReturn 1
EndProcedure