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




