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
