Strategien, um Speichereditoren für das Betrügen zu besiegen - Desktop-Spiele [geschlossen]

35

Ich gehe davon aus, dass es sich um Desktop-Spiele handelt - etwas, das der Player auf seinem lokalen Computer herunterlädt und ausführt. Viele sind Speichereditoren, mit denen Sie Werte erkennen und einfrieren können, beispielsweise die Gesundheit Ihres Players.

Wie verhindert man Betrug durch Speichermodifikation? Welche Strategien sind wirksam, um diese Art von Betrug zu bekämpfen?

Als Referenz weiß ich, dass Spieler: - nach Werten oder Bereichen suchen können - nach Werten suchen, die sich geändert haben - Speicherwerte festlegen - Speicherwerte einfrieren können

Ich suche ein paar gute. Zwei, die ich mittelmäßig benutze, sind:

  • Anzeige der Werte in Prozent anstelle der Zahl (z. B. 46/50 = 92% Gesundheit)
  • Eine Klasse auf niedriger Ebene, die Werte in einem Array enthält und diese bei jeder Änderung verschiebt. (Anstelle eines Int habe ich beispielsweise eine Klasse, die ein Array von Ints ist. Wenn sich der Wert ändert, verwende ich ein anderes, zufällig ausgewähltes Array-Element, um den Wert zu speichern.)

Das Spiel ist offline, kostenlos und Einzelspieler.

