Seite 1 von 2

Memory eines anderen Programms auslesen

Verfasst: 31.08.2006 23:42
von r0ulade
Hi
Ich versuche mit PB eine bestimmte Memory-Adresse eines anderen (aktuell laufenden) Programms in eine Variable zu kriegen.

Dachte mir zuerst, PeekS wäre mein Freund... aber dort kann ich ja nur auf mit AllocateMemory erstellte Memory-Bereiche zugreifen, nicht aber auf frei definierbare!

Zur Erklärung:
- Mit "RAM Cheat" (separates "Hilfs"-Programm) finde ich raus, welche Memory Adresse ich einlesen möchte, z.B. "0334CF8C".
- Dann möchte ich mit PB zwei Bytes ab dieser Adresse als ASCII/String einlesen.

Text$ = PeekS(0334CF8C, 4) klappt leider definitiv nicht :(

Bin dankbar für jeden noch so kleine Hinweis!

Verfasst: 31.08.2006 23:44
von ts-soft
>> klappt leider definitiv nicht
Du liest ja auch im virtuellem Speicher Deines Programms, nicht im Speicher
des anderen Programmes.

Verfasst: 01.09.2006 01:40
von Zaphod
Es gibt einen WinAPI befehl (an den ich micht grade nicht erinnere), mit dem du fremde Programme so starten kannst, dass du zugriff auf ihren Speicher hast, sonst ist das natürlich in einem modernen Betriebsystem vollkommen unmöglich. Da könnte ja sonst jeder prozess beliebig schaden anrichten.

Das ginge nur unter Windows 95/98/ME, aber nicht unter NT4/2K/XP.

Verfasst: 01.09.2006 15:38
von r0ulade
Zaphod hat geschrieben:Es gibt einen WinAPI befehl (an den ich micht grade nicht erinnere), mit dem du fremde Programme so starten kannst, dass du zugriff auf ihren Speicher hast
Das wäre ja vielleicht schon mal ein Anfang... weiss sonst noch jemand von diesem WinAPI-Befehl?
Zaphod hat geschrieben:, sonst ist das natürlich in einem modernen Betriebsystem vollkommen unmöglich. Da könnte ja sonst jeder prozess beliebig schaden anrichten.
Nun ja, es ginge mir ja eigentlich nur ums LESEN - das sollte doch nicht so gefährlich sein....!?

Verfasst: 01.09.2006 16:10
von Eric
zum Lesen gibt es ReadProcessMemory und zum Schreiben WriteProcessMemory.

Allerdings braucht man dazu ein Handle auf den Prozess (oder die ID um ein Handle zu erstellen)

Ich habe aber im Moment weder ein funktionierendes PB mit WinAPI und deshalb auch kein Beispiel.

Verfasst: 01.09.2006 18:15
von Thorium
Joa, Beispiel hab ich. Aus meinem Sacred Underworld BiInstancer. Der erlaubt es Sacred 2 mal zu starten. Ist recht simpel, sogar ohne den Code zu patchen. Es wird einfach der Mutexname gepatcht.

Hier wird der Process von Sacred geöffnet. Nicht wundern, der Code sucht nach dem 2. Sacredprozess, liegt daran das Sacred immer mit 2 Prozessen läuft, weiß der Geier warum. Auf jeden Fall ist immer der 2. der eigentliche Spielprozess.

Code: Alles auswählen

Procedure.l OpenSacredProcess()
  Define.l hProcess, hSnapshot, n
  Define.b OneFound
  Define.PROCESSENTRY32 P
  
  P\dwSize = SizeOf(P)
  hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPALL,0)
  If hSnapshot <> 0
    n = Process32First_(hSnapshot,P)
    If LCase(PeekS(@P\szExeFile)) = "sacred.exe"
      OneFound = 1
    EndIf
    While n <> 0
      n = Process32Next_(hSnapshot,P)
      If LCase(PeekS(@P\szExeFile)) = "sacred.exe"
        If OneFound = 1
          hProcess = OpenProcess_(#PROCESS_ALL_ACCESS,0,P\th32ProcessID)
          CloseHandle_(hSnapshot)
          ProcedureReturn hProcess
        Else
          OneFound = 1
        EndIf
      EndIf
    Wend
    CloseHandle_(hSnapshot)
  EndIf
  
  ProcedureReturn 0
EndProcedure
Und hier wird nun in den Prozesspeicher von Sacred geschrieben. Mag sein das der Code etwas unoptimiert ist, ich bin ja noch PureBasic-Anfänger.

Code: Alles auswählen

Procedure.l SacredChangeMutex(NewMutex.s)
  Define.l hProcess, StartTime, BufferAddr, BufferSize, BytesWritten, MutexSize
  Define.s Mutex
  
  ;Prozesshandle besorgen, wenn nicht innerhalb von #WndTimeOut Millisekunden erfolgreich, dann abbrechen
  StartTime = ElapsedMilliseconds()
  Repeat
    Delay(100) ;Nicht die CPU braten ;-)
    hProcess = OpenSacredProcess()
    If hProcess <> 0
      Break
    EndIf
  Until ElapsedMilliseconds() - StartTime => #WndTimeOut
  If hProcess = 0
    ProcedureReturn 1
  EndIf

  BufferSize = Len(NewMutex) + 1
  BufferAddr = AllocateMemory(BufferSize)
  PokeS(BufferAddr,NewMutex)
  
  MutexSize = 15
  Mutex = Space(MutexSize)
  While Mutex <> "SACRED_INSTANCE"
    ReadProcessMemory_(hProcess,#MutexAddr,Mutex,MutexSize,BytesWritten)
  Wend
  
  If WriteProcessMemory_(hProcess,#MutexAddr,BufferAddr,BufferSize,BytesWritten) = 0
    CloseHandle_(hProcess)
    ProcedureReturn 2
  EndIf
  
  CloseHandle_(hProcess)
  ProcedureReturn 0
EndProcedure

Verfasst: 01.09.2006 18:17
von Zaphod
Lesen ist genauso gefährlich, wenn nicht noch gefährlicher... denk mal an speicherbereiche mit passwörtern oder persönlichen daten.

Verfasst: 01.09.2006 18:22
von Thorium
Zaphod hat geschrieben:Lesen ist genauso gefährlich, wenn nicht noch gefährlicher... denk mal an speicherbereiche mit passwörtern oder persönlichen daten.
Ja, aber unter Windows kein Problem. Es gibt lediglich ein paar Ausnahmefälle wie z.b. Services aber auch den Speicher von Services kann man auslesen und manipulieren. Als Schutz davor empfehle ich Process Guard.

Verfasst: 02.09.2006 15:16
von r0ulade
Thorium hat geschrieben:Joa, Beispiel hab ich. Aus meinem Sacred Underworld BiInstancer.
Danke Thorium - das wird mich ein Weilchen beschäftigen...
Als PB-Oberanfänger :wink: versteh ich aber nicht ganz, woher hier #MutexAddr kommt, diese wird ja nicht in die Prozedur mitgegeben und hier nirgends deklariert... und das sollte ja eben die 'spannende' Adresse sein, wo ich dann im Ziel-Prozess fündig geworden bin!

Code: Alles auswählen

While Mutex <> "SACRED_INSTANCE"
  ReadProcessMemory_(hProcess,#MutexAddr,Mutex,MutexSize,BytesWritten)
Wend
Was bedeutet überhaupt das #-Zeichen? Wird diese Variable nach jedem Wend hochgezählt? Dann würde für mich die While-Wend Schlaufe wenigstens Sinn machen. Oder weisst Du diese Adresse im Ziel-Prozess schon im voraus und es handelt sich bei #MutexAddr um eine Globale Variable? Wenn ja, warum dann die Schleife?

Sorry für die vermutlich dumme Frage, aber in der PB-Hilfe lässt sich nicht nach dem Sinn/Unsinn des #-Zeichens suchen... :oops:

Verfasst: 02.09.2006 15:21
von #NULL