क्या बफर ओवरफ्लो परिवर्तनशील डेटा प्रकार को बदलता है, यह ओवरराइटिंग है? [बन्द है]


8

कहो कि मेरे पास एक सी वर्ण सरणी है char buf[15]। मान लीजिए कि वेरिएबल int set_me = 0का डेटा मेमोरी मेमोरी लोकेशन में सीधे संग्रहीत होता है char buf[15]। यदि मैं bufस्ट्रिंग के साथ बह निकला "aaabbbcccdddeee\xef\xbe\xad\xde", तो क्या set_meएक पूर्णांक से वर्ण सरणी में डेटा प्रकार बदल जाएगा?


3
इस बात पर निर्भर करता है कि डेटा की व्याख्या कौन कर रहा है। अंत में सब कुछ द्विआधारी है। तो जिस तरह से आप इसकी व्याख्या करते हैं, यह एक वैध पूर्णांक मान हो सकता है या एक कास्ट त्रुटि का कारण बन सकता है
गणेश आर

जवाबों:


33

नहीं।

एक चर का "डेटा प्रकार" केवल स्रोत कोड में प्रासंगिक है (और तब भी केवल कुछ भाषाओं में)। यह संकलक को चर का इलाज करने का तरीका बताता है।

ये उच्च-स्तरीय डेटा प्रकार संकलित (मूल) कोड में मौजूद नहीं हैं। वे प्रभावित कर सकते हैं कि एक संकलक क्या निर्देश उत्पन्न करता है, लेकिन यदि डेटा किसी वर्ण या संख्या का प्रतिनिधित्व करता है, तो निर्देशों की स्वयं परवाह नहीं करता है।


हार्डवेयर में चर मौजूद नहीं हैं। हार्डवेयर में, आपके पास स्मृति स्थान और निर्देश हैं जो उन पर काम करते हैं।

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

उदाहरण के लिए, बाइट 0x41 की व्याख्या UTF-8-एन्कोडेड वर्ण के रूप में की जा सकती है A। इसे एकल-बाइट पूर्णांक के रूप में भी व्याख्या किया जा सकता है 65। इसे मल्टी-बाइट पूर्णांक या फ्लोटिंग पॉइंट नंबर में एक बाइट या मल्टी-बाइट कैरेक्टर एन्कोडिंग में एक बाइट के रूप में भी समझा जा सकता है। यह बिटसेट हो सकता है 0b1000001। सभी एक ही बाइट से एक ही मेमोरी लोकेशन में। सी भाषा में, आप इन विभिन्न प्रकारों के लिए कास्टिंग करके इस प्रभाव को देख सकते हैं ।

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

जहाँ भी आप अगली बार उस मेमोरी लोकेशन को अपने कोड में एक्सेस करेंगे, निर्देश मूल रूप से परिभाषित होंगे। उदाहरण के लिए यदि वे वहां एक संख्या की उम्मीद कर रहे थे, तो वे डेटा के जितने भी बाइट्स पर कार्य करेंगे जैसे कि वे एक नंबर थे।


अपने उदाहरण का उपयोग करने के लिए, यह मानते हुए कि आपका intहस्ताक्षरित 4-बाइट (32-बिट) पूर्णांक है:

+-------------+--------------------------------------------+-----------+
| Source code |                  char[15]                  |    int    |
+-------------+--------------------------------------------------------+
| Memory      |61|61|61|62|62|62|63|63|63|64|64|64|65|65|65|EF|BE|AD|DE|
+-------------+--------------------------------------------------------+

आप देख सकते हैं कि intअब 0xEFBEADDEबड़े-एंडियन सिस्टम 2 को मानते हुए मेमोरी लोकेशन शामिल है । यह हस्ताक्षरित 32-बिट इंट है -272716322। अब, यदि आप एक ही स्मृति को अहस्ताक्षरित int ( uint) के रूप में व्याख्या करते हैं, तो यह 4022250974इसके बजाय होगा । मेमोरी में समान डेटा के लिए, अर्थ पूरी तरह से इस बात पर निर्भर करता है कि आप इसे कैसे देखते हैं।