Edit: Für die Nachwelt habe ich dies gelöst (in C #) und meine Lösung hier in meinem Blog gepostet .

ashes999
quelle

Antworten:

21

Eine andere Möglichkeit (für ganzzahlige Werte) besteht darin, eine zweite Elementvariable zu haben, die ein bitweises Komplement einer vorhandenen Variablen enthält.

Stell dir also vor health, du hättest es auch getan healthComplement. Ihre Implementierung könnte folgendermaßen aussehen:

// setter sets value and complement
void setHealth(int value){
    health = value;
    healthComplement = ~value;
}

// getter checks if value was changed outside of the setter
int getHealth(){
    if(value != ~healthComplement){
        // launch some cheat-counter-measure, like crashing the game?
        exit;
    }
    return health;
}

Jemand, der schummeln möchte, müsste Gesundheit und healthComplement richtig einstellen, sonst würde das Spiel abstürzen.

Ich finde es irgendwie sinnlos, solche Dinge zu verhindern. Die Leute haben erfolgreich Hacks / Cheats für viel komplexere Dinge erstellt und es verschleiert unnötigerweise Ihren Code oder verschlechtert die Leistung Ihres Spiels.

Blödmann
quelle
12

Hier ist ein Schema, das ich mir ausgedacht habe, als jemand vor langer Zeit an einem Brett darum gebeten hat. Die Verwendung von Prozentsätzen oder doppelten Variablen funktioniert nicht wirklich, da Sie nach "beliebigen" Werten suchen und diese einfrieren können.

Erstellen Sie stattdessen ein Monster eines Datentyps.

Grundsätzlich speichern Sie Ihre wichtigen Werte als Struktur mit:

  • 32 Zeiger auf Bits
  • Lassen Sie die Struktur zum schnellen Lesen auch den aktuellen Wert als einfaches Ganzes einschließen

Sammeln Sie zur Manipulation den aktuellen Wert aus den separat zugewiesenen Bits (die wahr / falsch sein können), ändern Sie den Wert und speichern Sie sie dann zurück.

Hier ist das böse Bit: Jedes Mal, wenn Sie den Wert manipulieren, geben Sie die Bits frei und weisen Sie sie erneut zu. Die Zuordnung sollte in zufälliger Reihenfolge erfolgen , damit die Daten im Speicher herumspringen und nicht einfach eingefroren werden können.

Zusätzliche Sicherheitsvorkehrungen wären das Speichern von Prüfsummen der Werte (sowie des "normalen" Int) und der Vergleich dieser Werte auch während der Manipulationsaufrufe. Wenn eine Nichtübereinstimmung festgestellt wird, tun Sie etwas Feines, z. B. einen zufälligen Schlüssel entfernen, der zum Entsperren von Türen erforderlich ist, um im Spiel Fortschritte zu erzielen.

Bearbeiten: Stellen Sie für weitere Speicherverschiebungen sicher, dass Sie die neuen "Bits" zuweisen, bevor Sie die alten freigeben.

Bearbeiten: Bei Multiplayer-Spielen ist es auch möglich, die Datenstruktur zu serialisieren, zu komprimieren und über das Netzwerk zu senden. Nicht die effizienteste Nutzung des Netzwerks, aber definitiv schwieriger durch Packet Sniffing herauszufinden.

Jari Komppa
quelle
9

Wie wäre es, wenn Sie den Gesundheitszustand zusammen mit einem zufälligen Wert speichern, der jedes Mal generiert wird, wenn Sie ihn speichern. Dies würde zumindest den einfachen Mechanismus des Suchens nach zunehmenden / abnehmenden Werten im Speicher zunichte machen, um die Gesundheit zu finden.

class Player
{
  int m_Health;
  int m_RandomHealth;
  Random m_Rnd = new Random();

  public int Health {
    get
    {
      return m_Health ^ m_RandomHealth;
    }

    set
    {
      m_RandomHealth = m_Rnd.Next();
      m_Health = value ^ m_RandomHealth;
    }
  }
}

Darüber hinaus möchten Sie möglicherweise den Wert für jeden Frame zurücksetzen, auch wenn sich der Zustand nicht ändert. Auf diese Weise wird verhindert, dass Personen nach geänderten Adressen suchen, wenn sich ihr Gesundheitszustand ändert und diese bei gleichem Gesundheitszustand gleich bleiben.

Bonus: Erstellen Sie jedes Mal ein neues Objekt, wenn es sich ändert, damit sich die Speicheradresse ändert, und stellen Sie den Zustand so ein, dass sich die Zufallszahl, der xored value und die Adresse im Speicher jedes Mal ändern, wenn Sie es lesen :

class Player
{
  int [] m_HealthArray; // [0] is random int, [1] is xored health
  Random m_Rnd = new Random();

  public Player() {
    this.Health = 100;
  }

  public int Health {
    get
    {
      int health = m_HealthArray[0] ^ m_HealthArray[1];
      Health = health; // reset to move in memory and change xor value
      return health;
    }

    set
    {
      m_HealthArray = new int[2];
      m_HealthArray[0] = m_Rnd.Next();
      m_HealthArray[1] = m_HealthArray[0] ^ value;
    }
  }
}
Jason Goemaat
quelle
8

Obwohl ich in meinem ersten Kommentar die Frage gestellt habe, ob die Erfahrung eines Teils Ihres Publikums ohne offensichtlichen Gewinn herabgesetzt werden soll, finde ich sie aus technischer Sicht immer noch interessant.

Ich hatte gerade die Idee: Was Betrüger tun, ist, Werte zu finden, die sich ändern und sie einfrieren. Die Suche würde dann nur zwischen Todesfällen oder Ereignissen stattfinden, die die Gesundheit des Spielers verändern. Darüber hinaus könnte der Betrüger die Suche verfeinern, indem er herausfiltert, was sich geändert hat, als er "nicht gestorben" war.

Was ist, wenn sich der "Gesundheits" -Zähler die ganze Zeit ändert? Machen Sie es zu einem Zeiger und ordnen Sie es jedem Frame oder allen N Frames neu zu, wenn der Performance-Hit zu groß ist. Oder XOR mit einem zufälligen Wert, der jeden Frame ändert (XOR wird erneut mit demselben Wert für die Entschlüsselung verglichen, bevor mit einem neuen zufälligen Wert verschlüsselt wird).

Wenn sich während des Spiels auch andere Daten ändern (einschließlich der x- und y-Position des Spielercharakters oder des Zeitzählers), ist es möglicherweise schwieriger herauszufinden, welche der sich ändernden Daten die Gesundheit sind. Und das Einfrieren des gesamten Spielzustands ist für den Betrüger kein Problem.

Zur weiteren Irreführung können Sie die Integrität in einer reinen Nur-Schreib-Variablen speichern, die als Honigtopf gedacht ist.

Bearbeiten :

Dennoch könnte der Betrüger versuchen herauszufinden, welche der Variablen, die sich die ganze Zeit ändern, diejenige ist, die durch Ausprobieren eingefroren werden kann. Eine mögliche Lösung wäre, die Variablen miteinander zu koppeln.

Ein Beispiel:

Anstatt Health (h) und Position (x) zu speichern, speichern Sie sie in zwei Variablen a und b, von denen Sie die Werte später abrufen können:

a = x+h; b = x-h
x = (a+b)/2; h = (a-b)/2

Auf diese Weise wird, wenn der Betrüger nur einen von ihnen einfriert und dann den Charakter bewegt, die Position beeinflusst und je nachdem, welcher eingefroren wurde, wird h negativ (sofortiger Tod). Sie können zwischen den obigen Formeln wechseln und:

a = x-h; b = x+h
x = (a+b)/2; h = (b-a)/2

In aufeinanderfolgenden Frames und Sie garantieren, dass in höchstens 2 Frames, nachdem eine der Variablen eingefroren wurde, der Zustand 0 wird, sobald sich x ändert. Denken Sie daran, dass Sie nur a und b speichern. Kombinieren Sie dies mit dem kontinuierlichen XOR wie oben erwähnt. Das Ergebnis ist eine Sammlung von Variablen, die jeden Frame in scheinbar zufällige Werte ändern, und das Einfrieren eines einzelnen oder einer Teilmenge davon führt nur zu unerwünschten Nebenwirkungen im Spiel, wobei der sofortige Tod einer von ihnen ist.

CeeJay
quelle
7

Eine mögliche Option, von der ich denke, dass sie funktioniert (ich bin mit diesen Betrugstools nicht allzu vertraut): Verstecke sie nicht. Führen Sie Ihre Operationen aus und erwarten Sie bestimmte Ergebnisse. Überprüfen Sie nach der Operation (möglicherweise im nächsten Bild), ob die Ergebnisse Ihren Erwartungen entsprechen. Wenn Sie die Integrität subtrahieren und dann überprüfen, um festzustellen, dass sie sich nie geändert hat, können Sie ziemlich sicher sein (vorausgesetzt, Sie haben keinen obskuren Fehler), dass sie gesperrt wurde.

Wenn Sie Betrug bemerken, können Sie jetzt die Spielregeln ändern, wenn Sie dies für eine maximale Trauer empfinden, sofern dies Ihre Absicht ist. Wenn Sie das Betrügen ignorieren möchten und das Spiel weiter funktionieren soll, ordnen Sie die Gesundheit an einer anderen Stelle im Speicher neu zu und ändern Sie Ihre Zeiger, sodass der neue Wert verwendet und der alte ignoriert wird. Wiederholen Sie ad infinitum.

James
quelle
6

Alle Versuche der bloßen Verschleierung scheitern in der Theorie, aber in der Praxis müssen Sie es nur schwer genug machen, um zu brechen, dass die Herausforderung weniger Spaß macht, als das Spiel zu bestehen. Ich weiß nicht, wie Ihr Spiel aussieht, deshalb werde ich nicht riskieren, Methoden zur Datenverschleierung vorzuschlagen, noch weniger, da ich glaube, dass sie sinnlos sind.

Das heißt, und Sie werden es wahrscheinlich nicht mögen , ich glaube, Sie suchen nach Memory Curtaining , einem Trusted-Computing- Konzept.

sam hocevar
quelle
3

Eine sehr effektive Technik, die von einigen Roguelikes (DoomRL, Brogue) verwendet wird, ist das Maskieren der tatsächlichen Variablen. Dies bedeutet, dass Gesundheit nicht als "2/10", sondern als "20%" angezeigt wird.

Denken Sie daran, dass die meisten Speichereditoren bei der Suche / Filterung nach bestimmten Werten gut funktionieren. Wenn Sie den spezifischen Wert nicht kennen, können Sie ihn dennoch aufspüren (z. B. nach geänderten / verringerten Werten suchen, nachdem die Gesundheit des Spielers gesunken ist), obwohl dies viel länger dauert.

Ich schlage auch eine Gegenreaktion vor. Wenn Sie beispielsweise ein Spiel haben, bei dem der Spieler einen nicht positiven Schaden erleidet und dessen Gesundheit nicht abfällt, können Sie dies einfach und genau überprüfen und wissen, dass der Spieler betrügt. Tun Sie etwas Interessantes, wie das Laichen einiger übermäßiger Feinde um ihn herum :)

