ReadProcessMemory Text/String auslesen

04/16/2011 07:46 BrendonHomo#1
Guten Morgen,

ich hab zurzeit ein kleines Problem wo in Google nicht viel drüber steht.
Undzwar ich will von einem Pointer den Text auslesen allerdings gelingt mir das nicht so wirklich, entweder ich schaff nur den ersten Buchstaben auszulesen ( liegt daran das ich die länge angeben muss,aber klappt nicht so wie ich das will) oder dort kommt nur komisches Zeug raus.

Code:
DWORD value;
ReadProcessMemory(hProcess,(LPVOID)Adresse,&value,sizeof(value),0);
ReadProcessMemory(hProcess,(LPVOID)(value+Offset),&value,sizeof(value),0);
Das währe jetzt für einen 4Byte wert, meine bitte an euch ist mir zu zeigen wie sowas für ein Text geht.
04/16/2011 08:27 HardCore.1337#2
Meine Idee wäre den Text in einem Array von jeweils 1Byte (1 Zeichen) zu speichern
04/16/2011 08:48 BrendonHomo#3
Schon probiert leider erfolglos.

Edit:

Eine Speicheradresse auszulesen schafft man so, allerdings klappt das nicht wirklich bei einem Pointer

char kette[10];
ReadProcessMemory(hProcess,(LPVOID)Adresse,kette,s trlen(" "),0);
04/16/2011 12:08 5769854332#4
Benutze eine Schleife: lies jeweils nur ein Byte, und schau, ob es "0" ist (terminating zero).
04/16/2011 14:00 MrSm!th#5
Blödsinn, Strings sind selbst nur Arrays von char's, also kannst du das auch als solches einlesen.

Weißt du die Länge des Strings? Falls ja, dann gehts einfach:

Code:
char str = new char[TextLen+1];
ZeroMemory(str,TextLen+1);
ReadProcessMemory(hProcess, addr, str, TextLen, 0);
Falls du sie nicht kennst, müsstest du es wohl wirklich in einer Schleife machen, was allerdings bei längeren Strings langsam wird, außerdem versteh ich nicht, wieso man die Länge des Strings nicht kennen sollte o.ô Willst du einen Chat o.Ä. auslesen?
04/16/2011 14:29 BrendonHomo#6
Ja ich will ein Chat auslesen :)
D.h Länge unbekannt.
04/16/2011 16:02 MrSm!th#7
Normalerweise hat ein Chat eine Variable für die Länge der Nachricht oder eine Max-Länge, die nicht überschritten werden kann.
D.h. du könntest entweder die Variable für die Länge auslesen oder die Variable für die Max-Länge und dann so viele Bytes auslesen; wenn die Länge nicht voll ausgenutzt wird, sollten dahinter Nullen sein, sodass du keinen Müll in deinem String hast.

Sollte keins von beidem zu finden sein (zb. per CE), müsstest du wirklich in einer Schleife immer nur ein Byte auslesen und prüfen, ob der Null-Terminator erreicht ist.
Oder, wenn du im gleichen Prozess bist, zb. via Dll-Injection einfach strcpy. Die Funktion hört nach dem Null-Terminator automatisch auf.
04/17/2011 15:55 BrendonHomo#8
Will irgendwie alles nicht, liegt aber auch bestimmt zum größten Teil an meiner mangelnden Erfahrung.
Wie sieht das mit der Schleife bei einem Multilevel Pointer aus in einer dll?
Text typ ist Ansi.
04/17/2011 23:02 MrSm!th#9
Quote:
Wie sieht das mit der Schleife bei einem Multilevel Pointer aus in einer dll?
Text typ ist Ansi.
Verstehe nicht ganz, bei Dlls macht das ganze keine Probleme:

Code:
char *buffer = NULL;
int len = strlen(addr);
buffer = new char[len+1];
strcpy(buffer, addr);
Ist es ein Multilevel-Pointer, dann dereferenziert man eben:

Code:
DWORD *addr = 0xDEADBEEF;
const DWORD offset = 0x1337
addr = (*(DWORD*)(addr) ) + offset;
char *buffer = NULL;
int len = strlen((char*)addr);
buffer = new char[len+1];
strcpy(buffer, addr);
04/24/2011 15:21 BrendonHomo#10
Sry, das ich mich so spät melde, das klappt nicht so ganz (Crash), also er loggt den ersten Satz und danach Crasht die Applikation.

Quote:
char *buffer;
int len = strlen((char*)addr);
buffer = new char[len+1];

while (1) {

if (flag==1) {

Sleep(1000);

addr = (*(DWORD*)(addr) ) + offset;
addr = (*(DWORD*)(addr) ) + offset2;
addr = (*(DWORD*)(addr) ) + offset3;
addr = (*(DWORD*)(addr) ) + offset4;
addr = (*(DWORD*)(addr) ) + offset5;


strcpy(buffer,(char*)addr);
Ist nur ein Stück vom Quellcode :)
04/24/2011 15:30 MrSm!th#11
Erstmal: Wie kannst du, bevor du den Pointer in der Schleife dereferenzierst, strlen benutzen? o.ô Macht doch keinen Sinn, wenn das ein Multilevel Pointer ist; bei strlen musst du genau so dereferenzieren wie für den Aufruf von strcpy.

Außerdem, setzt du addr am Anfang der Schleife wieder auf den Base Pointer? Falls nicht, ist das das Problem. Du willst sonst nämlich die ersten vier Bytes des Strings im zweiten Durchgang wieder als Pointer interpretieren und diesern erneut 5 Mal dereferenzieren.
04/24/2011 16:50 BrendonHomo#12
Das mit strlen kann ich mir auch nicht erklären aber es klappt,
der Crash kahm dadurch das ich addr am Anfang der Schleife nicht wieder auf die Base gelegt habe.
Nun klappt alles einwandfrei, nur ist das für Ansi, nun möchte ich das auch noch gerne in Unicode haben, wegen den Charnamen uvm , hab gelesen das ich dafür die Funktion MultibytetoWide benutzen muss.
04/24/2011 17:08 MrSm!th#13
Nimm einfach statt char wchar_t
Nur verstehe ich nicht ganz wieso. Wenn der Chat in Ansi ist, was bringt es dir dann, ihn in Unicode darzustellen? Es können doch eh nicht mehr Zeichen als die aus dem ASCII Zeichensatz dort geschrieben werden o.ô

Ich würde dir trotzdem raten, es bei strlen richtig zu machen, ich denke nämlich nicht, dass du die richtige String-Länge ausliest, sondern die Bytes, auf die der Basepointer zeigt, als String interpretierst und die Anzahl der Bytes bis zu einem 0 Byte zählst.
Das wird sicherlich nicht immer gehen...
04/24/2011 18:34 BrendonHomo#14
Wenn ich wchar_t nutze funktioniert das nicht:
Keine Konvertierung von wchar_t* nach const char*.

Ich arbeite mit Embracadero C++ Builder, sprich kein Visual Studio.
Unicode brauch ich wegen den Charakternamen uvm.
04/24/2011 22:15 MrSm!th#15
Verstehe ich nicht, was haben die mit dem Chat zutun? Wenn man im Chat nur Ansi schreiben kann, sind doch die Namen egal o.ô Dann liest du eben die Namen in wchar_ts ein und die Nachrichten in Ansi Strings.

Man kann auch nicht einfach so konvertieren, entweder nimmst du von Anfang an für alle Strings wchar_t und dementsprechend auch wcslen, wcscpy usw. oder du nutzt mbtowcs und wcstomb zum konvertieren.