Unity Gizleme Yöntemleri ve Saldırıya Karşı Koruma

Sonunda üzerinde çok çalıştığınız oyun'ü yayınladınız ve hatta oyuna meydan okuma eklemek için bir liderlik tablosu bile eklediniz. Ancak günler geçtikçe bazı oyuncuların gerçekçi olmayan yüksek puanlarla puan tablosunun en üstünde belirdiğini fark ediyorsunuz. İlk düşünceniz tabii ki hackliyorlar ama bunu nasıl yapıyorlar?

Cevap şu ki, büyük olasılıkla kendi değerlerini belleğe enjekte etmek için bir program kullanıyorlar; bu tür programların en popüler olanı Cheat Engine'dir. Şimdi, tek oyunculu oyunlarda hackleme o kadar da önemli değil, ancak diğer oyuncuların dahil olduğu çok oyunculu bir oyun olduğunda sorun haline geliyor.

Bu yazıda oyununuzu bu tür saldırılara karşı nasıl daha güvenli hale getirebileceğinizi göstereceğim, bu da bilgisayar korsanlığı yapmayan oyuncuların deneyimini geliştirecektir.

NOT: Bu makale yalnızca en yaygın saldırıları ve bunlara karşı temel korumayı kısaca kapsamaktadır. Daha fazla alışılmış çözüme ihtiyacınız varsa bu Asset Store Paketini kontrol etmekten çekinmeyin.

Cheat Engine ile hacklemeye gelince en yaygın 2 saldırı vardır: Hızlı Hackleme ve Değer Tarama.

Hız hilesi

Yürütülmesi en kolay olan (yalnızca 2 tıklama gerektirir), Speed ​​Hack genellikle acemi kullanıcılar için ilk tercihtir.

Speed ​​hack, oyunun güncelleme hızını hızlandırarak çalışır, her şeyi daha hızlı hale getirir, böylece bilgisayar korsanlarına normal hızda oynayan oyunculara karşı avantaj sağlar.

Neyse ki Unity'te bu hack'i tespit etmenin bir yolu var. Aşağıdaki betiği kontrol edin:

NOT: Bugün itibariyle bu yöntem artık işe yaramamaktadır, bu nedenle tek oyunculu oyunlarda speed hack'i tespit etmek çok daha zor hale gelmiştir. Ancak çok oyunculu oyunlar, oyuncu-sunucu zamanındaki herhangi bir uyumsuzluğu tespit etmek ve uygun eylemi (oyuncuyu tekmelemek/yasaklamak vb.) gerçekleştirmek için sunucu tarafı kontrollerine güvenerek bunu hâlâ yapabilir.

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.");
    }
}

Yukarıdaki komut dosyası oyun içi zamanı bir bilgisayarın (sistem) zamanı ile karşılaştırır. Normalde her iki zaman da aynı oranda güncellenir (Time.timeScale değerinin 1'e ayarlandığı varsayılarak), ancak SpeedHack etkinleştirildiğinde oyun içi güncelleme sıklığını hızlandırarak oyun içi sürenin birikmesini sağlar Daha hızlı.

Her iki zaman arasındaki fark çok büyük hale geldiğinde (bu durumda 7 saniye, ancak herhangi bir değeri seçebilirsiniz, yalnızca yanlış pozitifleri önlemek için çok küçük olmadığından emin olun), komut dosyası SpeedHack'in varlığını işaret eden SpeedhackDetected() yöntemini çağırır.

Komut dosyasını kullanmak için, Sahnedeki herhangi bir Nesneye ekli olduğundan emin olun.

Değer Tarama

Değer tarama, oyunun ayrılmış hafızasındaki ilgili değerleri bulma ve bunların üzerine farklı değerler yazma işlemidir. En yaygın olarak oyuncu Sağlığını, Silah Cephanesini veya bir bilgisayar korsanına oyunda haksız avantaj sağlayacak herhangi bir değeri artırmak için kullanılır.

Teknik olarak konuşursak, oyundaki her değerin üzerine yazılabilir/değiştirilebilir, ancak bu, hepsinin korunması gerektiği anlamına mı gelir? Şart değil. Genellikle acemi hackerlar sadece ekranda görüntülenen ve ne için kullanıldığı bilinen değerleri (Örneğin oyuncu sağlığı, cephane vb.) hedef alır. Yani çoğu zaman sadece "exposed" değerlerinin korunması gerekiyor.

Unity FPS Oyunu Ekran Görüntüsü

Örneğin yukarıdaki ekran görüntüsünde ekrandaki her değer, bilgisayar korsanlığı için potansiyel bir hedeftir.

Öyleyse asıl soru, önemli değerlerin Değer Tarama saldırısına karşı nasıl korunacağıdır? Cevap Şaşırtma.

Şaşırtma bir şeyi belirsiz, belirsiz veya anlaşılmaz hale getirme eylemidir.

Bir değişkeni gizlemenin birçok yolu vardır, ancak ben Randomizer adını verdiğim bir yöntem kullanacağım. Başlangıçta rastgele değer üretilir, ardından gerçek değer bundan çıkarılır (sonradan gizlenir), daha sonra ihtiyaç duyulduğunda gizli değer, orijinal sayı farkıyla oluşturulan rastgele değerden çıkarılır. Önemli olan, ekranda görüntülenen bir değerin değişkenden tamamen farklı bir değere sahip olmasıdır, bu da bilgisayar korsanlarını tarama sırasında tamamen yanlış bir yola yönlendirir.

  • Yeni bir komut dosyası oluşturun, onu 'SC_Obf' olarak adlandırın ve içine aşağıdaki kodu yapıştırın:

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;
    }
}

Yukarıdaki komut dosyası, rastgele bir sayı oluşturmak ve değerleri gizlemek ve gizlemeyi kaldırmak için 2 basit yöntem oluşturmak için kullanılacaktır.

  • Şimdi herhangi bir kafa karışıklığı yaratmadan normal bir komut dosyası örneğine geçelim:
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");
    }
}

Yukarıdaki komut dosyası 2 basit değişken içerir: sağlık (float) ve cephane (int). Her iki değişken de ekranda görüntülenir:

İşleri bu şekilde yapmanın bakım açısından basit ve kullanışlı olması, ancak bilgisayar korsanları değerleri kolayca tarayabilecek ve Cheat Engine veya benzeri bir yazılım kullanarak bunların üzerine yazabilecektir.

  • İşte aynı komut dosyası, ancak 'SC_Obf.cs':'deki gizleme yöntemlerini kullanıyor
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");
    }
}

Sağlık ve cephane değişkenlerini doğrudan başlatmak yerine, bunları başlangıçta void Awake() ile başlatırız ( kullanarak değerleri atamadan önce SC_Obf.Initialize() 'i çağırdığınızdan emin olun. SC_Obf.Obfuscate(değer)).

Daha sonra değerleri görüntülerken, SC_Obf.Deobfuscate(value)'i çağırarak ve böylece gerçek değerleri görüntüleyerek, anında bunların gizliliğini kaldırırız.

Bilgisayar korsanı 100 ve 30'i aramaya çalışır ancak gerçek değerler tamamen farklı olduğundan bunları bulamaz.

Gizlenmiş değerleri değiştirmek için (örneğin sağlığı çıkarmak), önce değerin gizliliğini kaldırırız, sonra gerekli değeri çıkarırız, ardından nihai sonucu geri gizleriz.

Daha gelişmiş bir çözüm için bu Asset Store Paketini kontrol etmekten çekinmeyin.