ashes999
quelle
2

Schreiben Sie einen Ring 0-Treiber, der SSDT einbindet und protokolliert / blockiert, wenn ReadProcessMemory / WriteProcessMemory für Ihre Anwendung aufgerufen wird. Es ist besser, sich nur anzumelden, damit Sie das Spielverhalten im Laufe der Zeit langsam ändern können, anstatt nur abzustürzen.

Doug-W
quelle
Es hört sich so an, als würden Sie über Details der Implementierung auf niedriger Ebene sprechen (Windows-API?). Ich frage nach allgemeinen Strategien auf hoher Ebene.
Asche999
2

Warum sollten Sie Spieler daran hindern, sich selbst zu betrügen (was Betrug in einem Einzelspielerspiel bedeutet)? In einer Multiplayer-Umgebung ist es die Aufgabe des Servers, unnatürliche Änderungen zu erkennen und ihnen entgegenzuwirken (in der Regel indem er die Eingaben ignoriert oder den Schuldigen vollständig vom Server ausschließt) Bärendienst.

IOW, es sei denn, Sie erstellen ein Multiplayer-Spiel, es ist eine Geldverschwendung, und wenn Sie daran denken, den falschen Ort zu härten.

jwenting
quelle
2

Informieren Sie sich über die bekannten Cheat-Tools - und überprüfen Sie regelmäßig, ob eines der am häufigsten verwendeten Tools ausgeführt wird (Prozessnamen überprüfen?).

