धोखा देने के लिए मेमोरी संपादकों को हराने की रणनीतियाँ - डेस्कटॉप गेम्स [बंद]


35

मैं मान रहा हूं कि हम डेस्कटॉप गेम के बारे में बात कर रहे हैं - कुछ खिलाड़ी डाउनलोड करते हैं और अपने स्थानीय कंप्यूटर पर चलाते हैं। कई स्मृति संपादक हैं जो आपको अपने खिलाड़ी के स्वास्थ्य की तरह मूल्यों का पता लगाने और स्थिर करने की अनुमति देते हैं।

आप मेमोरी-मॉडिफिकेशन के माध्यम से धोखा कैसे रोक सकते हैं? इस तरह की धोखाधड़ी से निपटने के लिए कौन सी रणनीतियां प्रभावी हैं?

संदर्भ के लिए, मुझे पता है कि खिलाड़ी कर सकते हैं: - मान या श्रेणी के आधार पर किसी चीज़ की खोज करें - किसी ऐसी चीज़ की खोज करें जो मूल्य बदल दे - स्मृति मान सेट करें - मुफ्त डाउनलोड मान

मैं कुछ अच्छे लोगों की तलाश कर रहा हूं। दो मैं जो औसत दर्जे का उपयोग कर रहे हैं:

  • मानों को संख्या के बजाय प्रतिशत के रूप में प्रदर्शित करना (जैसे। 46/50 = 92% स्वास्थ्य)
  • एक निम्न-स्तरीय वर्ग जो एक सरणी में मान रखता है और प्रत्येक परिवर्तन के साथ उन्हें स्थानांतरित करता है। (उदाहरण के लिए, एक इंट के बजाय, मेरे पास एक वर्ग है जो कि एक सरणी है, और जब भी मूल्य में परिवर्तन होता है, तो मैं मान रखने के लिए एक अलग, यादृच्छिक रूप से चयनित सरणी आइटम का उपयोग करता हूं)

खेल ऑफ़लाइन, नि: शुल्क और एकल-खिलाड़ी है।

