Seite 1 von 1

Spiele-Trainer (Speicher-Manipulator)

Verfasst: 02.06.2008 22:14
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

Re: Spiele-Trainer (Speicher-Manipulator)

Verfasst: 02.06.2008 22:29
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...)

Re: Spiele-Trainer (Speicher-Manipulator)

Verfasst: 03.06.2008 13:53
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>

Verfasst: 19.06.2008 12:26
von Kai
Falscher Thread :mrgreen:

Re: Spiele-Trainer (Speicher-Manipulator)

Verfasst: 19.06.2008 12:45
von DrShrek
Kaeru Gaman hat geschrieben:(ich pichel auch grad Weizen, also prostata...)
Müsste das nicht 'pissel' heissen?

Verfasst: 19.06.2008 13:21
von hardfalcon
Welcher weiße Löwe? Ich da irgendwie grad voll aufm Schlauch... :?

Verfasst: 19.06.2008 13:40
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