Unity obfuscation Methods og Anti-Hack Protection
Du har endelig frigivet spillet, som du har arbejdet så hårdt på, og måske endda tilføjet et leaderboard for at tilføje en udfordring til spillet. Men dagene går, og du bemærker, at nogle spillere dukker op på toppen af resultattavlen med urealistisk høje scores. Din første tanke er selvfølgelig, at de hacker, men hvordan gør de det?
Svaret er, at de højst sandsynligt bruger et program til at indsprøjte deres egne værdier i hukommelsen, hvor det mest populære af sådanne programmer er Cheat Engine. I singleplayer spil betyder hacking egentlig ikke så meget, men det bliver et problem, når det er et multiplayer spil, hvor de andre spillere er involveret.
I dette indlæg vil jeg vise, hvordan du gør dit spil mere sikkert mod sådanne angreb, hvilket igen vil forbedre oplevelsen for ikke-hackende spillere.
BEMÆRK: Denne artikel dækker kun kort de mest almindelige angreb og grundlæggende beskyttelse mod dem. Hvis du har brug for mere out-of-the-box løsning, er du velkommen til at tjekke denne Asset Store Pakke.
Når det kommer til hacking med Cheat Engine, er der 2 mest almindelige angreb: Speed Hacking og Value Scanning.
Speed Hack
Da det er det nemmeste at udføre (kræver kun 2 klik), er Speed Hack normalt det første valg for nybegyndere.
Speed hack virker ved at fremskynde spillets opdateringshastighed, hvilket gør alting hurtigere, og giver dermed hackere et forspring i forhold til de spillere, der spiller med normal hastighed.
Heldigvis er der en måde at opdage dette hack i Unity. Tjek nedenstående script:
BEMÆRK: Fra i dag virker denne metode ikke længere, derfor er det blevet meget vanskeligere at opdage speed hack i single-player spil. Multiplayer-spil er dog stadig i stand til at gøre det ved at stole på server-side-checks for at detektere ethvert misforhold i spiller-server-tiden og tage den passende handling (sparke/banne spilleren osv.).
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.");
}
}
Scriptet ovenfor sammenligner tiden i spillet med en computers (system) tid. Normalt opdateres begge tidspunkter med samme hastighed (forudsat at Time.timeScale er sat til 1), men når SpeedHack er aktiveret, accelererer det opdateringsfrekvensen i spillet, hvilket får tiden til at akkumulere i spillet. hurtigere.
Når forskellen mellem begge tidspunkter bliver for stor (i dette tilfælde 7 sekunder, men du kan vælge en hvilken som helst værdi, skal du bare sikre dig, at den ikke er for lille til at undgå falske positiver), kalder scriptet SpeedhackDetected() metoden, som signalerer tilstedeværelsen af SpeedHack.
For at bruge scriptet skal du sørge for, at det er vedhæftet til ethvert objekt i scenen.
Værdiscanning
Værdiscanning er en proces med at finde relevante værdier i spillets tildelte hukommelse og overskrive dem med forskellige værdier. Mest almindeligt brugt til at øge spillerens sundhed, våbenammunition eller enhver værdi, der ville give en hacker en uretfærdig fordel i spillet.
Teknisk set kan enhver værdi i spillet overskrives/ændres, men betyder det, at de alle skal beskyttes? Ikke nødvendigvis. Generelt målretter begyndere hackere kun de værdier, der vises på skærmen og ved, hvad de bruges til (For eksempel spillersundhed, ammunition osv.). Så det meste af tiden skal kun "exposed"-værdier beskyttes.
For eksempel på skærmbilledet ovenfor er hver værdi på skærmen et potentielt mål for hacking.
Så spørgsmålet er, hvordan man beskytter de vigtige værdier mod et Value Scanning-angreb? Svaret er Obfuscation.
Tilsløring er handlingen med at gøre noget uklart, uklart eller uforståeligt.
Der er mange måder at sløre en variabel på, men jeg vil bruge en metode, som jeg kalder Randomizer. Den tilfældige værdi genereres i starten, derefter trækkes den reelle værdi fra den (efterfølgende skjules den), og efter behov trækkes den skjulte værdi fra en genereret tilfældig værdi, hvor en forskel er det oprindelige tal. Nøglen er at have en værdi, der vises på skærmen, til at have en helt anden værdi end variablen, hvilket fører hackere på en helt forkert måde, når de scanner.
- Opret et nyt script, kald det 'SC_Obf', og indsæt koden nedenfor i det:
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;
}
}
Scriptet ovenfor vil blive brugt til at generere et tilfældigt tal og 2 simple metoder til at sløre og deobfuskere værdierne.
- Lad os nu gå til et almindeligt eksempel på et script uden nogen form for sløring:
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");
}
}
Scriptet ovenfor indeholder 2 simple variabler: sundhed (float) og ammunition (int). Begge variabler vises på skærmen:
Denne måde at gøre tingene på er enkel og bekvem i forhold til vedligeholdelse, men hackere vil nemt kunne scanne værdierne og overskrive dem ved hjælp af Cheat Engine eller lignende software.
- Her er det samme script, men ved at bruge sløringsmetoder fra '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");
}
}
I stedet for at initialisere sundheds- og ammunitionsvariabler direkte, initialiserer vi dem ved starten i void Awake() (Sørg for at kalde SC_Obf.Initialize() før du tildeler værdierne ved hjælp af SC_Obf.Obfuscate(værdi)).
Når vi derefter viser værdierne, deobfuskerer vi dem i farten ved at kalde SC_Obf.Deobfuscate(value) og viser dermed de reelle værdier.
Hackeren ville prøve at søge efter 100 og 30, men ville ikke være i stand til at finde dem, fordi de virkelige værdier er helt anderledes.
For at manipulere de slørede værdier (f.eks. subtrahering af sundhed) deobfuskerer vi først værdien, trækker derefter den nødvendige værdi fra og slører det endelige resultat tilbage.
For en mere avanceret løsning er du velkommen til at tjekke denne Asset Store Pakke.