2013-03-12 18 views
11

मैं एक स्टैक ओवरफ़्लो पर नियंत्रण लेने की कोशिश कर रहा हूं। समारोह GetInput के लिए कोडांतरक कोड के डंप:बफर ओवरफ़्लो दिखाई देने से पहले दिखाई दिया

0x08048455 <+0>: push ebp 
0x08048456 <+1>: mov ebp,esp 
0x08048458 <+3>: sub esp,0x28 
0x0804845b <+6>: lea eax,[ebp-0x10] 

यहाँ सबसे पहले, यहाँ सी कोड का एक उदाहरण मैं एक x32 वीएम लिनक्स (gcc -fno-stack-protector -ggdb -o first first.c) पर संकलित,

#include "stdio.h" 

int CanNeverExecute() 
{ 
    printf("I can never execute\n"); 
    return(0); 
} 

void GetInput() 
{ 
    char buffer[8]; 

    gets(buffer); 
    puts(buffer); 
} 

int main() 
{ 
    GetInput(); 
    return(0); 
} 

फिर डिबगर (इंटेल स्वाद) है हम देख सकते हैं कि उप esp, 0x28 एक बफर चर (दाएं?) के लिए 40 बाइट्स आरक्षित करता है। CanNeverExecute फ़ंक्शन पते 0x0804843c में स्थित है। तो, CanNeverExecute फ़ंक्शन चलाने के लिए, मुझे 40 बाइट्स को बफर वेरिएबल में डालने की आवश्यकता है, फिर संग्रहीत बेस पॉइंटर के लिए 8 बाइट्स और फिर 8 बाइट्स रिटर्न पॉइंटर के लिए बदलना है, जिसे मैं बदलना चाहता हूं।

तो, मुझे अंत में 48 ASCII प्रतीकों और \x3c\x84\x04\x08 की एक स्ट्रिंग की आवश्यकता है (CanNeverExecute फ़ंक्शन का पता)। यह सिद्धांत में है। लेकिन व्यवहार में मैं वापसी सूचक का पता पहले ही 20 बाइट की जरूरत है:

~/hacktest $ printf "123456789\x3c\x84\x04\x08" | ./first 
123456789.. 
I can never execute 
Illegal instruction (core dumped) 

यह केवल 20 के बजाय 48 बाइट्स की आवश्यकता क्यों है? मेरी गलती कहां है?

उत्तर

2

आप dissassembly का बड़ा भाग लेते हैं आप देखेंगे:

08048445 <GetInput>: 
8048445: 55      push %ebp 
8048446: 89 e5     mov %esp,%ebp 
8048448: 83 ec 28    sub $0x28,%esp 
804844b: 8d 45 f0    lea -0x10(%ebp),%eax 
804844e: 89 04 24    mov %eax,(%esp) 
8048451: e8 9a fe ff ff   call 80482f0 <[email protected]> 
8048456: 8d 45 f0    lea -0x10(%ebp),%eax 
8048459: 89 04 24    mov %eax,(%esp) 
804845c: e8 9f fe ff ff   call 8048300 <[email protected]> 
8048461: c9      leave 
8048462: c3      ret 

ईबीपी सहेजा जाता है, खास तौर पर ईबीपी के लिए ले जाया जाता है, तो 40 (, ढेर फ्रेम के रूप में आप ने लिखा) esp से घटाया जाता है, लेकिन सूचक बफर को ईएक्स रजिस्टर के माध्यम से प्राप्त किया जाता है, और ईएक्स ईबीपी -0x10 के साथ लोड किया जाता है!

lea -0x10(%ebp),%eax 

तो आप बफर (16 आरक्षित 4 संग्रहीत आधार सूचक के लिए 32-बिट सिस्टम पर)

से ऊपर जाने का केवल 20 बाइट्स की जरूरत है
9

सबसे पहले, आपकी असेंबली 32-बिट है। सहेजा गया ईबीपी और वापसी पता प्रत्येक 4 बाइट्स हैं।

दूसरा, buffer वैरिएबल स्टैक टॉप (ईएसपी) पर शुरू नहीं होता है - यह ebp-0x10 पर शुरू होता है। रिटर्न पते से 20 बाइट दूर है। 0x10 16 बाइट्स है, फिर सहेजे गए ईबीपी के लिए 4 और।

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