Alle .l Typendefinitionen sollten durch .i ausgetauscht werden. Einige Sachen werden dennoch nicht unter x64 laufen, wie z.B. die DLL-Injection.
Code: Alles auswählen
;/-------------------------\
;| N.E.T. Trainer-Engine |
;| |
;| Version 0.01 |
;| 22.05.2007 |
;| |
;| PureBasic 4.02 |
;| |
;| Requires: min. Win2000 |
;\-------------------------/
EnableExplicit
;Windows-Konstanten
#THREAD_ALL_ACCESS = $1F03FF
;Trainer-Engine-Konstanten
#TypeCode = 1
#TypeData = 2
Macro ArrayIndex(Array)
PeekL(Array-8)-1
EndMacro
;/-------------------\
;|LowLevel-Prozeduren|
;\-------------------/
;Ermittelt die ID des Hauptthreads des Zielprozesses.
Procedure.l GetThreadID(ProcessID.l)
Define.l hSnapshot,RetVal
Define.THREADENTRY32 ThreadInfo
ThreadInfo\dwSize = SizeOf(ThreadInfo)
hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD,0)
If hSnapshot <> 0
RetVal = Thread32First_(hSnapshot,@ThreadInfo)
If RetVal <> 0
If ThreadInfo\th32OwnerProcessID = ProcessID
CloseHandle_(hSnapshot)
ProcedureReturn ThreadInfo\th32ThreadID
EndIf
Repeat
RetVal = Thread32Next_(hSnapshot,@ThreadInfo)
If RetVal = 0
Break
Else
If ThreadInfo\th32OwnerProcessID = ProcessID
CloseHandle_(hSnapshot)
ProcedureReturn ThreadInfo\th32ThreadID
EndIf
EndIf
Until RetVal = 0
CloseHandle_(hSnapshot)
EndIf
EndIf
ProcedureReturn 0
EndProcedure
;Öffnet einen Thread und gibt das Handle zurück, ab Windows 2000.
Procedure.l OpenThread(ThreadID.l)
Define.l hKernel32,hThread
hKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
hThread = CallFunction(hKernel32,"OpenThread",#THREAD_ALL_ACCESS,0,ThreadID)
ProcedureReturn hThread
EndProcedure
;Öffnet den Zielprozess und gibt den Handle zurück
Procedure.l OpenProcess(ProcessID.l)
Define.l hProcess
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS,0,ProcessID)
ProcedureReturn hProcess
EndProcedure
;Allokiert Speicher im Zielprozess und gibt die Adresse zurück.
;Type ist der Typ der Binärdaten: 1=Code 2=Daten
Procedure.l RemoteAllocMem(hProcess.l,Size.l,Type.b)
Define.l RegionAddr,PageAccess
If Type = 1
PageAccess = #PAGE_EXECUTE_READWRITE
Else
PageAccess = #PAGE_READWRITE
EndIf
RegionAddr = VirtualAllocEx_(hProcess,0,Size,#MEM_COMMIT | #MEM_RESERVE,PageAccess)
If RegionAddr = 0
ProcedureReturn 0
EndIf
ProcedureReturn RegionAddr
EndProcedure
;Schreibt Daten in den Zielprozess.
Procedure.l RemoteWriteMem(hProcess.l,DestAddr.l,SrcAddr.l,SrcLen.l)
Define.l BytesWritten
If WriteProcessMemory_(hProcess,DestAddr,SrcAddr,SrcLen,@BytesWritten) = 0
ProcedureReturn 0
EndIf
If BytesWritten <> SrcLen
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
;/-------------------\
;|MidLevel-Prozeduren|
;\-------------------/
;Hält die Programmausführung des Zielprozesses an.
Procedure.l FreezProcess(ProcessID.l)
Define.l ThreadID,hThread,RetVal,hKernel32
;ID des Hauptthreads des Zielprozesses ermitteln
ThreadID = GetThreadID(ProcessID)
If ThreadID = 0
ProcedureReturn 0
EndIf
;Öffnen des Threads
hThread = OpenThread(ThreadID)
If hThread = 0
ProcedureReturn 0
EndIf
;Anhalten des Threads
SuspendThread_(hThread)
CloseHandle_(hThread)
ProcedureReturn 1
EndProcedure
;Lässt die Programmausführung des Zielprozess wieder weiterlaufen.
Procedure.l UnFreezProcess(ProcessID.l)
Define.l ThreadID,hThread,RetVal,hKernel32
;ID des Hauptthreads des Zielprozesses ermitteln
ThreadID = GetThreadID(ProcessID)
If ThreadID = 0
ProcedureReturn 0
EndIf
;Öffnen des Threads (minimum Win2000)
hThread = OpenThread(ThreadID)
If hThread = 0
ProcedureReturn 0
EndIf
;Fortsetzen des Threads
ResumeThread_(hThread)
CloseHandle_(hThread)
ProcedureReturn 1
EndProcedure
;Injiziert Code oder Daten in den Zielprozess und gibt die Adresse zurück
;Type ist der Typ der Binärdaten: 1=Code 2=Daten
Procedure.l InjectBinary(hTarget.l,BinData.l,BinDataLen.l,Type.b)
Define.l BinDataAddr,BytesWritten,PageAccess
;Speicher für Code im Zielprozess allokieren
BinDataAddr = RemoteAllocMem(hTarget,BinDataLen,Type)
If BinDataAddr = 0
ProcedureReturn
EndIf
;Code in den Speicher des Zielprozesses schreiben
If RemoteWriteMem(hTarget,BinDataAddr,BinData,BinDataLen) = 0
ProcedureReturn 0
EndIf
ProcedureReturn BinDataAddr
EndProcedure
;Ruft eine Prozedur im Zielprocess auf und übergibt ihr einen Parameter.
Procedure.l RemoteCallProcOneParamThread(hProcess.l,ProcAddr.l,Param.l,Wait.b)
Define.l hThread
;Prozedur ausführen indem ein Thread im Zielprozess erzeugt wird
hThread.l = CreateRemoteThread_(hProcess,0,0,ProcAddr,Param, 0, 0)
If hThread = 0
ProcedureReturn 0
EndIf
;falls erwünscht warten bis der Thread beendet ist
If Wait = 1
WaitForSingleObject_(hThread,#INFINITE)
EndIf
ProcedureReturn 1
EndProcedure
;Ruft eine Prozedur im Zielprocess auf und übergibt ihr eine beliebige Anzahl Parameter.
Procedure.l RemoteCallProcManyParamsThread(hProcess.l,ProcAddr.l,Params.l(1),Wait.b)
Define.l i,Position,ParamsCnt,hThread,BytesWritten,ProcCallAddr,CodeBuffer,CodeLen
ParamsCnt = ArrayIndex(Params())
;Codelänge berechnen und entsprechen Speicher allokieren für die Codegenerierung
CodeLen = ParamsCnt + 1
CodeLen * 5
CodeLen + 8
CodeBuffer = AllocateMemory(CodeLen)
;Parameter-Pushen generieren: push const
For i = ParamsCnt To 0 Step -1
PokeB(CodeBuffer + Position,$68)
Position + 1
PokeL(CodeBuffer + Position,Params(i))
Position + 4
Next
;Prozeduraufruf generieren: mov eax,const : call eax
PokeB(CodeBuffer + Position,$B8)
Position + 1
PokeL(CodeBuffer + Position,ProcAddr)
Position + 4
PokeW(CodeBuffer + Position,$D0FF)
Position + 2
;Rücksprung generieren: ret
PokeB(CodeBuffer + Position,$C3)
Position + 1
;Code in den Zielprozess injizieren
ProcCallAddr = InjectBinary(hProcess,CodeBuffer,CodeLen,#TypeCode)
;Speicher für Codegenerierung wieder freigeben
FreeMemory(CodeBuffer)
;Code ausführen indem ein Thread im Zielprozess erzeugt wird
hThread = CreateRemoteThread_(hProcess,0,0,ProcCallAddr,0, 0, 0)
If hThread = 0
ProcedureReturn 0
EndIf
;falls erwünscht warten bis der Thread beendet ist
If Wait = 1
WaitForSingleObject_(hThread,#INFINITE)
VirtualFreeEx_(hProcess,ProcCallAddr,0,#MEM_RELEASE)
EndIf
ProcedureReturn 1
EndProcedure
;/------------------\
;|HiLevel-Prozeduren|
;\------------------/
;Sucht den Zielprozess mittels des Fenstertitels und gibt die ProcessID zurück.
Procedure.l FindTargetByWndTitle(WndTitle.s)
Define.l PID
GetWindowThreadProcessId_(FindWindow_(0,WndTitle),@PID)
ProcedureReturn PID
EndProcedure
;Sucht den Zielprozess mittels des Prozessnamens und gibt die ProcessID zurück.
Procedure.l FindTargetByPrcName(PrcName.s)
Define.l hSnapshot,RetVal
Define.PROCESSENTRY32 ProcessInfo
PrcName = LCase(PrcName)
ProcessInfo\dwSize = SizeOf(ProcessInfo)
hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL, 0)
If hSnapshot <> 0
RetVal = Process32First_(hSnapshot, @ProcessInfo)
If RetVal <> 0
If LCase(PeekS(@ProcessInfo\szExeFile)) = PrcName
CloseHandle_(hSnapshot)
ProcedureReturn ProcessInfo\th32ProcessID
EndIf
Repeat
RetVal = Process32Next_(hSnapshot, @ProcessInfo)
If RetVal = 0
Break
Else
If LCase(PeekS(@ProcessInfo\szExeFile)) = PrcName
CloseHandle_(hSnapshot)
ProcedureReturn ProcessInfo\th32ProcessID
EndIf
EndIf
Until RetVal = 0
CloseHandle_(hSnapshot)
EndIf
EndIf
ProcedureReturn 0
EndProcedure
;Sucht den Zielprozess mittels einer Signatur im Prozessspeicher und gibt die ProcessID zurück.
Procedure.l FindTargetBySignature(SigAddr.l,SigLen.l,Sig.l)
Define.l hSnapshot,hProcess,RetVal,SigBuffer,BytesRead
Define.PROCESSENTRY32 ProcessInfo
SigBuffer = AllocateMemory(SigLen)
ProcessInfo\dwSize = SizeOf(ProcessInfo)
hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL, 0)
If hSnapshot <> 0
RetVal = Process32First_(hSnapshot, @ProcessInfo)
If RetVal <> 0
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS,0,ProcessInfo\th32ProcessID)
ReadProcessMemory_(hProcess,SigAddr,SigBuffer,SigLen,@BytesRead)
If CompareMemory(Sig,SigBuffer,SigLen) = 1
CloseHandle_(hSnapshot)
CloseHandle_(hProcess)
FreeMemory(SigBuffer)
ProcedureReturn ProcessInfo\th32ProcessID
EndIf
Repeat
RetVal = Process32Next_(hSnapshot, @ProcessInfo)
If RetVal = 0
Break
Else
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS,0,ProcessInfo\th32ProcessID)
ReadProcessMemory_(hProcess,SigAddr,SigBuffer,SigLen,@BytesRead)
If CompareMemory(Sig,SigBuffer,SigLen) = 1
CloseHandle_(hSnapshot)
CloseHandle_(hProcess)
FreeMemory(SigBuffer)
ProcedureReturn ProcessInfo\th32ProcessID
EndIf
EndIf
Until RetVal = 0
CloseHandle_(hSnapshot)
FreeMemory(SigBuffer)
EndIf
EndIf
ProcedureReturn 0
EndProcedure
;Injiziert eine DLL in den Zielprozess.
Procedure.l InjectDLLThread(hProcess.l,DLLFileName.s)
Define.l FileNameLen,FileNameAddr,BytesWritten,hKernel32,LoadLibraryAAddr,hThread
;Dateiname der DLL in den Zielprozess schreiben
FileNameLen = Len(DLLFileName) + 1
FileNameAddr = VirtualAllocEx_(hProcess,0,FileNameLen,#MEM_COMMIT | #MEM_RESERVE,#PAGE_READWRITE)
If FileNameAddr = 0
ProcedureReturn 0
EndIf
If WriteProcessMemory_(hProcess,FileNameAddr,DLLFileName,FileNameLen,@BytesWritten) = 0
ProcedureReturn 0
EndIf
If BytesWritten <> FileNameLen
ProcedureReturn 0
EndIf
;Addresse von LoadLibraryA ermitteln
hKernel32 = GetModuleHandle_("Kernel32.dll")
If hKernel32 = 0
ProcedureReturn 0
EndIf
LoadLibraryAAddr = GetProcAddress_(hKernel32,"LoadLibraryA")
If LoadLibraryAAddr = 0
ProcedureReturn 0
EndIf
;Thread im Zielprozess erstellen um LoadLibraryA auszuführen
hThread = CreateRemoteThread_(hProcess,0,0,LoadLibraryAAddr,FileNameAddr, 0, 0)
If hThread = 0
ProcedureReturn 0
EndIf
;warten bis der Thread beendet ist und aufräumen
WaitForSingleObject_(hThread,#INFINITE)
VirtualFreeEx_(hProcess,FileNameAddr,0,#MEM_RELEASE)
ProcedureReturn 1
EndProcedure
;Injiziert eine DLL in den Zielprozess.
Procedure.l InjectDLL(hProcess.l,ProcessID.l,DLLFileName.s)
Define.l FileNameLen,FileNameAddr,CodeAddr,BytesWritten,hKernel32,LoadLibraryAAddr,CodeBuffer,Position,ThreadID,hThread
Define.CONTEXT ThreadContext
;Dateiname der DLL in den Zielprozess schreiben
FileNameLen = Len(DLLFileName) + 1
FileNameAddr = VirtualAllocEx_(hProcess,0,FileNameLen,#MEM_COMMIT | #MEM_RESERVE,#PAGE_READWRITE)
If FileNameAddr = 0
ProcedureReturn 0
EndIf
If WriteProcessMemory_(hProcess,FileNameAddr,DLLFileName,FileNameLen,@BytesWritten) = 0
ProcedureReturn 0
EndIf
If BytesWritten <> FileNameLen
ProcedureReturn 0
EndIf
;Addresse von LoadLibraryA ermitteln
hKernel32 = GetModuleHandle_("Kernel32.dll")
If hKernel32 = 0
ProcedureReturn 0
EndIf
LoadLibraryAAddr = GetProcAddress_(hKernel32,"LoadLibraryA")
If LoadLibraryAAddr = 0
ProcedureReturn 0
EndIf
;Speicher im Zielprozess für den Code allokieren
CodeAddr = VirtualAllocEx_(hProcess,0,22,#MEM_COMMIT | #MEM_RESERVE,#PAGE_EXECUTE_READWRITE)
;Speicher für die Codegenerierung allokieren
CodeBuffer = AllocateMemory(22)
;Zielprozess anhalten
If FreezProcess(ProcessID) = 0
VirtualFreeEx_(hProcess,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hProcess,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
ProcedureReturn 0
EndIf
;EIP-Register des Hauptthreads besorgen
idThread = GetThreadID(ProcessID)
hThread = OpenThread(ThreadID)
If hThread = 0
VirtualFreeEx_(hProcess,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hProcess,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
CloseHandle_(hThread)
UnFreezProcess(ProcessID)
ProcedureReturn 0
EndIf
ThreadContext\ContextFlags = #CONTEXT_CONTROL
If GetThreadContext_(hThread,@ThreadContext) = 0
VirtualFreeEx_(hProcess,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hProcess,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
CloseHandle_(hThread)
UnFreezProcess(ProcessID)
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_(hProcess,CodeAddr,CodeBuffer,22,@BytesWritten) = 0
VirtualFreeEx_(hProcess,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hProcess,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
CloseHandle_(hProcess)
UnFreezProcess(ProcessID)
ProcedureReturn 0
EndIf
If BytesWritten <> 22
VirtualFreeEx_(hProcess,FileNameAddr,0,#MEM_RELEASE)
VirtualFreeEx_(hProcess,CodeAddr,0,#MEM_RELEASE)
FreeMemory(CodeBuffer)
CloseHandle_(hThread)
UnFreezProcess(ProcessID)
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)
ProcedureReturn 1
EndProcedure