Unity-verduisteringsmethoden en anti-hackbescherming
Je hebt eindelijk de game uitgebracht waar je zo hard aan hebt gewerkt, en misschien zelfs een leaderboard toegevoegd om de game uit te dagen. Maar de dagen gaan voorbij en je merkt dat sommige spelers bovenaan het scorebord verschijnen met onrealistisch hoge scores. Je eerste gedachte is natuurlijk dat ze aan het hacken zijn, maar hoe doen ze dat?
Het antwoord is dat ze hoogstwaarschijnlijk een programma gebruiken om hun eigen waarden in het geheugen te injecteren, waarbij Cheat Engine het populairste van dergelijke programma's is. Bij games voor één speler doet hacken er eigenlijk niet zoveel toe, maar het wordt een probleem als het een multiplayer game is waarbij de andere spelers betrokken zijn.
In dit bericht laat ik zien hoe je je spel veiliger kunt maken tegen dergelijke aanvallen, wat op zijn beurt de ervaring voor niet-hackende spelers zal verbeteren.
OPMERKING: Dit artikel behandelt slechts kort de meest voorkomende aanvallen en de basisbescherming daartegen. Als je meer kant-en-klare oplossingen nodig hebt, bekijk dan gerust dit Asset Store pakket.
Als het gaat om hacken met Cheat Engine zijn er 2 meest voorkomende aanvallen: Speed Hacking en Value Scanning.
Snelheidshack
De Speed Hack is het gemakkelijkst uit te voeren (vereist slechts 2 klikken) en is meestal de eerste keuze voor beginnende gebruikers.
Speedhack werkt door de updatesnelheid van het spel te versnellen, waardoor alles sneller wordt, waardoor hackers een voorsprong krijgen op de spelers die op normale snelheid spelen.
Gelukkig is er een manier om deze hack te detecteren in Unity. Controleer het onderstaande script:
OPMERKING: Vanaf vandaag werkt deze methode niet meer, daarom is het detecteren van speedhack veel moeilijker geworden in games voor één speler. Multiplayer-spellen kunnen dit echter nog steeds doen door te vertrouwen op controles aan de serverzijde om eventuele discrepanties in de speler-servertijd te detecteren en de juiste actie te ondernemen (de speler schoppen/verbannen, enz.).
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.");
}
}
Het bovenstaande script vergelijkt de in-game tijd met de computer(systeem)tijd. Normaal gesproken worden beide tijden met dezelfde snelheid bijgewerkt (ervan uitgaande dat de Time.timeScale is ingesteld op 1), maar wanneer de SpeedHack is geactiveerd, versnelt deze de in-game updatefrequentie, waardoor de in -speeltijd accumuleert sneller.
Zodra het verschil tussen beide tijden te groot wordt (in dit geval 7 seconden, maar u kunt elke waarde kiezen, zorg er wel voor dat deze niet te klein is om valse positieven te voorkomen), roept het script de SpeedhackDetected() -methode aan die de aanwezigheid van SpeedHack signaleert.
Om het script te gebruiken, zorg ervoor dat het gekoppeld is aan elk object in de scène.
Waarde scannen
Waardenscannen is een proces waarbij relevante waarden in het toegewezen geheugen van het spel worden gevonden en deze met andere waarden worden overschreven. Meestal gebruikt om de gezondheid van de speler, wapenmunitie of een andere waarde die een hacker een oneerlijk voordeel in het spel zou geven, te verhogen.
Technisch gezien kan elke waarde in het spel worden overschreven/gewijzigd, maar betekent dit dat ze allemaal moeten worden beschermd? Niet noodzakelijk. Over het algemeen richten beginnende hackers zich alleen op de waarden die op het scherm worden weergegeven en waarvan bekend is waarvoor ze worden gebruikt (bijvoorbeeld de gezondheid van de speler, munitie, enz.). Meestal hoeven dus alleen "exposed"-waarden te worden beschermd.
In de bovenstaande schermafbeelding is bijvoorbeeld elke waarde op het scherm een potentieel doelwit voor hacking.
De vraag is dus: hoe kunnen we de belangrijke waarden beschermen tegen een Value Scanning-aanval? Het antwoord is Verduistering.
Verduistering is de handeling waarbij iets duister, onduidelijk of onbegrijpelijk wordt gemaakt.
Er zijn veel manieren om een variabele te verdoezelen, maar ik zal een methode gebruiken die ik Randomizer noem. De willekeurige waarde wordt aan het begin gegenereerd, vervolgens wordt de echte waarde ervan afgetrokken (vervolgens verborgen), en indien nodig wordt de verborgen waarde afgetrokken van een gegenereerde willekeurige waarde, waarbij het verschil het oorspronkelijke getal is. De sleutel is om ervoor te zorgen dat een waarde die op het scherm wordt weergegeven een totaal andere waarde heeft dan de variabele, waardoor hackers op een volledig verkeerde manier worden geleid bij het scannen.
- Maak een nieuw script, noem het 'SC_Obf' en plak de onderstaande code erin:
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;
}
}
Het bovenstaande script zal worden gebruikt om een willekeurig getal te genereren en twee eenvoudige methoden om de waarden te verdoezelen en te deobfusceren.
- Laten we nu naar een normaal voorbeeld van een script gaan zonder enige verwarring:
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");
}
}
Het bovenstaande script bevat twee eenvoudige variabelen: gezondheid (float) en munitie (int). Beide variabelen worden op het scherm weergegeven:
Deze manier van werken is eenvoudig en handig in termen van onderhoud, maar hackers zullen gemakkelijk de waarden kunnen scannen en overschrijven met behulp van Cheat Engine of soortgelijke software.
- Hier is hetzelfde script, maar met verduisteringsmethoden uit '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");
}
}
In plaats van de gezondheids- en munitievariabelen rechtstreeks te initialiseren, initialiseren we ze aan het begin in void Awake() (zorg ervoor dat u SC_Obf.Initialize() aanroept voordat u de waarden toewijst met SC_Obf.Obfuscate(value)).
Wanneer we de waarden vervolgens weergeven, deobfusceren we ze meteen door SC_Obf.Deobfuscate(value) aan te roepen, waardoor de echte waarden worden weergegeven.
De hacker zou proberen te zoeken naar 100 en 30, maar zou ze niet kunnen vinden omdat de echte waarden totaal verschillend zijn.
Om de versluierde waarden te manipuleren (bijvoorbeeld het aftrekken van gezondheid) maken we eerst de waarde onleesbaar, trekken vervolgens de benodigde waarde af en verduisteren vervolgens het eindresultaat.
Voor een meer geavanceerde oplossing kun je dit Asset Store pakket raadplegen.