Unity-Verschleierungsmethoden und Anti-Hack-Schutz
Sie haben endlich das -Spiel veröffentlicht, an dem Sie so hart gearbeitet haben, und vielleicht sogar eine -Bestenliste hinzugefügt, um das Spiel herausfordernder zu machen. Aber die Tage vergehen und man bemerkt, dass einige Spieler mit unrealistisch hohen Punktzahlen ganz oben auf der Anzeigetafel auftauchen. Ihr erster Gedanke ist natürlich, dass sie hacken, aber wie machen sie das?
Die Antwort ist, dass sie höchstwahrscheinlich ein Programm verwenden, um ihre eigenen Werte in den Speicher einzufügen. Das beliebteste dieser Programme ist Cheat Engine. Bei Einzelspieler-Spielen spielt das Hacken keine so große Rolle, wird aber zum Problem, wenn es sich um ein mehrspieler-Spiel handelt, an dem die anderen Spieler beteiligt sind.
In diesem Beitrag werde ich zeigen, wie Sie Ihr Spiel vor solchen Angriffen schützen können, was wiederum das Spielerlebnis für Nicht-Hacker-Spieler verbessert.
HINWEIS: Dieser Artikel behandelt nur kurz die häufigsten Angriffe und den grundlegenden Schutz davor. Wenn Sie weitere sofort einsatzbereite Lösungen benötigen, können Sie sich dieses Asset Store-Paket ansehen.
Beim Hacken mit der Cheat Engine gibt es zwei häufigste Angriffe: Speed Hacking und Value Scanning.
Speed-Hack
Der Speed Hack ist am einfachsten auszuführen (erfordert nur 2 Klicks) und ist in der Regel die erste Wahl für unerfahrene Benutzer.
Speed Hack funktioniert, indem es die Aktualisierungsrate des Spiels beschleunigt, wodurch alles schneller wird und Hackern so einen Vorteil gegenüber den Spielern verschafft, die mit normaler Geschwindigkeit spielen.
Glücklicherweise gibt es eine Möglichkeit, diesen Hack in Unity zu erkennen. Überprüfen Sie das folgende Skript:
HINWEIS: Ab heute funktioniert diese Methode nicht mehr, daher ist die Erkennung von Speed-Hacks in Einzelspieler-Spielen viel schwieriger geworden. Multiplayer-Spiele sind jedoch immer noch in der Lage, dies zu tun, indem sie sich auf serverseitige Überprüfungen verlassen, um Unstimmigkeiten in der Spieler-Server-Zeit zu erkennen und die entsprechenden Maßnahmen zu ergreifen (Spieler rauswerfen/sperren usw.).
SC_SpeedhackDetector.cs
using UnityEngine;
using System;
public class SC_SpeedhackDetector : MonoBehaviour
{
//Speed hack protection
public int timeDiff = 0;
int previousTime = 0;
int realTime = 0;
float gameTime = 0;
bool detected = false;
// Use this for initialization
void Start()
{
previousTime = DateTime.Now.Second;
gameTime = 1;
}
// Update is called once per frame
void FixedUpdate()
{
if (previousTime != DateTime.Now.Second)
{
realTime++;
previousTime = DateTime.Now.Second;
timeDiff = (int)gameTime - realTime;
if (timeDiff > 7)
{
if (!detected)
{
detected = true;
SpeedhackDetected();
}
}
else
{
detected = false;
}
}
gameTime += Time.deltaTime;
}
void SpeedhackDetected()
{
//Speedhack was detected, do something here (kick player from the game etc.)
print("Speedhack detected.");
}
}
Das obige Skript vergleicht die Spielzeit mit der Zeit eines Computers (Systems). Normalerweise werden beide Zeiten mit der gleichen Rate aktualisiert (vorausgesetzt, Time.timeScale ist auf 1 gesetzt), aber wenn der SpeedHack aktiviert ist, beschleunigt er die Aktualisierungshäufigkeit im Spiel, wodurch sich die Zeit im Spiel summiert Schneller.
Sobald der Unterschied zwischen beiden Zeiten zu groß wird (in diesem Fall 7 Sekunden, aber Sie können einen beliebigen Wert wählen, stellen Sie nur sicher, dass er nicht zu klein ist, um Fehlalarme zu vermeiden), ruft das Skript die Methode SpeedhackDetected() auf, die das Vorhandensein von SpeedHack signalisiert.
Um das Skript zu verwenden, stellen Sie sicher, dass es angehängt an ein beliebiges Objekt in der Szene ist.
Wertscannen
Beim Wertscannen handelt es sich um einen Prozess, bei dem relevante Werte im zugewiesenen Speicher des Spiels gefunden und mit anderen Werten überschrieben werden. Wird am häufigsten verwendet, um die Gesundheit des Spielers, die Waffenmunition oder jeden anderen Wert zu erhöhen, der einem Hacker einen unfairen Vorteil im Spiel verschaffen würde.
Technisch gesehen kann jeder Wert im Spiel überschrieben/geändert werden, aber bedeutet das, dass alle geschützt werden müssen? Nicht unbedingt. Im Allgemeinen zielen unerfahrene Hacker nur auf die Werte ab, die auf dem Bildschirm angezeigt werden und von denen sie wissen, wofür sie verwendet werden (zum Beispiel die Gesundheit des Spielers, die Munition usw.). Daher müssen meistens nur "exposed"-Werte geschützt werden.
Im Screenshot oben ist beispielsweise jeder Wert auf dem Bildschirm ein potenzielles Angriffsziel.
Die Frage ist also, wie man die wichtigen Werte vor einem Value-Scanning-Angriff schützt. Die Antwort ist Verschleierung.
Verschleierung ist die Aktion, etwas unklar, unklar oder unverständlich zu machen.
Es gibt viele Möglichkeiten, eine Variable zu verschleiern, aber ich verwende eine Methode, die ich Randomizer nenne. Der Zufallswert wird zu Beginn generiert, dann wird der reale Wert davon subtrahiert (und anschließend ausgeblendet) und bei Bedarf wird der verborgene Wert von einem generierten Zufallswert subtrahiert, wobei eine Differenz die ursprüngliche Zahl ist. Der Schlüssel besteht darin, dass ein Wert, der auf dem Bildschirm angezeigt wird, einen völlig anderen Wert als die Variable hat, was Hacker beim Scannen auf eine völlig falsche Art und Weise verleitet.
- Erstellen Sie ein neues Skript, nennen Sie es 'SC_Obf' und fügen Sie den folgenden Code ein:
SC_Obf.cs
using UnityEngine;
public class SC_Obf : MonoBehaviour
{
static float random = -1;
public static void Initialize()
{
if(random == -1)
{
random = Random.Range(10000, 99999);
}
}
public static float Obfuscate(float originalValue)
{
return random - originalValue;
}
public static float Deobfuscate(float obfuscatedValue)
{
return random - obfuscatedValue;
}
}
Das obige Skript wird verwendet, um eine Zufallszahl und zwei einfache Methoden zum Verschleiern und Entschleieren der Werte zu generieren.
- Kommen wir nun zu einem regulären Beispiel eines Skripts ohne jegliche Verschleierung:
using UnityEngine;
public class SC_Test : MonoBehaviour
{
public float health = 100;
public int ammo = 30;
public void Damage(float points)
{
health -= points;
}
void OnGUI()
{
GUI.Label(new Rect(5, 5, 150, 25), health + " HP");
GUI.Label(new Rect(5, 30, 150, 25), ammo + " Ammo");
}
}
Das obige Skript enthält zwei einfache Variablen: Gesundheit (float) und Munition (int). Beide Variablen werden auf dem Bildschirm angezeigt:
Diese Vorgehensweise ist im Hinblick auf die Wartung einfach und bequem, Hacker können die Werte jedoch leicht scannen und sie mit Cheat Engine oder ähnlicher Software überschreiben.
- Hier ist das gleiche Skript, aber mit Verschleierungsmethoden aus 'SC_Obf.cs':
using UnityEngine;
public class SC_Test : MonoBehaviour
{
public float health;
public int ammo;
void Awake()
{
SC_Obf.Initialize();
health = SC_Obf.Obfuscate(100);
ammo = (int)SC_Obf.Obfuscate(30);
}
public void Damage(float points)
{
health = SC_Obf.Obfuscate(SC_Obf.Deobfuscate(health) - points);
}
void OnGUI()
{
GUI.Label(new Rect(5, 5, 150, 25), SC_Obf.Deobfuscate(health) + " HP");
GUI.Label(new Rect(5, 30, 150, 25), SC_Obf.Deobfuscate(ammo) + " Ammo");
}
}
Anstatt Gesundheits- und Munitionsvariablen direkt zu initialisieren, initialisieren wir sie zu Beginn in void Awake() (Stellen Sie sicher, dass Sie SC_Obf.Initialize() aufrufen, bevor Sie die Werte mit zuweisen) SC_Obf.Obfuscate(value)).
Wenn wir die Werte dann anzeigen, entschlüsseln wir sie im Handumdrehen, indem wir SC_Obf.Deobfuscate(value) aufrufen und so die tatsächlichen Werte anzeigen.
Der Hacker würde versuchen, nach 100 und 30 zu suchen, könnte sie aber nicht finden, da die tatsächlichen Werte völlig unterschiedlich sind.
Um die verschleierten Werte zu manipulieren (z. B. die Gesundheit zu subtrahieren), entschleieren wir zunächst den Wert, subtrahieren dann den benötigten Wert und verschleiern dann das Endergebnis wieder.
Für eine fortgeschrittenere Lösung schauen Sie sich bitte dieses Asset Store Paket an.