1 Punkte von GN⁺ 2025-04-24 | 1 Kommentare | Auf WhatsApp teilen
  • Ein 20 Jahre alter Bug in GTA San Andreas tritt unter Windows 11 24H2 zutage
    • Es wurde ein Bug gemeldet, bei dem das Skimmer-Flugzeug in GTA San Andreas unter Windows 11 24H2 verschwindet
    • Auch mit SilentPatch lässt sich das Problem nicht beheben
    • Unter Windows 11 23H2 tritt das Problem nicht auf
    • Alle Nutzer, die auf Windows 11 24H2 aktualisiert haben, erleben diesen Bug

Untersuchung des Bugs

Was ist schiefgelaufen?

  • Bei installierter SilentPatch friert das Spiel ein
  • Es wurde festgestellt, dass CPlane::PreRender in einer kleinen Schleife hängen bleibt
  • Die Rotorgeschwindigkeit des Flugzeugs wird auf einen ungewöhnlich hohen Wert gesetzt
  • Die Rotorgeschwindigkeit wird proportional zur Flughöhe des Flugzeugs berechnet

Warum und wie?

  • In der vehicles.ide-Definition des Skimmer fehlt ein erforderlicher Parameter
  • In Vice City war der Skimmer als Boot definiert
  • In San Andreas wurde er zu einem Flugzeug geändert, aber der benötigte Parameter wurde nicht ergänzt

Die wahre Grundursache

  • Das Problem tritt auf, weil sich die Art der Stack-Nutzung in Windows 11 24H2 geändert hat
  • LeaveCriticalSection verwendet mehr Stack-Speicher als zuvor
  • Früher haben fgets und LeaveCriticalSection den Stack-Bereich nicht überschrieben, jetzt tun sie es

Warum tritt das erst jetzt auf?

  • Durch Änderungen in Windows 11 24H2 hat sich die Stack-Belegung verändert
  • Das Spiel verwendet eine nicht initialisierte lokale Variable, wodurch das Problem entsteht
  • Auf anderen Plattformen war das Problem bereits behoben

Wie kann man das Problem im Spiel beheben?

  • Der nächste SilentPatch-Hotfix soll eine Codekorrektur enthalten
  • Das Problem lässt sich auch durch manuelles Bearbeiten der Datei vehicles.ide beheben

Schlusswort

  • Dieser Bug ist interessant, weil er direkt mit einer bestimmten OS-Version verknüpft ist
  • Er zeigt, dass Änderungen am Stack-Layout die Kompatibilität beeinflussen können
  • Eingabedaten sollten validiert und Compiler-Warnungen nicht ignoriert werden

1 Kommentare

 
GN⁺ 2025-04-24
Hacker-News-Kommentare
  • Klingt nach etwas, das man von Raymond Chen erwarten würde. Das ist sehr hohes Lob
  • Freut mich, dass die Ursache des Problems tiefergehend nachverfolgt wurde
  • Meiner persönlichen Meinung nach sollte alles, was nicht Teil des Vertrags ist, zufällig behandelt werden. Wenn zum Beispiel die Iterationsreihenfolge einer Map in einer Sprache nicht garantiert ist, dann sollte die Sprache sie zufällig machen. Sonst wird der Code fragil
  • Compiler-Warnungen sollte man nicht ignorieren. Dieser Code hat im ursprünglichen Code wahrscheinlich Warnungen ausgelöst
  • Welcher Compiler-Fehler wäre hier zu erwarten? Vielleicht, dass der Rückgabewert von scanf nicht geprüft wird, um sicherzustellen, dass er zur Anzahl der Parameter passt. Andernfalls sieht es eher nach einem Fehler in einer Datendatei aus, den der Compiler nicht kennen kann
  • Ich lese technische Artikel immer gern. Ich frage mich, wie viel seltener solche Texte im Zeitalter der KI werden
  • Ich frage mich, was sich in der Implementierung des Sperrens/Entsperrens kritischer Abschnitte in Windows geändert hat
  • Bereitstellung eines Links für Menschen mit Zugriffsproblemen
  • Über das Stack-Ende hinaus zu lesen und zu schreiben war immer viel zu einfach. Das sollte einfach fehlschlagen
  • Es gibt Gegenmaßnahmen – ASLR, NX-Seiten, Stack-Smashing-Schutz usw. Aber sie verhindern nicht vollständig das Lesen alter Daten jenseits des Stacks
  • Gedankenexperiment: Was wäre, wenn die Hardware das Lesen oder Schreiben ungenutzter Teile des Stack-Bereichs verhindern würde?
  • Vorschlag für eine Methode, die Startadresse A des Stacks, die Größe S und die aktuelle Tiefe D zu verfolgen
    • Einen Befehl hinzufügen, der der CPU mitteilt, dass ein Stack an Adresse A mit Größe S existiert
    • Einen Sprungbefehl hinzufügen, der N Bytes auf dem Stack reserviert
    • Den bestehenden Rückkehrbefehl um Stack-Bewusstsein erweitern
    • Lesen oder Schreiben in Stack-Bereiche jenseits der aktuellen Tiefe schlägt fehl
    • Bei Architekturen, in denen der Stack nach unten wächst, gilt die Arithmetik umgekehrt
  • Als Nachteil würde dadurch eine einzige Calling Convention festgeschrieben, und der Speicherverwalter der CPU bräuchte viel Zustandsinformation
  • Stacks gibt es überall. Hardwareseitiges Stack-Bewusstsein würde neue Gegenmaßnahmen ermöglichen
  • Warum ist diese Idee nicht verbreitet? Wurde sie schon einmal ausprobiert?
  • All diese Erkenntnisse beweisen, dass dies kein Problem von Windows 11 24H2 ist. Das Spiel verlässt sich auf undefiniertes Verhalten
  • Undefiniertes Verhalten ist äußerst hinterhältig und bringt einen dazu zu glauben, man liege richtig, obwohl man bereits einen Fehler gemacht hat
  • Wenn ein C- oder C++-Programm undefiniertes Verhalten auslöst, kann bei der Programmausführung alles Mögliche passieren
  • Mit Glück zeigt das Programm eine angemessene Fehlermeldung an oder stürzt ab, sodass sofort klar ist, dass etwas nicht stimmt
  • Mit Pech beschädigt das Programm Daten stillschweigend, und wenn man das Problem erkennt, ist die Ursache längst in vergangenen Ausführungen vergraben
  • Mit sehr viel Pech funktioniert das Programm genau wie gewünscht, bis man nicht zusammenhängenden Code ändert oder die Compiler-Version, das Betriebssystem usw. wechselt und neue Bugs auftauchen
  • Vorschläge für einen besseren Weg aus Entwicklersicht
    • Undefiniertes Verhalten in C oder C++ lesen, verstehen und verinnerlichen und es vermeiden
    • Die Anwendung im Debug-Modus kompilieren und mit dem Release-Modus vergleichen; wenn es Unterschiede gibt, liegt ein ernstes Problem vor
    • Werkzeuge wie -fsanitize=undefined,address verwenden, um undefiniertes Verhalten zur Laufzeit zu erkennen
    • Verwaltete Sprachen wie Java, C# oder Python verwenden. Oder sichere Low-Level-Sprachen wie Rust
  • Empfehlung, einen Debugger zu verwenden. Ich habe Geschichten über die Probleme gehört, die entstehen, wenn man keinen Debugger benutzt
  • Viel Liebe an Silent. Seit über 10 Jahren verbessert er Spiele, die ich liebe