यूनिटी ऑबफस्केशन मेथड्स और एंटी-हैक प्रोटेक्शन

आपने अंततः गेम जारी कर दिया जिस पर आप बहुत मेहनत कर रहे थे, और शायद गेम में चुनौती जोड़ने के लिए एक लीडरबोर्ड भी जोड़ा। लेकिन दिन बीतते हैं और आप देखते हैं कि कुछ खिलाड़ी अवास्तविक रूप से उच्च स्कोर के साथ स्कोरबोर्ड के शीर्ष पर आ रहे हैं। आपका पहला विचार यह है कि बेशक वे हैकिंग कर रहे हैं, लेकिन वे ऐसा कैसे करते हैं?

इसका उत्तर यह है कि, संभवतः वे मेमोरी में अपने स्वयं के मूल्यों को इंजेक्ट करने के लिए एक प्रोग्राम का उपयोग कर रहे हैं, ऐसे प्रोग्रामों में सबसे लोकप्रिय है चीट इंजन। अब, एकल-खिलाड़ी गेम में, हैकिंग वास्तव में उतना मायने नहीं रखती है, लेकिन यह एक समस्या बन जाती है जब यह मल्टीप्लेयर गेम होता है जहां अन्य खिलाड़ी शामिल होते हैं।

इस पोस्ट में, मैं दिखाऊंगा कि ऐसे हमलों के खिलाफ अपने गेम को और अधिक सुरक्षित कैसे बनाया जाए, जिससे गैर-हैकिंग खिलाड़ियों के अनुभव में सुधार होगा।

ध्यान दें: यह लेख केवल सबसे आम हमलों और उनके खिलाफ बुनियादी सुरक्षा को संक्षेप में कवर करता है। यदि आपको अधिक आउट-ऑफ-द-बॉक्स समाधान की आवश्यकता है तो बेझिझक इस Asset Store पैकेज को जांचें।

जब चीट इंजन के साथ हैकिंग की बात आती है तो 2 सबसे आम हमले होते हैं: स्पीड हैकिंग और वैल्यू स्कैनिंग।

गति को हैक करना

निष्पादित करने में सबसे आसान (केवल 2 क्लिक की आवश्यकता) होने के कारण, स्पीड हैक आमतौर पर नौसिखिए उपयोगकर्ताओं के लिए पहली पसंद है।

स्पीड हैक गेम की अपडेट दर को तेज़ करके काम करता है, जिससे सब कुछ तेज़ हो जाता है, जिससे हैकर्स को सामान्य गति से खेलने वाले खिलाड़ियों पर बढ़त मिल जाती है।

सौभाग्य से, Unity में इस हैक का पता लगाने का एक तरीका है। नीचे दी गई स्क्रिप्ट की जाँच करें:

ध्यान दें: आज तक, यह विधि अब काम नहीं करती है, इसलिए, एकल-खिलाड़ी गेम में स्पीड हैक का पता लगाना अधिक कठिन हो गया है। हालाँकि, मल्टीप्लेयर गेम अभी भी खिलाड़ी-सर्वर समय में किसी भी बेमेल का पता लगाने और उचित कार्रवाई (खिलाड़ी को लात मारना/प्रतिबंधित करना, आदि) करने के लिए सर्वर-साइड जांच पर भरोसा करके ऐसा करने में सक्षम हैं।

SC_स्पीडहैकडिटेक्टर.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.");
    }
}

उपरोक्त स्क्रिप्ट गेम के समय की तुलना कंप्यूटर (सिस्टम) के समय से करती है। आम तौर पर दोनों समय एक ही दर पर अपडेट किए जाते हैं (यह मानते हुए कि Time.timeScale को 1 पर सेट किया गया है), लेकिन जब स्पीडहैक सक्रिय होता है, तो यह इन-गेम अपडेट आवृत्ति को तेज कर देता है, जिससे इन-गेम समय जमा हो जाता है और तेज।

एक बार जब दोनों समय के बीच का अंतर बहुत अधिक हो जाता है (इस मामले में 7 सेकंड, लेकिन आप कोई भी मान चुन सकते हैं, बस सुनिश्चित करें कि झूठी सकारात्मकता से बचने के लिए यह बहुत छोटा नहीं है) स्क्रिप्ट स्पीडहैकडिटेक्टेड() विधि को कॉल करती है जो स्पीडहैक की उपस्थिति का संकेत देती है।

स्क्रिप्ट का उपयोग करने के लिए सुनिश्चित करें कि यह दृश्य में किसी भी ऑब्जेक्ट से अटैच्ड है।

मूल्य स्कैनिंग

वैल्यू स्कैनिंग गेम की आवंटित मेमोरी में प्रासंगिक मान ढूंढने और उन्हें विभिन्न मानों के साथ ओवरराइट करने की एक प्रक्रिया है। आमतौर पर खिलाड़ी के स्वास्थ्य, हथियार बारूद, या किसी भी मूल्य को बढ़ाने के लिए उपयोग किया जाता है जो हैकर को गेम में अनुचित लाभ देगा।

