Highscore speichern; Hash/Checksum; boost;



  • Wenn du das Schummeln noch etwas mehr erschweren möchtest, dann solltest du nicht nur den Hash des Highscores berechnen sondern noch ein Paar geheime Bytes dazu packen. Außerdem ist boost::hash eigentlich für Hash Maps gedacht und nicht um irgendwas abzusichern. Dafür gibt es kryptographische Hash Funktionen wie z.B. SHA1. Wenn man es dann wirklich richtig machen will nutzt man HMAC. Dann hängt die Sicherheit nur noch davon ab wie gut du die geheimen Bytes in deinem Programm verstecken kannst. Für ein einfaches Spiel aber vermutlich Overkill.



  • Hi,

    vielen Dank für deine Antwort.

    Das habe ich schon irgendwo gelesen, dass gerne mal hash/checksum unter einen Hut gebracht werden.

    Das mit den "geheimen bytes" macht für mich irgendwie Sinn. Ich meine, wenn der "hacker" weiß, welchen Algorithmus ich verwende, kann er ja auch einfach die checksum für das gefälschte erzeugen.

    Mich würde interessieren, was die Leute immer meinen, wenn sie von "im Programm verstecken" reden.

    // Ist das hier versteckt?
    checksum = checksum_from(foo + bar + "geheim")
    
    // oder das?
    char c[7] = "geheim";
    // ...
    
    // oder so?
    char* ch = new char[6];
    ch[0] = 'g';
    ch[1] = 'e';
    ch[2] = 'h';
    ch[3] = 'e';
    ch[4] = 'i';
    ch[5] = 'm';
    // ...
    
    // oder einfach eine wahllose Zahl/Char anfügen?
    checksum = checksum_from(foo + bar + to_string(1234));
    

    Google ist auch nicht gerade hilfreich, wenn ich nach "C++ bytes im Programm verstecken" suche.

    Aber ja, realistisch gesehen, ist sowas schon wieder overkill für mein Projekt, es ging mir lediglich darum, dass keiner einfach nur eine text Datei zu öffnen braucht und sofort den top-highscore geknackt hat.

    Mir gehts dabei eher um das Dazulernen^^

    LG
    HarteWare


  • Mod

    HarteWare schrieb:

    Google ist auch nicht gerade hilfreich, wenn ich nach "C++ bytes im Programm verstecken" suche.

    Die Welt spricht Englisch. Ist nun einmal so.

    Google: c++ hide strings in executable



  • SeppJ schrieb:

    HarteWare schrieb:

    Google ist auch nicht gerade hilfreich, wenn ich nach "C++ bytes im Programm verstecken" suche.

    Die Welt spricht Englisch. Ist nun einmal so.

    Google: c++ hide strings in executable

    danke für deine Antwort.

    Auf den Gedanken bin ich dann auch gekommen, bei deiner Suche waren dann nochmal mehr Ergebnisse dabei, als bei mir (ich habe statt executable 'program' und 'source code' probiert).

    Bin mir jetzt nicht sicher, ob etwas wie

    auto val = 0x1234
    

    ausreichen würde, als "geheime(s) byte(s)", oder ob man lieber einen String verschlüsselt speichern sollte. (und ob das dann die präferierte Variante wäre für z.B. irgendeinen key). So Dinge wie in mehrere Strings aufteilen und dann wieder zusammenfügen find ich irgendwie nicht so dolle...

    Wie dem auch sei, für die praktische Anwendung ist das im Moment für mich sowieso "overkill", aber es wäre halt ganz interessant irgendwie...

    LG


  • Mod

    HarteWare schrieb:

    Bin mir jetzt nicht sicher, ob etwas wie

    auto val = 0x1234
    

    Zahlen sind für den Compiler nur Zahlenwerte, unabhängig von der Darstellung. Ob du 0x1234, 4660, 2*2330, 4661-1 oder was anderes schreibst, es wird jedes Mal der gleiche Code erzeugt. Du musst schon die gleichen Prinzipien benutzen wie bei der Zeichenkettenverschlüsselung, also den "richtigen" Wert erst zur Laufzeit berechnen. Wer aber in der Lage ist, in deinem übersetzten Programm den Wert 4660 zu finden, der ist auch in der Lage, diese "Verschlüsselung" zu knacken. Denn schließlich ist das Finden der Zahl 4660 nicht so einfach, wie mit dem Editor das Programm zu öffnen und nach lesbaren Zeichenketten zu gucken. Man muss dazu das Programm deassemblieren, den Assemblercode verstehen können und dann die richtigen Zahlen in dem Programm finden.


  • Mod

    So etwas hatten wir doch schonmal, nicht? FWIW, für C++14 könnte es so aussehen:

    #include <algorithm>
    #include <initializer_list>
    
    template <typename Char>
    constexpr Char rot13(Char ch) {
    	for (auto base : {'a', 'A'})
    		if (ch >= base && ch <= base+26)
    			return (ch-base+13)%26+base;
    	return ch;
    }
    
    template <typename Char, std::size_t N>
    struct StrambleProxy {
    	Char arr[N];
    
    	operator Char const*() {
    		static bool done;
    		if (!done && (done=true))
    			std::transform(arr, arr+N, arr, rot13<Char>);
    		return arr;
    	}
    };
    
    template <typename Char, Char... ch>
    constexpr auto operator"" _rot13() {
    	StrambleProxy<Char, sizeof...(ch)+1> str = {ch...};
    	for (auto& c : str.arr)
    		c = rot13(c);
    	return str;
    }
    

    GCC, zumindest seit Version 5.1, beinhaltet den originalen String lediglich in der Form von ASCII Werten:

    auto operator"" _rot13<char, (char)65, (char)66, (char)67, (char)68, (char)69>()
    

    (http://goo.gl/3jgIXn)



  • Hi,

    vielen Dank für deine Antwort Arcoth.

    Ich glaub ich hab irgendwo schonmal davon gelesen... irgendwas mit "security through obscurity" 😃 (sollte jetzt eine witzige Anspielung auf mein mangelndes Verständnis für den Code sein).

    Ich hab aber noch eine andere, ganz wichtige, Frage: Was, wenn ich vorhabe meine Software open-source zu machen? Dann bringt das doch alles nichts, oder? Auch nicht irgend eine nette "Zauberei". Weil jeder könnte ja sehen, wie das gemacht wird.

    Kann ich überhaupt bei einem open-source Spiel einen halbwegs großen Aufwand erzeugen, der für das "hacken" einer online highscoreliste nötig wäre?

    LG
    HarteWare

    P.S.: Wenn es stört, dass ich im C++ unterforum nun eine etwas andere Frage aufwerfe, die nicht direkt mit C++ zu tun hat, kann ich auch gern nochmal in einem anderen Subforum einen Thread aufmachen. Aber irgendwie gehört es ja schon zu diesem Thema.


  • Mod

    HarteWare schrieb:

    Kann ich überhaupt bei einem open-source Spiel einen halbwegs großen Aufwand erzeugen, der für das "hacken" einer online highscoreliste nötig wäre?

    Ja. Online machen 🙂 .


  • Mod

    @SeppJ: Sätze sollte man entweder mit einem Smiley oder mit einem Satzzeichen beenden, aber beides hintereinander sieht falsch aus - außer der Smiley folgt dem Satzzeichen.

    Hello World! 🙂

    Hello World 🙂

    Hello World 🙂 !

    Welcher von diesen Sätzen sieht am hässlichsten aus?


  • Mod

    Logik geht eben vor Ästhetik, bis die Gesellschaft für deutsche Sprache sich der korrekten Interpunktion von Smileys widmet (also so um das Jahr 2150 herum).



  • @Arcoth:
    Wie wär's mit...

    Hello World! :)!

    :D?



  • SeppJ schrieb:

    HarteWare schrieb:

    Kann ich überhaupt bei einem open-source Spiel einen halbwegs großen Aufwand erzeugen, der für das "hacken" einer online highscoreliste nötig wäre?

    Ja. Online machen 🙂 .

    Wie jetzt, online machen? Ich machs doch online. Oder meinst Du jetzt als HTML5 Game im Browser oder was 😕 ?


  • Mod

    HarteWare schrieb:

    SeppJ schrieb:

    HarteWare schrieb:

    Kann ich überhaupt bei einem open-source Spiel einen halbwegs großen Aufwand erzeugen, der für das "hacken" einer online highscoreliste nötig wäre?

    Ja. Online machen 🙂 .

    Wie jetzt, online machen? Ich machs doch online.

    Erzähl mal mehr. Bis jetzt hast du bloß nach Textdateien gefragt.



  • Ich habe eine Website gehostet, auf dem Server lagert ein PHP skript, an welches man einen POST request mit dem Highscore schicken kann, woraufhin dieses den Highscore der Datenbank hinzufügt.

    Jetzt könnte ich ja aber auch einfach ein Programm schreiben, welches ebenfalls einen solchen POST Request sendet, aber mit gefälschtem highscore. Mein PHP Skript weiß aber nicht, dass der Request nicht tatsächlich vom Spiel kam. Auch wenn ich noch irgendein Passwort hinzufüge (grob gesagt) - wenn es open-source ist, könnte das andere Programm das ja auch alles imitieren, oder?



  • Dazu muss das Programm nicht open-source sein, das geht auch so. Selbst mit TLS kannst du nicht verhindern, dass jemand falsche Daten an den Server sendet.

    Der Server spielt deshalb auch das Spiel und zwar mit den Eingabedaten, die vom Client kommen. Falls der Server zum selben Ergebnis kommt, dann ist der Highscore gültig. Falls also jemand trotzdem den Highscore manipulieren will, dann muss er schon einen Bot dafür schreiben.



  • patrick246 schrieb:

    Dazu muss das Programm nicht open-source sein, das geht auch so. Selbst mit TLS kannst du nicht verhindern, dass jemand falsche Daten an den Server sendet.

    Der Server spielt deshalb auch das Spiel und zwar mit den Eingabedaten, die vom Client kommen. Falls der Server zum selben Ergebnis kommt, dann ist der Highscore gültig. Falls also jemand trotzdem den Highscore manipulieren will, dann muss er schon einen Bot dafür schreiben.

    Wie ist das gemeint, das selbe Ergebnis mit den Eingabedaten?



  • Ich weiß nicht, wie dein Spiel funktioniert, aber generell werden die Eingabedaten zum Server übermittelt, d.h. Spieler hat zum Zeitpunkt X die Taste Y gedrückt. Dann spielt der Server das Spiel mit diesen Daten durch, für Zufallswerte muss natürlich noch der Seed übermittelt werden, damit das ganze funktioniert. Und falls mit den Eingabedaten beim Server der gleiche Highscore herauskommt, ist er gültig.


  • Mod

    HarteWare schrieb:

    Wie ist das gemeint, das selbe Ergebnis mit den Eingabedaten?

    Always-online DRM! Das Spiel wird nicht auf dem Clientcomputer gespielt, sondern auf dem Server. Der Client übernimmt nur die grafische Darstellung, der Server die Spiellogik. So bist du davor geschützt, dass die Spiellogik vom Spieler manipuliert wird. Manipulationen sind so nur noch auf wenige und aufwendige Arten und Weisen möglich, z.B. durch Manipulation der Grafikengine, wie Wallhack oder alle Gegner neongrün leuchten lassen.

    Abgeschwächte Variante: Anstatt des Highscores wird ein Replay hochgeladen, welches die Eingaben des Spielers enthält, nicht (nur) den Zustand des Spiels auf dem Client. Der Server zieht anhand der Eingaben den Spielverlauf nach und berechnet daraus selber den Highscore. Ist ein wenig einfacher zu manipulieren, aber nicht viel einfacher. Entlastet aber deinen Server und riecht weniger stark nach Nutzergängelung.



  • Hallo,

    danke für eure Antworten.

    Es handelt sich um ein Memory spiel. D.h., spiellogik wäre z.B. eine Reihe von Karten ID's in der Reihenfolge, in der sie aufgedeckt wurden. Sowas könnte man aber denke ich auch relativ leicht fälschen, wenn man die Formel zur Berechung des highscores kennt (was bei open source der Fall wäre).

    D.h. ich müsste also auf dem Server eine session starten, und nach jedem Spielzug die Daten (zB welche Karte wurde aufgedeckt) übermitteln. Bei einem simplen Spiel wie Memory könnte man das dann doch auch fälschen.

    Aber ok, es ging mir ja ums Prinzip, damit ich einen kleinen Schimmer davon have wie sowas funktionieren könnte.

    Es wär ja auch blöd, wenn man nur mit Internetverbindung spielen kann.

    Da das Spiel aus Urheberrechtlichen Gründen eh nur für den privaten Gebrauch geeignet ist, muss ich mir vermutlich keine Gedanken um gehackte Highscores machen, realistisch gesehen. Ich bin halt nur so wissbegierig^^

    LG
    HarteWare


  • Mod

    Bei solch einer Art Spiel musst du die Spiellogik tatsächlich komplett auf dem Server haben. Wenn das Spiel auf dem Rechner des Nutzers laufen würde, könnte dieser ja einfach im Speicher gucken, welche Karte welche ist, selbst wenn sie noch zugedeckt ist. Wenn aber das Spiel selbst auf dem Server läuft, dann erfährt der Nutzer erst nach Aufdecken einer Karte, welche dies ist und der Server kann sicherstellen, dass der Nutzer sich an die Regeln hält.

    Es wär ja auch blöd, wenn man nur mit Internetverbindung spielen kann.

    Tja, ist eben so, wenn du einen manipulationssicheren, weltweiten Highscore möchtest.


Anmelden zum Antworten