संपादित करें: पोस्टीरिटी के लिए, मैंने इसे (C # में) हल किया और अपना समाधान यहां , अपने ब्लॉग पर पोस्ट किया।

जवाबों:


21

एक अन्य संभावना (पूर्णांक मानों के लिए) में एक दूसरा सदस्य-चर होना चाहिए जो मौजूदा चर का एक बिटवाइज़ पूरक होता है।

तो कल्पना कीजिए आपको मिल गया health, आपके पास भी होगा healthComplement। आपका कार्यान्वयन इस तरह दिख सकता है:

// setter sets value and complement
void setHealth(int value){
    health = value;
    healthComplement = ~value;
}

// getter checks if value was changed outside of the setter
int getHealth(){
    if(value != ~healthComplement){
        // launch some cheat-counter-measure, like crashing the game?
        exit;
    }
    return health;
}

जो कोई धोखा देना चाहता है उसे स्वास्थ्य और स्वास्थ्य को सही ढंग से लागू करना होगा, अन्यथा खेल दुर्घटनाग्रस्त हो जाएगा।

मुझे लगता है कि इस तरह से सामान को रोकने की कोशिश करना थोड़े व्यर्थ है। लोगों ने बहुत अधिक जटिल सामानों के लिए सफलतापूर्वक हैक / धोखा दिया है और यह सिर्फ आपके कोड को अनावश्यक रूप से बाधित करता है या आपके खेल को खराब करता है।


12

यहाँ एक योजना है जब मैं किसी के लिए बोर्ड पर बहुत पहले से पूछ रहा था। प्रतिशत या दोगुने चर का उपयोग करना वास्तव में काम नहीं करता है, क्योंकि आप "किसी भी" मूल्यों की खोज कर सकते हैं और उन्हें फ्रीज कर सकते हैं।

इसके बजाय, डेटा प्रकार का एक राक्षस बनाएं।

मूल रूप से, अपने महत्वपूर्ण मूल्यों को एक संरचना के रूप में संग्रहीत करें:

  • 32 बिट्स को इंगित करता है
  • त्वरित पढ़ने के लिए, संरचना में एक सादे इंट के रूप में वर्तमान मूल्य भी शामिल है

हेरफेर के लिए, अलग-अलग-आवंटित बिट्स (जो सच / गलत इनट्स हो सकते हैं) से वर्तमान मूल्य को इकट्ठा करें, मान बदलें, और फिर उन्हें वापस स्टोर करें।

यहाँ बुरा सा है: हर बार जब आप मूल्य में हेरफेर करते हैं, तो मुफ्त और बिट्स को फिर से आवंटित करते हैं। आवंटन यादृच्छिक क्रम में होना चाहिए , इसलिए डेटा स्मृति में चारों ओर कूदता है और आसानी से जमे हुए नहीं हो सकता है।

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

संपादित करें: आगे के मेमोरी मूवमेंट के लिए, सुनिश्चित करें कि आपने पुराने को खाली करने से पहले नए "बिट्स" आवंटित किए हैं।

संपादित करें: मल्टीप्लेयर गेम के लिए, डेटा संरचना को क्रमबद्ध करना, इसे संपीड़ित करना और इसे नेटवर्क पर भेजना भी संभव है। नेटवर्क का सबसे कुशल उपयोग नहीं है, लेकिन निश्चित रूप से पैकेट सूँघने के माध्यम से यह पता लगाने के लिए कठिन है।


9

हर बार जब आप इसे स्टोर करते हैं, तो रेंडम वैल्यू के साथ पूरक स्वास्थ्य को आप कैसे स्टोर करते हैं। यह कम से कम स्वास्थ्य को खोजने के लिए स्मृति में बढ़ते / घटते मूल्यों की खोज के सरल तंत्र को पराजित करेगा।

class Player
{
  int m_Health;
  int m_RandomHealth;
  Random m_Rnd = new Random();

  public int Health {
    get
    {
      return m_Health ^ m_RandomHealth;
    }

    set
    {
      m_RandomHealth = m_Rnd.Next();
      m_Health = value ^ m_RandomHealth;
    }
  }
}

इसके अलावा, यदि आप स्वास्थ्य में बदलाव नहीं करते हैं, तो आप प्रत्येक फ़्रेम को रीसेट करना चाह सकते हैं। यह लोगों को उनके स्वास्थ्य में परिवर्तन होने पर परिवर्तित पते की खोज करने से रोकेगा और जब उनका स्वास्थ्य समान रहेगा।

बोनस: हर बार जब यह बदलता है तो एक नया ऑब्जेक्ट बनाएं ताकि मेमोरी ऐड्रेसेज़ बदल जाए, और हर बार पढ़ते समय यादृच्छिक संख्या, xored मान और मेमोरी में पता बदलने के लिए स्वास्थ्य सेट करें :

class Player
{
  int [] m_HealthArray; // [0] is random int, [1] is xored health
  Random m_Rnd = new Random();

  public Player() {
    this.Health = 100;
  }

  public int Health {
    get
    {
      int health = m_HealthArray[0] ^ m_HealthArray[1];
      Health = health; // reset to move in memory and change xor value
      return health;
    }

    set
    {
      m_HealthArray = new int[2];
      m_HealthArray[0] = m_Rnd.Next();
      m_HealthArray[1] = m_HealthArray[0] ^ value;
    }
  }
}

8

हालांकि मैंने पहली टिप्पणी में आपके दर्शकों के एक हिस्से के अनुभव को कम करने के लिए बिना किसी स्पष्ट लाभ के अपमान के बिंदु पर सवाल उठाया था, फिर भी मुझे तकनीकी दृष्टिकोण से यह एक दिलचस्प सवाल लगता है।

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

क्या होगा अगर "स्वास्थ्य" काउंटर पूरे समय बदल रहा है? यदि यह प्रदर्शन बहुत बड़ा है, तो इसे एक पॉइंटर बनाएं और इसे हर फ्रेम या हर N फ्रेम पर फिर से लगाएँ। या इसे एक यादृच्छिक मूल्य के साथ XOR करें जो हर फ्रेम को बदलता है (नए यादृच्छिक मूल्य के साथ एन्क्रिप्ट करने से पहले डिक्रिप्टिंग के लिए उसी मूल्य के खिलाफ XORing फिर से)।

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

आगे की गुमराह करने के लिए, आप वास्तव में स्वास्थ्य को केवल सादे पॉट में केवल शहद के बर्तन के रूप में लिख सकते हैं।

संपादित करें :

फिर भी, चीटर यह जानने की कोशिश कर सकता है कि कौन सा चर पूरे समय बदल रहा है, परीक्षण और त्रुटि के माध्यम से जमने वाला है। एक संभव समाधान यह होगा कि चर को एक साथ जोड़ा जाए।

एक उदाहरण:

स्वास्थ्य (एच) और स्थिति (एक्स) के भंडारण के बजाय, आप उन्हें दो चर ए और बी में संग्रहीत करते हैं, जिससे आप बाद में मूल्यों को प्राप्त कर सकते हैं:

a = x+h; b = x-h
x = (a+b)/2; h = (a-b)/2

इस तरह, यदि चीटर उनमें से केवल एक को जमा देता है और फिर चरित्र को स्थानांतरित करता है, तो स्थिति प्रभावित होती है और, जिसके आधार पर एक को जमे हुए किया जाता है, एच नकारात्मक (तत्काल मृत्यु) हो जाता है। आप उपरोक्त सूत्रों के बीच स्विच कर सकते हैं और:

a = x-h; b = x+h
x = (a+b)/2; h = (b-a)/2

लगातार फ़्रेम में, और आप गारंटी देते हैं कि अधिकांश 2 फ़्रेमों में या तो एक के बाद एक जमे हुए स्वास्थ्य जमे हुए हैं, 0 पल में x बदल जाएगा। याद रखें कि आप केवल ए और बी का भंडारण कर रहे हैं। ऊपर बताए अनुसार निरंतर XOR के साथ इसे मिलाएं। परिणाम चर का एक संग्रह है जो हर फ्रेम को प्रतीत होता है कि यादृच्छिक मूल्यों में बदल रहा है, और उनमें से किसी एक को फ्रीज़ करना या केवल एक सबसेट खेल में अवांछित दुष्प्रभाव पैदा करता है, तत्काल मृत्यु उनमें से एक है।


7

एक संभव विकल्प मुझे लगता है कि काम कर सकता है (मैं इन धोखा उपकरणों से बहुत परिचित नहीं हूं): इसे छिपाएं नहीं। अपने ऑपरेशन करें और कुछ परिणामों की अपेक्षा करें। ऑपरेशन के बाद (संभवतः अगले फ्रेम), यह सुनिश्चित करने के लिए जांचें कि परिणाम आपके द्वारा होने की उम्मीद है। यदि आप स्वास्थ्य को घटाते हैं और फिर इसे सत्यापित करते हैं, तो केवल यह पता लगाने के लिए कि स्वास्थ्य कभी नहीं बदला है, आप बहुत सुनिश्चित हो सकते हैं (बशर्ते आपके पास कुछ अस्पष्ट बग न हो) जो कि बंद था।

यदि आप धोखाधड़ी का पता लगाते हैं, तो आप अब खेल के नियमों को बदलने के लिए स्वतंत्र हैं क्योंकि आप अधिकतम दु: ख के लिए फिट हैं, यदि यह आपका इरादा है। यदि आपका इरादा धोखा देने को नजरअंदाज करने का है और खेल जारी है, तो स्वास्थ्य को याद में कहीं और पुनः स्थापित करें और अपने संकेत बदलें ताकि नए मूल्य का उपयोग हो और पुराने को नजरअंदाज कर दिया जाए। दोहराएँ विज्ञापन infinitum।


6

केवल मोटे तौर पर किसी भी प्रयास को सिद्धांत में विफल होने के लिए बाध्य किया जाता है, लेकिन व्यवहार में आपको बस इतना कठिन बनाने की आवश्यकता है कि चुनौती खेल में सफल होने की तुलना में कम मज़ेदार हो जाए। मुझे नहीं पता कि आपका खेल क्या है, इसलिए मैं डेटा अपचयन के तरीकों का सुझाव देने का जोखिम नहीं उठाऊंगा, भले ही मेरा मानना ​​है कि वे व्यर्थ हैं।

उस ने कहा, और आप शायद इसके शौकीन नहीं होंगे, मेरा मानना ​​है कि आप मेमोरी क्यूरिंग की तलाश कर रहे हैं , जो एक विश्वसनीय कम्प्यूटिंग अवधारणा है।


3

कुछ roguelikes (DoomRL, Brogue) द्वारा उपयोग की जाने वाली एक बहुत प्रभावी तकनीक वास्तविक चर का मुखौटा है। इसका मतलब यह है कि स्वास्थ्य को "2/10" के रूप में दिखाने के बजाय, इसे "20%" के रूप में दिखाएं।

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

मैं एक एंटी-चीट बैकलैश भी सुझाता हूं। उदाहरण के लिए, यदि आपके पास एक ऐसा खेल है जहां खिलाड़ी गैर-सकारात्मक क्षति उठाता है और उनका स्वास्थ्य नहीं गिरा है, तो आप आसानी से और सटीक रूप से इसकी जांच कर सकते हैं और जान सकते हैं कि खिलाड़ी धोखा देता है। कुछ दिलचस्प करो, जैसे उसके चारों ओर कुछ uber दुश्मन पैदा करना :)