Wenn welche entdeckt werden, lassen Sie den Spieler schummeln (wenn er offline ist, ist es harmlos), aber stellen Sie sicher, dass keine Punkte / Erfolge auf einer Online-Rangliste / einem Erfolgungssystem veröffentlicht werden.

Hält entschlossenere Hacker nicht auf, verringert aber die Wahrscheinlichkeit, dass gelegentliche Cheats Ihre Bestenlisten durcheinander bringen.

(Könnte Codierer ärgern, die Entwicklerwerkzeuge zu legitimen Zwecken geöffnet und minimiert haben und dennoch eine Spielepause einlegen ...)

Bluescrn
quelle
7
Ich war ein großer Fan von Steam als Distributionsplattform und habe vor ein paar Jahren eine Menge von Team Fortress II gespielt. Eines Abends machte ich eine Pause von einer langen Codierungssitzung und ließ Visual Studio und einen Debugger offen, während ich spielte. Ich fand mich von TF2 wegen "Betrugs" gebannt. Keine Berufung, kein Rahmen für die Aufhebung eines Verbots. Ein "Vergehen" und es ist für das Konto dauerhaft. Ich habe immer noch keine Ahnung warum - und glaube mir, ich war wütend - außer dass ich tief in einer FAQ vergraben sah, dass das Öffnen eines "Speichereditors" während des Spiels Betrug bedeutete und verboten war. Wow.
1

Ich denke, die einfachste Lösung besteht darin, eine Cheat-Option zu implementieren. Deaktiviere die Wertung, während du die Cheat-Option aktivierst.

Eine weitere gute Idee, dass ich keine Ahnung habe, wie Sie das umsetzen würden. Ist das Spiel zu beenden, wenn es eine eingefrorene Speichervariable oder ähnliches gibt :)

Viel Glück)

HgMerk
quelle
3
Das Implementieren von Cheats ist eine gute Option. Beende das Spiel, nicht so sehr ... (Stell dir vor, du
verstehst