Speicheradresse auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@anymagical: Warum rufst Du `c_ulong()` mit dem Argument 4 auf? Ich hoffe Du denkst nicht dass das dann vier Bytes gross ist. Die Bitlänge von diesem Typ hängt vom System ab, ist also nicht garantiert und die vier ist der *Wert* dem Du dieser Zahl gibst. Da der sowieso überschrieben wird, ist die vier an der Stelle etwas verwirrend. Wenn Du einen vorzeichenlosen Integertyp mit vier Bytes, also 32 Bits, haben möchtest, dann musst Du `ctypes.c_uint32` nehmen. Der belegt unabhängig vom System immer vier Bytes.

Der gezeigte Quelltext dürfte übrigens einen `NameError` auslösen.
anymagical
User
Beiträge: 33
Registriert: Montag 2. April 2012, 15:34

Na ich hab gemerkt das c_ulong(4) nicht die größe angibt. Danke für den Tip mit c_uint32()!
Oh da habe ich noch einen falschen Namen verwendet wurde korrigiert.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Mit c_ulong ist eben genau das gemeint - eiin Typ in C der "Größe" unsigned long. D.h. Du fällst auf das zurück, was auf der eingesetzten Plattform long (vorzeichenlos) ist, was eben nicht plattform unabhängig in C spezifiziert ist. Das ist ein altbekanntes Problem unter C, welchem man mit Erweiterungen der Typen um "fixed sized" Typen ala int<SIZE>_t seit C99 zu begegnen versucht.
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

anymagical hat geschrieben: Was mich dennoch interessieren würde ist wieso das ganze nicht mit Solitär funktioniert, falls da jemand noch die ein oder andere Idee hat würde ich sie gerne erfahren 8)
Unicode... probiere

Code: Alles auswählen

HWND = win32ui.FindWindow(None,u"Solitär").GetSafeHwnd()
anymagical
User
Beiträge: 33
Registriert: Montag 2. April 2012, 15:34

Hallo,

ich habe den Fehler noch gefunden,

Code: Alles auswählen

ADDRESS1 = 0x00B97D5C
ADDRESS2 = ctypes.create_string_buffer(64)
rPM(PROCESS,ADDRESS1,ADDRESS2,64,None)
man musste statt ADDRESS2 bei der rPM Funktion einen Pointer übergeben welcher auf die Addresse 2 zeigt.

Code: Alles auswählen

ADDRESS1 = 0x00B97D5C
ADDRESS2 = ctypes.create_string_buffer(64)
rPM(PROCESS,ADDRESS1,ctypes.pointer(ADDRESS2),64,None)
Der Prozess wird auch ohne unicode gefunden!

Grüße
Anymagical
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

@ anymagical

Hallo

Ich find das Thema hier sehr interessant und dein Beispiel über Solitär hat mein Interesse geweckt. Leider kenne ich mich mit dem Modul ctypes nicht sonderlich gut aus. Meine Fragen beziehen sich nun erstmals auf den BasePointer. Also ich hab mittels CE 6.2 einmal einen pointer scan gemacht und einmal habe ich den pointer auch manuell gesucht. bzw zusammen gebaut (siehe Bilder).

Bild
Bild

Meine Frage ist nun, wie ich in etwa diesen Pointer in deinen obigen Code einbaue, so dass ich nicht die Speicheradresse jedes Mal manuell abändern muss sobald ich Solitär neu starte. Muss ich die Offsets irgendwie dazu addieren?

lg
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@lackschuh: Verstehe ich deine Frage richtig, dass du wissen willst, ob/wie man Pointer auf beliebige Speicheradressen fremder Programme setzen kann?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@lackschuh:
Dein Frage ist unverständlich. Wenn Du wissen willst, wie man an das Processhandle nach Programmneustart kommt - dafür gibts verschiedene Funktionen in der Win-API (z.B. EnumProcesses oder ..zensiert..). Damit kannst Du aus dem Pool der laufenden Prozesse den gesuchten Prozess rausfischen.
Was Du dann mit dem Handle anfangen kannst, hängt von Deinen Rechten ab (Debugging-Rechte).

Im Übrigen hat das alles hat nix mehr mit ctypes zu tun. ctypes stellt nur Python-Wrapper zu den hierfür nötigen Systemfunktionen. Ohne ein grundlegendes Verständnis von gewissen Windowsinterna wie Prozess- und Speicherverwaltung und deren Rechtesystem wirst Du da nicht weiterkommen.

