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

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...

Verfasst: 02.09.2006 15:21
von #NULL