2016-08-11 7 views
8

मैं वर्तमान में पढ़ रहा हूं (दूसरी बार) "हैकिंग: एक्सप्लॉयशन ऑफ आर्ट" और कुछ पर ठोकर खाई है।क्या जीसीसी संकलन समय पर स्थानीय चरों को पुन: व्यवस्थित कर रहा है?

पुस्तक इन दो इसी तरह के कार्यक्रमों का फायदा उठाने की दो अलग अलग तरीकों से पता चलता है: auth_overflow और auth_overflow2

पहले एक में, वहाँ है एक पासवर्ड चेकिंग समारोह इस

int check_authentication(char *password) { 
    int auth_flag = 0; 
    char password_buffer[16]; 

    strcpy(password_buffer, password); 
    ... 
} 

तरह से बाहर रखी 16 से अधिक inputing ASCII वर्ण 0 से अधिक कुछ के लिए auth_flag के मान को बदल देंगे, इस प्रकार चेक को छोड़कर, जैसा कि इस जीडीबी आउटपुट पर दिखाया गया है:

gdb$ x/12x $esp 
0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141 
0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001 
0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556 

password_buffer @ 0xbffff40c 
auth_flag @ 0xbffff41c 

दूसरा कार्यक्रम दो चर उलट:

int check_authentication(char *password) { 
    char password_buffer[16]; 
    int auth_flag = 0; 

    strcpy(password_buffer, password); 
    ... 
} 

लेखक तो पता चलता है की तुलना में यह auth_flag है, जो मैं वास्तव में विश्वास करते थे में से ऊपर जाने का संभव नहीं है। मैं फिर बफर को बहने लगा, और मेरे आश्चर्य के लिए, यह अभी भी काम किया। auth_flag चर अभी भी, बफर के बाद बैठा हुआ था के रूप में आप इस gdb उत्पादन पर देख सकते हैं:

gdb$ x/12x $esp 
0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141 
0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001 
0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556 

password_buffer @ 0xbffff40c 
auth_flag @ 0xbffff41c 

मैं अगर जीसीसी alignement/अनुकूलन प्रयोजनों के लिए स्थानीय चर को पुन: क्रम नहीं है सोच रहा हूँ।

मैंने -ऑ0 ध्वज का उपयोग करके संकलन करने की कोशिश की, लेकिन परिणाम वही है।

क्या आप में से कोई जानता है कि यह क्यों हो रहा है?

अग्रिम धन्यवाद।

+3

"रीडरिंग" किसी भी तरह से तात्पर्य है कि आप प्रारंभिक "ऑर्डर" होने की उम्मीद करते हैं। सी ++ वास्तव में स्थानीय चर के भंडारण के किसी भी प्रकार का ऑर्डर निर्दिष्ट नहीं करता है, जिसका भंडारण "स्वचालित" कहा जाता है - यानी नहीं पूछें। –

+0

मुझे कोड में घोषित आदेश को छोड़ने के लिए संकलक (इसके अनुकूलन अक्षम के साथ) की उम्मीद थी। लेकिन मैं कंपाइलर्स के बारे में ज्यादा नहीं जानता। पुस्तक के लेखक भी वही व्यवहार की उम्मीद करते हैं। मैं अभी भी इसे काम करने में कामयाब रहा जैसे मैं चाहता था कि दोनों चर अस्थिर घोषित कर सकें। – rgehan

+2

ठीक है, आपकी उम्मीदें दुर्भाग्य से भाषा नियमों से असंबद्ध हैं। (क्षमा करें, आपने सी कहा है, सी ++ नहीं, लेकिन एक ही बिंदु लागू होता है।) "व्यक्तिगत उम्मीदों से अलग वास्तविकता" आपके अनुभव का एक उचित सारांश होगा :-) स्वचालित भंडारण केवल "स्वचालित रूप से वहां" है, बहुत कम गारंटीकृत विनिर्देशों के साथ। –

उत्तर

11

कंपाइलर लेखक स्वचालित स्टोरेज के साथ स्थानीय चर के लिए आवंटन योजना को लागू करने के लिए पूरी तरह से स्वतंत्र हैं। auth_flag को स्टैक पर password_buffer से पहले या उसके बाद सेट किया जा सकता है, यह एक रजिस्टर में हो सकता है, अगर कोड के उचित विश्लेषण की अनुमति मिलती है तो इसे पूरी तरह से बढ़ाया जा सकता है। यहां तक ​​कि स्टैक भी नहीं हो सकता है ... मानक आपको केवल गारंटी देता है:

strcpy(password_buffer, password); अपरिभाषित व्यवहार का आह्वान करता है यदि उसके शून्य टर्मिनेटर सहित स्रोत स्ट्रिंग गंतव्य सरणी password_buffer से अधिक है। चाहे यह अपरिभाषित व्यवहार आपकी आवश्यकताओं को पूरी तरह से भाषा विनिर्देश के बाहर फिट करता है।

वास्तव में, कुछ कार्यान्वयनकर्ता जानबूझकर पोस्ट कोड जैसे मामलों में व्यवहार को यादृच्छिक रूप से हैकर्स के काम को जटिल बनाते हैं।

+0

यही है कि केरेक एसबी और उपयोगकर्ता 6 9 3333 ने बताया। मैंने नहीं सोचा था कि एक कंपाइलर का आउटपुट दूसरे कंपाइलर में से एक से अलग हो सकता है। यह पूरी तरह से समझ में आता है। धन्यवाद :) – rgehan

संबंधित मुद्दे