2

जब ReadProcessMemory / WriteProcessMemory आपके आवेदन पर कॉल की जाती है, तो एक रिंग 0 ड्राइवर लिखें जो SSDT और लॉग / ब्लॉक को हुक करता है। यह सिर्फ लॉग करने के लिए बेहतर होगा ताकि आप धीरे-धीरे समय के साथ दुर्घटना के बजाय उनके खेल व्यवहार को बदल सकें।


ऐसा लगता है कि आप निम्न-स्तरीय कार्यान्वयन विवरण (विंडोज एपीआई?) के बारे में बात कर रहे हैं, मैं सामान्य, उच्च-स्तरीय रणनीतियों के बारे में पूछ रहा हूं।
ashes999

2

आप खिलाड़ियों को खुद को धोखा देने से क्यों रोकेंगे (जो कि एकल खिलाड़ी गेम में धोखा दे रहा है)? एक मल्टीप्लेयर वातावरण में, अप्राकृतिक परिवर्तनों का पता लगाना और उन्हें काउंटर करना (आमतौर पर इनपुट को अनदेखा करना या अपराधी को सर्वर से पूरी तरह से रोकना) सर्वर का काम है, लेकिन एकल खिलाड़ी के माहौल में कुछ भी नहीं हो रहा है सिवाय चीटर के खुद को करने के! अपकार।

