Memory eines anderen Programms auslesen

Anfängerfragen zum Programmieren mit PureBasic.
r0ulade
Beiträge: 4
Registriert: 31.08.2006 23:29
Wohnort: na na na na

Memory eines anderen Programms auslesen

Beitrag 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!
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

>> klappt leider definitiv nicht
Du liest ja auch im virtuellem Speicher Deines Programms, nicht im Speicher
des anderen Programmes.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag 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.
r0ulade
Beiträge: 4
Registriert: 31.08.2006 23:29
Wohnort: na na na na

Beitrag 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....!?
Benutzeravatar
Eric
Beiträge: 303
Registriert: 05.09.2004 09:50
Wohnort: Göttingen

Beitrag 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.
El_Choni_work: cant't you just spit the binary data to sqlite, as you would spit a hamster into a microwave oven?
* Fangles falls off the chair laughing
Bild
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag 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
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag von Zaphod »

Lesen ist genauso gefährlich, wenn nicht noch gefährlicher... denk mal an speicherbereiche mit passwörtern oder persönlichen daten.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Beitrag 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.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
r0ulade
Beiträge: 4
Registriert: 31.08.2006 23:29
Wohnort: na na na na

Beitrag 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:
Antworten