Mehr sag ich nicht, da die Sache doch ein wenig nach Skriptkiddie riecht ;)
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Hallo

Meine Frage war, wie ich eine Adresse bilde/errechne, welche aus einer Basisadresse und den offsets besteht (siehe Bilder). Also theoretisch addiere ich die Offsets zu der Basisadresse?

Um meine Frage vielleicht vereinfachen zu können an Hand eines "falschen" Beispiels:

Code: Alles auswählen

addresse1 = 0xFF44AFA8
offset = 0x50
addresse2 = 0

#<-- dann eine Funktion, welche die addresse1 ausliest und in addresse2 schreib
#<-- danach die Offsets dazu addieren
address2 = address2+offset
Meine Frage richtete sich in erster Linie an anymagical, da dieser auf S.1 diese Problematik angesprochen hat in der Hoffnung, dass er dieses Problem gelöst hat und mir eventuell seine Lösung sagen kann.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

lackschuh hat geschrieben: Meine Frage war, wie ich eine Adresse bilde/errechne, welche aus einer Basisadresse und den offsets besteht (siehe Bilder). Also theoretisch addiere ich die Offsets zu der Basisadresse?
Ehm, ja - wobei Du mit der Festlegung, Zieladresse ergibt sich aus Basisadresse + Offset das ja quasi so festlegst. Bei Sprachen mit Pointerarithmetik muss Du noch die Typisierung der Pointer beachten. Kennst Du nur den Gesamtoffset in Bytes würde man in C auf char* zurückgreifen.
Deine Bilder verdeutlichen mir Deine Fragestellung nicht, da ich nicht weiss, was Du da treibst.

Zu Deinem Pseudocode:
'addresse1' ist eine gültige Adresse, mit einem Offset von 0x50 wäre die Zieladresse 0xFF44AFF8. 'addresse2 = 0' entspricht fast überall dem Nullpointer, d.h. der Versuch, dorthin zu schreiben, wird fehlschlagen (was Du in der Funktion machen willst). Nach 'addresse2 = addresse2+offset' ist 'addresse2' 0x50 (für char-Pointer, hab mal ein 'e' hinzugedichtet).
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

jerch hat geschrieben:@lackschuh:
Dein Frage ist unverständlich. Wenn Du wissen willst, wie man an das Processhandle nach Programmneustart kommt - dafür gibts verschiedene Funktionen in der Win-API (z.B. EnumProcesses oder ..zensiert..)
Hallo

Ich hab mich wieder ein paar Abende mit dem Obgenannten beschäftigt...

Mit EnumProcessModulesEx bekomme ich nur bei 32-bit Programmen den Processhandle. Bei 64-bit Programmen geht es nicht. Solitär ist wohl ein 64-bit Programm, da ich Win 7 Uiltimate x64 habe.

Um an die dynamische Speicheradresse zukommen, welche die Punkte speichert, muss ich die Basis-Adresse von solitaire.exe haben/bekommen. Zu dieser addiere ich wie auf dem Bild 0xBAFA8.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@lackschuh:
Bin mir nicht sicher, was Du eigentlich suchst, EnumProcessModulesEx gibt keine Processhandles zurück sondern Modulehandles eines Prozesses. Und da gibts tatsächlich Probleme, wenn Du versucht von 32bit auf 64bit und vice versa zuzugreifen. Ein Processhandle liefert Dir z.B. OpenProcess.
lackschuh
User
Beiträge: 281
Registriert: Dienstag 8. Mai 2012, 13:40

Danke für die Info. Also mit OpenProcess bekomme ich in der Tat den Handle von Solitär (64bit). Danach, wenn ich weiter nach der Doku vorgehe mit EnumProcessModules, sollte nun das erste Modul des Prozesses die .exe sein also in meinem Fall die solitaire.exe.
baseAdresse= psapi.EnumProcessModules(hProcess, byref(hModule), sizeof(hModule), byref(count))
print "Adresse:", baseAdresse
Wenn ich hier einen anderen Prozess aufrufe, zB "FileZilla", dann geht alles (darum denke ich, dass es an dem 64-bit Solitär liegt)

http://support.microsoft.com/kb/175030/de?wa=wsignin1.0
http://code.activestate.com/recipes/305 ... n-windows/

PS: Ich hab noch einen Notebook Zuhause, auf welchem eine 32-bit Win 7 Version oben ist. Es ist wohl besser, ich probiere dort weiter.
Antworten