Probleme mit Nullen im String und Logikfehler
-
Hallo !

Ich habe mir eine Funktion gebastelt um im Prozesspeichers eines Windows-Prozesses nach einem binären Pattern zu suchen (mit einer x/? -Maske modifizierbar).Nun ja...das größte Problem ist gleich mal dass \x00 in einem String ihn mir gleich terminiert und ich nicht length() aufrufen kann.
Das selbe Problem habe ich auch mit den Daten die ich aus dem Speicher lese.Ich könnte auch eine DLL in meinen Prozess injecten und per Zeigerspielereien auf mein Pattern-Offset zu kommen doch das kommt mir zu "wuchtig" rüber.
Außerdem glaube ich dass ich einige Logikfehler im Code habe. Wäre nett wenn mal jemand durch den Code schauen würde bzw mir sagen könnte wie ich einen string mit binären Daten füllen kann ohne dass ein \x00 ihn mir gleich terminiert.

Hier mal mein aktueller Code:
So wird der Code verwendet:
Process* proc = new Process; proc->SetByProcessName("pinball.exe"); proc->Open(); cout << "\n"; cout << "Process-ID: " << proc->ID() << "\n"; cout << "Process-Handle: " << proc->Handle() << "\n"; cout << "Scanning for score offset...\n"; string pattern = "\xC2\x00\x00\x00\x00\x00\x0A\x00\x05\x00\x92\x01\x08\x01\x5A\x44\x00\x00"; string mask = "xxxxxxxxxxxxxxxxxx"; DWORD score_offset = proc->FindBinaryPattern(0x400000, 0x1000000, 18, pattern, mask); cout << "Score-Offset: " << score_offset << "\n";Und hier die Implementation der Funktion:
"int patternlength" wird nur benötig da pattern.length() nicht aufrufbar ist...wäre doch deutlich praktischer mit der anderen Lösung

bool Process::DataCompare(string data, int index, int patternlength,string pattern, string mask) { for (int i = 0; i < patternlength; i++) { if (mask[i] == 'x' && data[index + i] != pattern[i]) return false; } return true; } DWORD Process::FindBinaryPattern(DWORD StartAddress, int Length, int patternlength, string pattern, string mask) { int index = 0; string buffer; if(FINDBINARYPATTERN_BYTESTOREAD > Length) { buffer = ReadMemString(StartAddress, Length); for(int i = 0; i < (Length - patternlength); i++) { if(DataCompare(buffer, i, patternlength, pattern, mask)) return static_cast<DWORD>(StartAddress + i); } } else { while (index < Length) { buffer = ReadMemString(StartAddress + index, FINDBINARYPATTERN_BYTESTOREAD + patternlength); for (int i = 0; i < FINDBINARYPATTERN_BYTESTOREAD; i++) { if(DataCompare(buffer, i, patternlength, pattern, mask)) return static_cast<DWORD>(StartAddress + index + i); index += FINDBINARYPATTERN_BYTESTOREAD; } } } return static_cast<DWORD>(NULL); }Ich setze Hoffnung in euch^^
Grüße und Danke im Vor-raus !

-
1. voraus
2. versteh ich nicht genau, was du möchtest
Nun ja...das größte Problem ist gleich mal dass \x00 in einem String ihn mir gleich terminiert und ich nicht length() aufrufen kann.
das stimmt (falls ich es nich falsch verstehe) nicht:
std::string foo; assert(foo.size() == 0); foo.push_back(0); assert(foo.size() == 1); foo.push_back(1); assert(foo.size() == 2);bb
-
Die Klasse
std::stringbetrachtet vorkommende'\0'-Zeichen nicht als Terminierungen. Anders sieht es aus, wenn du den C-String überc_str()holst.Da
std::stringspeziell für Zeichenkettenverwaltung konzipiert ist und du eher einen Container für Daten brauchst, rate ich dir zustd::vector<char>. Da hast du zum Beispiel auch die Garantie, dass alle Elemente hintereinander im Speicher liegen, was beistd::stringnicht sein muss.