Wie ändere ich den Wert in einer bestimmten Speicheradresse?
Ich bin neu in der C-Programmierung. Es gibt einen Anwendungsfall: Ich muss den Wert in einer bestimmten Speicheradresse ändern.
int main(){
int *p;
p = 0x111;
*p = 100;
return 0;
}
Ich kann den obigen Code jedoch nicht kompilieren. Es zeigt das folgende Problem.
test.c:10:7: warning: incompatible integer to pointer conversion assigning to 'int *' from 'int' [-Wint-conversion]
p = 0x111;
^ ~~~~~
1 warning generated.
Ich habe versucht, wie folgt zu gießen:
int main(){
int *p;
p = (int *) 0x111;
*p = 100;
return 0;
}
Es kann jedoch kompiliert werden, wenn ich es ausführe segmentation fault
.
Meine Frage:
Gibt es eine Möglichkeit, diesen Code zwangsweise zu kompilieren und auszuführen? Ich weiß, dass es ein Problem mit wilden Zeigern gibt. Es ist jedoch ein häufiger Anwendungsfall, um den Speicher zu manipulieren. Zum Beispiel, wenn ich ein lokales Spiel spiele. Irgendwie kenne ich die spezifische Speicheradresse des Gesundheitspunkts meines Spielers, wenn das Spiel läuft, z. B. Adresse = 0x123. Wie ändere ich einfach den Wert in 0x123?
Wenn ich den obigen Weg nicht verwenden kann, um den Wert in einer bestimmten Speicheradresse zu manipulieren, gibt es einen anderen Standardweg, um meinen Anwendungsfall zu realisieren?
PS: Übrigens habe ich den Beispielweg gefunden, um meinen Anwendungsfall zu realisieren.
Sie können sich auf den Quellcode beziehen: https://github.com/haseeb-heaven/GTLibc/
Wie ändern Spieltrainer eine Adresse im Speicher, die dynamisch ist?
https://www.youtube.com/watch?v=cRCnN987gd8&ab_channel=HaseebMir
Antworten
Geben Sie einen gültigen Zeiger auf ein Objekt in einer Speicheradresse an, indirekt über den Zeiger, und weisen Sie einen Wert zu:
int health_points = 1337; // an object in some memory address
int* ptr = &a; // pointer to the value in that memory address
*ptr = 0; // the value is modified
Gibt es eine Möglichkeit, diesen Code zwangsweise zu kompilieren und auszuführen?
Ihr Programm ist schlecht geformt. Es kann eine Möglichkeit geben, einen Compiler erfolgreich kompilieren zu lassen, wenn der Compiler eine relevante Spracherweiterung bereitstellt. In der Regel ist es jedoch eine schlechte Idee, sich auf solche Erweiterungen zu verlassen, da Sie dadurch in die Verwendung dieses einen Compilers verwickelt werden.
Anstatt zu versuchen, einen Compiler zu zwingen, ein fehlerhaftes Programm zu akzeptieren, empfehle ich, das Programm zu reparieren.
Wie ändere ich den Wert in einer bestimmten Speicheradresse?
Zunächst muss der Speicher in dieser Adresse zugewiesen werden. Die Sprachimplementierung sorgt für die Zuweisung des gesamten Speichers, und es gibt keine Standardmethode, um anzugeben, welche Adresse zugewiesen wird.
Einige Sprachimplementierungen geben jedoch möglicherweise bestimmte Adressen als zugänglich an. Dies ist typisch für eingebettete Systeme. Wenn dies der Fall ist, können Sie einen ganzzahligen Wert mithilfe einer Umwandlung in einen Zeiger konvertieren:
std::uintptr_t address = 0x111; // see documentation whether this is a valid address
int* ptr = reinterpret_cast<int*>(address);
Wenn Ihre Sprachimplementierung nicht angibt, dass auf die Adresse zugegriffen werden kann, gibt es keine Garantie für den Zugriff darauf. Unter modernen Betriebssystemen, die den virtuellen Speicher verwalten, ist das beste Szenario ein Segfault.
Lassen Sie mich verstehen, wie Anwendungen die Adresse einer anderen Anwendung oder von sich selbst lesen.
- Selbstadresse.
Die Adresse, die Sie lesen, befindet sich über der Basisadresse, die 0x0040000
für ein ausführbares Image bestimmt ist. Sie sollte also so aussehen 0x0040000
+ 0x0040
wobei 0x0040
der Versatz von der Basisadresse ist. Wenn Sie auf eine andere Region als .text (schreibgeschützt) zugreifen, müssen Sie zuerst die Berechtigung der Region mithilfe der hier gezeigten VirtualProtect- Methode ändern
- Externe Anwendungsadresse.
Wenn Sie Adresse von einem externen Anwendung lesen möchten können Ihr Spiel sagen dann müssen Sie zunächst die Anwendung erhalten Griff , die gerade und Bezeichner für Ihre Anwendung und verwenden Sie dann Readprocessmemory wie gezeigt hier in ähnlicher Weise können Sie schreiben , auch mit Write wie gezeigt hier
Stellen Sie nur immer sicher, dass Sie nur auf den .text
Abschnitt zugreifen, ohne dessen Berechtigungsbereich zu ändern, da Ihr Programm sonst abstürzen könnte.