Spiele-Trainer (Speicher-Manipulator)

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Spiele-Trainer (Speicher-Manipulator)

Beitrag von Helle »

Da der kleine weisse Löwe mit Anfragen zum Lesen/Schreiben von (Programm-Internen) Speicherbereichen hier (und nicht nur hier) schon ganze Völkerstämme beschäftigt, hier mal ein simples Beispiel für einen sogenannten Spiele-Trainer. Soll nur eine Anregung sein!

Code: Alles auswählen

;- Einfacher Speicher-Manipulator ("Spiele-Trainer")
;- "Helle" Klaus Helbing, 02.06.2008, PB 4.20
;- Version 4.20 ist erforderlich für Val(Hex), sonst anpassen!
;- Getestet mit WinXP und dem "Test-Klassiker" winmine.exe
;- Für "winmine.exe" interessante Anfangs-Speicher-Adresse: $1005000 (Programm laufen lassen !"
;- Zum Ändern einfach auf die "Zelle" doppel-klicken (linke Maustaste) und schauen
;- Änderungen von Strings sind Zeit-Relevant!
;- Benutzung auf eigene Gefahr!

Global Rot.l
Global WindowID.l
Global Zeile.l
Global Spalte.l
Global GadgetNr.l
Global NeuWert.b
#NbProcessesMax = 10000
Global Dim ProcessesArray(#NbProcessesMax)

Procedure GetProcessList() 
  If OpenLibrary(0, "psapi.dll") 
    EnumProcesses = GetFunction(0, "EnumProcesses") 
    EnumProcessModules = GetFunction(0, "EnumProcessModules") 
    GetModuleBaseName = GetFunction(0, "GetModuleBaseNameA") 
 
    CallFunctionFast(EnumProcesses, ProcessesArray(), #NbProcessesMax, @nProcesses) 
        
    For k = 0 To nProcesses >> 2 
      hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, ProcessesArray(k)) 
      If hProcess 
        CallFunctionFast(EnumProcessModules, hProcess, @BaseModule, 4, @cbNeeded) 
        Prozess$ = Space(cbNeeded) 
        CallFunctionFast(GetModuleBaseName, hProcess, BaseModule, @Prozess$, cbNeeded) 
 
        If Len(Prozess$) <> 0     ;z.B. System
          AddGadgetItem(0, -1, Prozess$ + Chr(10) + Str(ProcessesArray(k))) 
        EndIf 
        CloseHandle_(hProcess) 
      EndIf 
    Next 
    CloseLibrary(0) 
  EndIf 
EndProcedure 

Procedure NotifyCallback(WindowID, Message, wParam, lParam)     ;für roten Text
  If Message = #WM_NOTIFY              ;nur WM_NOTIFY-Messages abfangen
    *TextColor.NMLVCUSTOMDRAW = lParam 
    If *TextColor\nmcd\hdr\hWndFrom = GadgetNr
      *pnmh.NMHDR = lParam
      If *pnmh\code = #NM_DBLCLK       ;Double-Click in Liste? 
        *lpnmitem.NMITEMACTIVATE = lParam 
        Zeile = *lpnmitem\iItem 
        Spalte = *lpnmitem\iSubItem 
      EndIf 
      Select *TextColor\nmcd\dwDrawStage
        Case #CDDS_PREPAINT
          ProcedureReturn #CDRF_NOTIFYITEMDRAW 
        Case #CDDS_ITEMPREPAINT                    
          ProcedureReturn #CDRF_NOTIFYSUBITEMDRAW 
        Case #CDDS_SUBITEM | #CDDS_ITEMPREPAINT
          If Rot  
            *TextColor\clrText = 255   ;rot
          EndIf 
      EndSelect 
    EndIf
   Else  
    ProcedureReturn #PB_ProcessPureBasicEvents   ;war nichts von Interesse, normal weiter
  EndIf 
EndProcedure 
 
WindowID = OpenWindow(0, 0, 0, 665, 520, "Auswahl des zu beobachtenden Programmes", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If WindowID And CreateGadgetList(WindowID(0))
  ;Structuren definieren
  MBI.MEMORY_BASIC_INFORMATION
  SysInfo.SYSTEM_INFO
       
  ButtonGadget(1, 0, 0, 0, 0, "Über den Explorer ein Programm auswählen und starten")
  ButtonGadget(2, 0, 0, 0, 0, "Ein bereits gestartetes Programm auswählen") 
  SplitterGadget(0, 10, 10, 645, 150, 1, 2, #PB_Splitter_Vertical | #PB_Splitter_Separator)

  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow
      End 
    EndIf   
  Until EventGadget() = 1 Or EventGadget() = 2 

  FreeGadget(0) : FreeGadget(1) : FreeGadget(2)   

  If EventGadget() = 1       ;Status bleibt auch nach FreeGadget() erhalten (hoffe ich!)
    ExplorerTreeGadget(0, 10, 10, 645, 485,"",#PB_Explorer_NoDriveRequester)
    Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_CloseWindow
        End 
      EndIf   
    Until EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(0) = #PB_Explorer_File
    File$ = GetGadgetText(0)
    ;Programm starten und Programm-Handle ermitteln
    hProgram = RunProgram(File$, "", GetCurrentDirectory(), #PB_Program_Open) 
    ;damit die Programm-ID ermitteln; ist die, die auch der Task-Manager anzeigt (variabel!!!)
    ProgID = ProgramID(hProgram) 
    File$ = GetFilePart(File$)    ;nur File-Name
   Else
    ListIconGadget(0, 10, 10, 645, 480, "Name", 345, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect) 
    AddGadgetColumn(0, 1, "ProgID", 300) 

    GetProcessList() 
  
    Repeat 
      File$ = GetGadgetItemText(0, GetGadgetState(0))
      ProgID = Val(GetGadgetItemText(0, GetGadgetState(0), 1))

      Event = WaitWindowEvent()
      If Event = #PB_Event_CloseWindow
        End
      EndIf   
    Until EventType() = #PB_EventType_LeftDoubleClick Or Event = #PB_Event_CloseWindow
  EndIf 

  FreeGadget(0)

  SetWindowTitle(0, "Assoziierte Speicherbereiche für " + File$) 

  ListIconGadget(0, 10, 10, 645, 485, "Start-Adresse", 125, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
  AddGadgetColumn(0, 1, "End-Adresse", 125)
  AddGadgetColumn(0, 2, "Grösse", 125)
  AddGadgetColumn(0, 3, "Status", 215)

  GetSystemInfo_(SysInfo)    ;Ermittlung des für Programme zur Verfügung stehenden Speichers
  MinAdr = SysInfo\lpMinimumApplicationAddress
  MaxAdr = SysInfo\lpMaximumApplicationAddress

  ;jetzt das Ganze für Vollzugriff öffnen
  ProcessHandle = OpenProcess_(#PROCESS_ALL_ACCESS, #False, ProgID)

  AnfAdresse = MinAdr
  Delay(1000)                ;Windows etwas Zeit zum Speicher-Organisieren geben
  Zeile = 0
  While AnfAdresse < MaxAdr  ;Speicher abklappern
    VirtualQueryEx_(ProcessHandle, AnfAdresse, MBI, SizeOf(MEMORY_BASIC_INFORMATION))
    Eigner = MBI\State
    Size = MBI\RegionSize
    Status = MBI\Protect
    If Eigner = #MEM_COMMIT  ;Test, ob Speicherbereich mit ausgewähltem Programm assoziiert ist
      BaseAdr = MBI\BaseAddress
      AddGadgetItem(0, -1, "")
      SetGadgetItemText(0, Zeile, "$" + Hex(BaseAdr), 0)
      EndAdr = BaseAdr + Size
      SetGadgetItemText(0, Zeile, "$" + Hex(EndAdr), 1)
      SetGadgetItemText(0, Zeile, "$" + Hex(Size), 2) 
      If Status = $1
        Status$ = "PAGE_NOACCESS"
       ElseIf Status = $2
        Status$ = "PAGE_READONLY"
       ElseIf Status = $4
        Status$ = "PAGE_READWRITE"    
       ElseIf Status = $8
        Status$ = "PAGE_WRITECOPY"     
       ElseIf Status = $10
        Status$ = "PAGE_EXECUTE"    
       ElseIf Status = $20
        Status$ = "PAGE_EXECUTE_READ"    
       ElseIf Status = $40
        Status$ = "PAGE_EXECUTE_READWRITE"    
       ElseIf Status = $80
        Status$ = "PAGE_EXECUTE_WRITECOPY"    
       ElseIf Status = $100
        Status$ = "PAGE_GUARD"   
       ElseIf Status = $200
        Status$ = "PAGE_NOCACHE" 
       ElseIf Status = $400
        Status$ = "PAGE_WRITECOMBINE"    
       Else
        Status$ = "Kombination"
      EndIf 
      SetGadgetItemText(0, Zeile, "$" + Hex(Status) + " = " + Status$ , 3)
      Status$ = ""
      Zeile + 1
    EndIf
    AnfAdresse + Size
    If AnfAdresse < 0        ;negativ!
      Break
    EndIf
  Wend  

  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_CloseWindow
      End
    EndIf    
  Until EventType() = #PB_EventType_LeftDoubleClick

  BaseAdr$ = GetGadgetItemText(0, GetGadgetState(0))
  BaseAdr = Val(BaseAdr$)
  EndAdr$ = GetGadgetItemText(0, GetGadgetState(0), 1)
  EndAdr = Val(EndAdr$)

  ;Buffer-Speicher anfordern ---
  Laenge = (EndAdr - BaseAdr)
  Buffer = AllocateMemory(Laenge)
  BufferS = AllocateMemory(Laenge)
  If Buffer = 0 Or BufferS = 0
    MessageRequester("Fehler !", "Der benötigte Speicher konnte nicht bereitgestellt werden !")
    End
  EndIf 
  ;-----------------------------
  FreeGadget(0)

  SetWindowTitle(0, "Anzeige Speicherbereich von " + BaseAdr$ +" bis " + EndAdr$ + " für " + File$) 
  GadgetNr = ListIconGadget(0, 10, 10, 645, 485, "Adresse", 75, #PB_ListIcon_GridLines | #LVS_NOSORTHEADER | #PB_ListIcon_FullRowSelect)
 
  For b = 1 To 16
    AddGadgetColumn(0, b, Hex(b-1), 34)
  Next
 
  ReadProcessMemory_(ProcessHandle, BaseAdr, Buffer, Laenge, 0)
  n = Laenge
  n >> 4
  n - 1
  For k = 0 To n
    For i = 0 To 15
      Test1$ + Chr(10) + RSet(Hex(PeekB(Buffer + z) & 255), 2, "0")
      z + 1
    Next 
    AddGadgetItem(0, -1, Hex(BaseAdr + k << 4) + Test1$)
    Test1$ = "" 
  Next   
  
  SetWindowCallback(@NotifyCallback(), 0)   ;aktuelle Änderungen im sichtbaren Bereich rot markieren    
  
  Repeat : Event = WindowEvent()  

    CopyMemory(Buffer, BufferS, Laenge)

    ReadProcessMemory_(ProcessHandle, BaseAdr, Buffer, Laenge, 0)
    z = 0
    n = Laenge-4
    n >> 4
    n - 1
    Rot = 0
     
    For k = 0 To n
      For i = 0 To 15
        If (PeekB(Buffer + z) & 255) <> (PeekB(BufferS + z) & 255)
          Wert$=RSet(Hex((PeekB(Buffer + z) & 255)), 2, "0") + "<"   ;"<" als Zeichen für verändert
          Rot = 255                              ;für NotifyCallback (<>0)
          SetGadgetItemText(0, k, Wert$, i + 1)  ;Wert$ soll rot ausgegeben werden
        EndIf 
        z + 1
      Next 
    Next   

    ;Test auf Ändern
    If Zeile <> OldZeile Or Spalte <> OldSpalte
      OldZeile = Zeile                 ;Zeile und Spalte von NotifyCallback
      OldSpalte = Spalte
      If Spalte > 0                    ;Adresse
        Adresse = BaseAdr + (Zeile << 4) + (Spalte - 1) 
        FreeGadget(5)
        TextGadget(1, 20, 500, 250, 15, "Ausgewählte Speicher-Adresse : $" + Hex(Adresse))
        TextGadget(2, 300, 500, 175, 15, "Aktueller Wert : $" + RSet(Hex(PeekB(Buffer + (Zeile << 4) + (Spalte - 1)) & 255), 2, "0")) 
        TextGadget(3, 480, 500, 100, 15, "Neuer Wert : ")
        TextGadget(4, 545, 500, 50, 15, "")
 
        NeuWert$ = "$"
        NoWrite = 0
        While Len(NeuWert$) < 3
          If GetAsyncKeyState_(#VK_RETURN) = -32767
            NoWrite = 1
            Break                      ;Abbruch mit Return
          EndIf
          For C = 48 To 57             ;Ziffern 0-9
            If GetAsyncKeyState_(C) = -32767
              NeuWert$ + Chr(C)
              SetGadgetText(4, NeuWert$)
            EndIf
          Next 
          For C = 65 To 70             ;Buchstaben A-F
            If GetAsyncKeyState_(C) = -32767
              NeuWert$ + Chr(C)
              SetGadgetText(4, NeuWert$)    ;pro Forma... und für Tests
            EndIf
          Next
        Wend     

        If NoWrite = 0
          NeuWert = Val(NeuWert$)
          VirtualProtectEx_(ProcessHandle, Adresse, 1, #PAGE_EXECUTE_READWRITE , @ProtectStatus)
          ;ordentlicherweise müsste der alte Protect-Status wiederhergestellt werden, aber liegt ja "nur" im Speicher...  
          If WriteProcessMemory_(ProcessHandle, Adresse, @NeuWert, 1, #Null) = 0
            MessageRequester("Fehler !", "Schreibvorgang war nicht erfolgreich !")
          EndIf 
          OldZeile = 0 : OldSpalte = 0 : Zeile = 0 : Spalte = 0 ;somit sofort wieder anwählbar
        EndIf  

        FreeGadget(1) : FreeGadget(2) : FreeGadget(3) : FreeGadget(4)
        TextGadget(5, 200, 500, 400, 15, "Zuletzt geschrieben : Wert " + NeuWert$ + " in Adresse $" + Hex(Adresse))
      EndIf 
    EndIf
    ;Delay(1)
  Until Event = #PB_Event_CloseWindow

  CloseWindow(0)
EndIf
Ich komme gerade vom Weissbier-Trinken, also bitte keine allzu herbe Kritik :mrgreen: !

Gruß
Helle
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: Spiele-Trainer (Speicher-Manipulator)

Beitrag von Kaeru Gaman »

Helle hat geschrieben:Da der kleine weisse Löwe mit Anfragen zum Lesen/Schreiben von (Programm-Internen) Speicherbereichen hier (und nicht nur hier) schon ganze Völkerstämme beschäftigt, hier mal ein simples Beispiel für einen sogenannten Spiele-Trainer.
schätze mal, damit hast du einen einfachen Simba sehr glücklich gemacht.... :mrgreen:
(ich pichel auch grad Weizen, also prostata...)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Mok
BotHunter
Beiträge: 1484
Registriert: 26.12.2005 14:14
Computerausstattung: MSI GX780R
Intel Core i5-2410M
Nvidia GT 555M
Windows 7 Home Premium 64 bit
Wohnort:   

Re: Spiele-Trainer (Speicher-Manipulator)

Beitrag von Mok »

Kaeru Gaman hat geschrieben:
Helle hat geschrieben:Da der kleine weisse Löwe mit Anfragen zum Lesen/Schreiben von (Programm-Internen) Speicherbereichen hier (und nicht nur hier) schon ganze Völkerstämme beschäftigt, hier mal ein simples Beispiel für einen sogenannten Spiele-Trainer.
schätze mal, damit hast du einen einfachen Simba sehr glücklich gemacht.... :mrgreen:
(ich pichel auch grad Weizen, also prostata...)
:mrgreen: :lol:

<ot> ich weiß, dass es otal unproduktiv war, aber es war lustig zu lesen^^ </ot>
Win 7 Home Premium 64 bit | PureBasic 5.20 - x86 und x86-64 | Firefox [aktuelle stable-Version hier einfügen]
"Jeder macht irgendwann mal Fehler, darum gibt's auch Bleistifte mit Radiergummi." --Carl
Benutzeravatar
Kai
Beiträge: 264
Registriert: 29.09.2005 20:58
Computerausstattung: iMac 2019
Wohnort: Hannover
Kontaktdaten:

Beitrag von Kai »

Falscher Thread :mrgreen:
Meine Homepage - Aktuelle Projekte - Launcher
Letzte PB-Version - Window 7 x86
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Re: Spiele-Trainer (Speicher-Manipulator)

Beitrag von DrShrek »

Kaeru Gaman hat geschrieben:(ich pichel auch grad Weizen, also prostata...)
Müsste das nicht 'pissel' heissen?
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Benutzeravatar
hardfalcon
Beiträge: 3447
Registriert: 29.08.2004 20:46

Beitrag von hardfalcon »

Welcher weiße Löwe? Ich da irgendwie grad voll aufm Schlauch... :?
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Hakuna Matata :mrgreen: ! Gemeint (aber von mir nicht böse) war whitelion, der ganz heftig mit Speicherstellen-Änderungen beschäftigt war.

Gruß
Helle
Antworten