तकनीकी रूप से कहें तो, खेल में प्रत्येक मान को अधिलेखित/बदला जा सकता है, लेकिन क्या इसका मतलब यह है कि उन सभी को संरक्षित करने की आवश्यकता है? आवश्यक रूप से नहीं। आम तौर पर, नौसिखिया हैकर केवल उन मानों को लक्षित करते हैं जो स्क्रीन पर प्रदर्शित होते हैं और जानते हैं कि उनका उपयोग किस लिए किया जाता है (उदाहरण के लिए खिलाड़ी का स्वास्थ्य, बारूद, आदि)। इसलिए अधिकांश समय केवल "exposed" मानों को संरक्षित करने की आवश्यकता होती है।

यूनिटी एफपीएस गेम स्क्रीनशॉट

उदाहरण के लिए ऊपर दिए गए स्क्रीनशॉट में, स्क्रीन पर प्रत्येक मान हैकिंग के लिए एक संभावित लक्ष्य है।

तो सवाल यह है कि वैल्यू स्कैनिंग हमले के खिलाफ महत्वपूर्ण मूल्यों की रक्षा कैसे करें? उत्तर है आक्षेप.

अस्पष्टीकरण किसी चीज़ को अस्पष्ट, अस्पष्ट या समझ से परे बनाने की क्रिया है।

किसी वेरिएबल को अस्पष्ट करने के कई तरीके हैं, लेकिन मैं एक विधि का उपयोग करूंगा जिसे मैं Randomizer कहता हूं। प्रारंभ में यादृच्छिक मान उत्पन्न होता है, फिर वास्तविक मान को इसमें से घटा दिया जाता है (बाद में इसे छिपा दिया जाता है), फिर आवश्यकता पड़ने पर, छिपे हुए मान को उत्पन्न यादृच्छिक मान से घटा दिया जाता है, जिसमें मूल संख्या का अंतर होता है। मुख्य बात यह है कि स्क्रीन पर प्रदर्शित होने वाला मान वेरिएबल से पूरी तरह से अलग होता है, जिससे स्कैन करते समय हैकर्स पूरी तरह से गलत तरीके से आगे बढ़ते हैं।

  • एक नई स्क्रिप्ट बनाएं, इसे 'SC_Obf' कहें और इसके अंदर नीचे दिया गया कोड पेस्ट करें:

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

उपरोक्त स्क्रिप्ट का उपयोग एक यादृच्छिक संख्या उत्पन्न करने के लिए किया जाएगा और मूल्यों को अस्पष्ट और स्पष्ट करने के लिए 2 सरल तरीकों का उपयोग किया जाएगा।

  • आइए अब बिना किसी लाग-लपेट के स्क्रिप्ट के एक नियमित उदाहरण की ओर बढ़ते हैं:
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");
    }
}

उपरोक्त स्क्रिप्ट में 2 सरल चर हैं: स्वास्थ्य (फ्लोट) और बारूद (इंट)। दोनों चर स्क्रीन पर प्रदर्शित होते हैं:

चीजों को करने का यह तरीका रखरखाव के मामले में सरल और सुविधाजनक है, लेकिन हैकर्स आसानी से मूल्यों को स्कैन करने और चीट इंजन या इसी तरह के सॉफ़्टवेयर का उपयोग करके उन्हें ओवरराइट करने में सक्षम होंगे।

  • यहां वही स्क्रिप्ट है, लेकिन '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");
    }
}

स्वास्थ्य और बारूद चर को सीधे प्रारंभ करने के बजाय, हम उन्हें प्रारंभ में void Awake() में प्रारंभ करते हैं ( का उपयोग करके मान निर्दिष्ट करने से पहले SC_Obf.Initialize() को कॉल करना सुनिश्चित करें SC_Obf.Obfuscat(मान)).

फिर मूल्यों को प्रदर्शित करते समय, हम SC_Obf.Deobfusate(value) पर कॉल करके तुरंत उन्हें स्पष्ट कर देते हैं और इस प्रकार वास्तविक मान प्रदर्शित करते हैं।

हैकर 100 और 30 को खोजने का प्रयास करेगा लेकिन उन्हें ढूंढ नहीं पाएगा क्योंकि वास्तविक मान पूरी तरह से अलग हैं।

अस्पष्ट मूल्यों में हेरफेर करने के लिए (उदा. स्वास्थ्य को घटाना) हम पहले मूल्य को अस्पष्ट करते हैं, फिर आवश्यक मूल्य घटाते हैं और फिर अंतिम परिणाम को अस्पष्ट करते हैं।

अधिक उन्नत समाधान के लिए बेझिझक इस Asset Store पैकेज को जांचें।