1 कुछ तंत्र हैं जो आपको स्मृति के संरक्षित क्षेत्रों में लिखने से रोकते हैं, और यदि आप ऐसा करने का प्रयास करते हैं तो यह आपके प्रोग्राम को क्रैश कर देगा।

2 x86 वास्तव में थोड़ा-सा एंडियन है, जिसका अर्थ है कि आप बाइट्स को एक बड़ा मूल्य बनाते हैं। तो x86 पर आप इसके बजाय 0xDEADBEEF, हस्ताक्षरित -559038737या अहस्ताक्षरित होंगे 3735928559


तो 0xdeadbeef, एक x86 आर्किटेक्चर पर, अपने दशमलव समकक्ष की तुलना में स्मृति में कम जगह लेगा 3735928559,?
डेरेन स्प्रिंगर

2
@DarienSpringer दोनों मेमोरी के 4 बाइट्स लेते हैं - वे समान 4-बाइट अनुक्रम हैं। वे स्मृति में समान हैं। यदि आप चाहें तो आप इसे सभी को आधार 2 (बाइनरी) मान सकते हैं। फिर, जब आप उन्हें प्रदर्शित करते हैं (आउटपुट के लिए एक स्ट्रिंग में कनवर्ट करते हैं) तो आप प्रदर्शित करने के लिए एक आधार चुन सकते हैं - हेक्स 16 बेस है, और दशमलव 10 बेस है। स्ट्रिंग का प्रतिनिधित्व एक अलग मेमोरी लोकेशन में संग्रहीत होता है और विभिन्न मात्राओं का उपयोग कर सकता है। स्मृति के रूप में (प्रत्येक चरित्र एक अलग बाइट है)। स्ट्रिंग 0xDEADBEEF के रूप में स्मृति में संग्रहीत किया जाता है 0x30 0x78 0x44 0x45 0x41 0x44 0x42 0x45 0x45 0x46
बॉब

5
@DarienSpringer दूसरा तरीका रखो, एक संख्या एक ही संख्या है कोई फर्क नहीं पड़ता कि यह किस आधार में है। हेक्स द्विआधारी को देखने के लिए एक सुविधाजनक (कॉम्पैक्ट) तरीका है। शारीरिक रूप से, यह द्विआधारी है। इंसान को दशमलव पसंद है, इसलिए हम अक्सर संख्याओं को दशमलव के रूप में प्रदर्शित करते हैं। लेकिन जब तक हम डिस्प्ले स्टेप पर नहीं आते हैं, सभी संख्यात्मक ऑपरेशन (जोड़, घटाना, गुणा, आदि) मेमोरी में एक ही बाइनरी डेटा पर काम करते हैं।
बॉब

1
"आप देख सकते हैं कि इंट की मेमोरी लोकेशन अब 0xEFBEADDE है" नाइटपिक: मुझे पता है कि आपने यह इरादा नहीं किया था, लेकिन ऐसा लगता है जैसे आप कह रहे हैं कि मेमोरी स्थान पर स्थित है 0xEFBEADDE। शायद कि थोड़ा सा reword करें। अन्यथा यह एक शानदार जवाब है - मैं विशेष रूप से "दृश्य" सादृश्य और "स्क्विंटिंग" विचार को पसंद करता हूं :)
लाइटनेस रेस इन ऑर्बिट

@LightnessRacesinOrbit अच्छा बिंदु। संपादित।
बॉब

2

सी के नजरिए से, जवाब होगा "कौन जानता है? यह अपरिभाषित व्यवहार है"।

प्रकार एक C अवधारणा है, हार्डवेयर नहीं। लेकिन सी नियम लागू नहीं होता है यदि आपके कार्यक्रम में अपरिभाषित व्यवहार है, जो कि सी मानक में अपरिभाषित व्यवहार का शाब्दिक अर्थ है। और बफर ओवरफ्लो उसी का एक रूप है।

मैंने शुरू में "सी नियम अब लागू नहीं होता है" लिखा था, लेकिन वास्तव में अपरिभाषित व्यवहार पूर्वव्यापी है। सी नियम उस प्रोग्राम पर लागू नहीं होते हैं जिसमें भविष्य में अपरिभाषित व्यवहार होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.