IOW, जब तक आप एक मल्टीप्लेयर गेम नहीं बना रहे हैं, यह पैसे की बर्बादी है, और यदि आप गलत जगह को सख्त करने की सोच रहे हैं।


2

ज्ञात धोखा उपकरणों पर शोध करें - और अक्सर जांचें कि क्या सबसे आम लोगों में से किसी का पता चल रहा है (जांच प्रक्रिया के नाम?)

यदि किसी का पता लगाया जाता है, तो खिलाड़ी को धोखा दें (यदि ऑफ़लाइन है, तो यह हानिरहित है), लेकिन यह सुनिश्चित करें कि कोई भी स्कोर / एचीवमेंट किसी भी ऑनलाइन लीडरबोर्ड / एचीवमेंट सिस्टम पर पोस्ट नहीं किया जाएगा - बस इसे चुपचाप विफल कर दें?

अधिक निर्धारित हैकर्स को नहीं रोकेंगे, लेकिन आपके लीडरबोर्ड को गड़बड़ करने वाले अधिक आकस्मिक धोखा देने की संभावना को कम कर देंगे।

(हो सकता है कि क्रोधित कोडर्स जिनके पास देव उपकरण खुले हों और कानूनी उद्देश्यों के लिए कम से कम हों और गेमिंग ब्रेक ले रहे हों, हालांकि ...)


7
मैं एक वितरण मंच के रूप में स्टीम का बहुत बड़ा प्रशंसक था, और कुछ साल पहले टीम फोर्टिस II की बहुत भूमिका निभाई थी। एक शाम, मैंने एक लंबे कोडिंग सत्र से ब्रेक लिया और ओपन विजुअल स्टूडियो और एक डिबगर छोड़ दिया, जबकि मैंने खेला था। मैंने खुद को "धोखा" के लिए TF2 से प्रतिबंधित पाया। कोई अपील नहीं, प्रतिबंध हटाने की कोई रूपरेखा नहीं। एक "अपराध" और यह खाते के लिए स्थायी है। मुझे अभी भी पता नहीं था कि क्यों - और मेरा विश्वास करो, मैं फ्यूमिंग कर रहा था - सिवाय इसके कि मैं अक्सर पूछे जाने वाले प्रश्न में गहरे दफन देखता हूं कि गेम को धोखा देते हुए "मेमोरी एडिटर" खुला है और प्रतिबंध लगाने में सक्षम है। वाह।

1

मुझे लगता है कि इसका सबसे सरल उपाय धोखा विकल्प को लागू करना है। धोखा विकल्प में स्कोरिंग अक्षम करें।

एक और अच्छा विचार है, मुझे नहीं पता कि आप कैसे लागू करेंगे। खेल को बंद करने के लिए है जब एक जमे हुए मेमोरी चर या ऐसा कुछ है :)

अच्छा भाग्यशाली)


3
धोखा देना एक अच्छा विकल्प है। खेल बंद, इतना नहीं ... (कल्पना करें कि क्या आपको यह गलत लगता है, और एक वैध खिलाड़ी को बंद कर दें।)
ashes999
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.