Re: Inhalt einer Speichaddresse auslesen
Verfasst: 24.02.2015 14:53
Hier ein alter Code von mir mit Kram den man so fürs Trainer schreiben braucht.
Alle .l Typendefinitionen sollten durch .i ausgetauscht werden. Einige Sachen werden dennoch nicht unter x64 laufen, wie z.B. die DLL-Injection.
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