كيف "تجاوز سعة مكدس الذاكرة المؤقتة" تحدث وكيف يمكن الوقاية منه ؟

StackOverflow https://stackoverflow.com/questions/26158

  •  09-06-2019
  •  | 
  •  

سؤال

كيف يمكن تجاوز سعة مكدس تحدث و ما هي أفضل الطرق للتأكد من أنه لا يحدث ، أو طرق لمنع وخاصة على ملقمات ويب ، ولكن أمثلة أخرى سيكون من المثير للاهتمام أيضا ؟

هل كانت مفيدة؟

المحلول

المكدس

كومة, في هذا السياق, هو في الماضي, لأول مرة العازلة تقوم بوضع البيانات أثناء تشغيل البرنامج.في الماضي, لأول مرة (LIFO) يعني أن آخر شيء كنت وضعت في هو دائما أول شيء كنت الخروج - إذا كنت تدفع 2 البنود على المكدس ، 'A' ثم 'B', ثم أول شيء كنت البوب قبالة كومة سوف يكون 'B', والشيء التالي هو 'A'.

عند استدعاء دالة في التعليمات البرمجية التعليمة التالية بعد استدعاء الدالة يتم تخزينها في المكدس ، أي مساحة التخزين التي قد تكون الكتابة بواسطة استدعاء دالة.وظيفة تتصل قد استخدم أكثر كومة الخاصة المتغيرات المحلية.وعندما يحدث ذلك فإنه يحرر المحلية متغير مساحة مكدس تستخدم ، ثم يعود إلى الدالة السابقة.

تجاوز سعة مكدس

تجاوز سعة مكدس هو عندما كنت قد استخدمت أكثر من ذاكرة كومة من البرنامج كان من المفترض أن تستخدم.في النظم المضمنة قد يكون لديك فقط 256 بايت المكدس ، وإذا كان كل وظيفة يستغرق 32 بايت ثم هل يمكن أن يكون فقط المكالمات وظيفة 8 العميقة وظيفة 1 المكالمات وظيفة 2 الذي يدعو وظيفة 3 الذي يدعو وظيفة 4 ....الذي يدعو وظيفة 8 الذي يدعو وظيفة 9 ، ولكن وظيفة 9 بالكتابة الذاكرة خارج المكدس.هذا قد الكتابة فوق الذاكرة, رمز, الخ.

العديد من المبرمجين تجعل هذا الخطأ عن طريق استدعاء الدالة على ذلك ثم يدعو وظيفة ب ، ثم يدعو وظيفة ج ، ثم يدعو وظيفة A.قد تعمل أكثر من مرة ، ولكن فقط بمجرد إدخال بيانات خاطئة سوف يؤدي إلى الذهاب في تلك الدائرة إلى الأبد حتى يتعرف الكمبيوتر أن المكدس هو مبالغ فيها.

وظائف العودية هي أيضا سبب هذا, ولكن إذا كنت تكتب بشكل متكرر (أي وظيفة الخاص بك تدعو نفسها) ثم عليك أن تكون على بينة من هذا و استخدام ثابت/المتغيرات العالمية لمنع لانهائية العودية.

عموما نظام التشغيل و لغة البرمجة كنت تستخدم إدارة كومة ، و هو من بين يديك.يجب أن ننظر في دعوة الرسم البياني (هيكل شجرة يظهر من أهم ما كل المكالمات وظيفة) لمعرفة مدى عمق الخاص بك وظيفة المكالمات تذهب للكشف عن دورات العودية التي لا يقصد.المتعمد دورات العودية تحتاج إلى أن تكون مصطنع تأكدت أن الخطأ إذا كانوا يدعون بعضهم البعض في كثير من الأحيان.

ما وراء الخير البرمجة الممارسات ، والدينامية اختبار, ليس هناك الكثير يمكنك القيام به في هذه عالية المستوى النظم.

جزءا لا يتجزأ من أنظمة

في جزءا لا يتجزأ من العالم ، وخاصة في موثوقية عالية رمز (السيارات, الطائرات, الفضاء) كنت تفعل واسعة رمز الآراء و التحقق ، ولكن يمكنك أيضا القيام بما يلي:

  • عدم السماح العودية و دورات القسري من قبل السياسة والاختبار
  • نضع كود كومة متباعدة (رمز في فلاش ، المكدس في ذاكرة الوصول العشوائي ، ولم يجتمع)
  • مكان حارس عصابات حول كومة منطقة فارغة من الذاكرة التي يمكنك ملء مع الرقم السحري (عادة ما تكون البرامج يقطع تعليمات ، ولكن هناك العديد من الخيارات هنا), و مئات أو آلاف المرات في الثانية تبدو في الحرس العصابات للتأكد من أنها لم تكن الكتابة.
  • استخدام الذاكرة الحماية (أي لا يوجد تنفيذ على المكدس ، أي القراءة أو الكتابة خارج المكدس)
  • المقاطعات لا تتصل الوظائف الثانوية - وضعوا أعلام نسخ البيانات, و ترك التطبيق تأخذ الرعاية من معالجة ذلك (وإلا قد تحصل على 8 العميق في استدعاء دالة شجرة ، المقاطعة ، ثم تخرج أخرى عدة وظائف داخل المقاطعة ، مما تسبب في انفجار).لديك العديد من المكالمات الأشجار واحد على العمليات الرئيسية ، واحد لكل مقاطعة.إذا كان الخاص بك يمكن أن يقطع يقطع بعضها البعض...حسنا, هناك يكون التنين...

اللغات عالية المستوى و أنظمة

ولكن في لغات المستوى العالي تعمل على أنظمة التشغيل:

  • خفض الخاص بك المحلية تخزين المتغير (المتغيرات المحلية يتم تخزينها في المكدس - على الرغم من أن المجمعين هي ذكية جدا حول هذا وسوف وضعت في بعض الأحيان كبيرة من السكان المحليين على كومة إذا شجرة الضحلة)
  • تجنب أو تقصر العودية
  • لا تكسر البرامج الخاصة بك بعيدا جدا إلى أصغر و أصغر وظائف - حتى دون احتساب المتغيرات المحلية كل استدعاء دالة يستهلك قدر 64 بايت على المكدس (32 بت المعالج ، وتوفير نصف سجلات وحدة المعالجة المركزية, أعلام, الخ)
  • الحفاظ على الخاص بك شجرة الضحلة (على غرار البيان أعلاه)

ملقمات ويب

ذلك يعتمد على 'رمل' لديك ما إذا كان يمكنك السيطرة أو حتى رؤية المكدس.وهناك احتمالات جيدة يمكنك علاج خوادم الويب كما تفعل أي لغة عالية المستوى و نظام التشغيل إلى حد كبير من يديك, ولكن تحقق من اللغة مكدس server الذي تستخدمه.ذلك هو من الممكن ضربة المكدس على SQL server الخاص بك على سبيل المثال.

-آدم

نصائح أخرى

تجاوز سعة مكدس في رمز حقيقي يحدث نادرا جدا.معظم الحالات التي يحدث فيها هي recursions حيث انتهاء قد نسي.ومع ذلك فإنه قد نادرا ما تحدث في غاية هياكل متداخلة ، على سبيل المثاللا سيما الكبيرة مستندات XML.فقط مساعدة حقيقية هنا هو ريفاكتور رمز لاستخدام صريح كومة كائن بدلا من الاستدعاءات.

معظم الناس سوف أقول لكم أن تجاوز سعة مكدس يحدث مع العودية دون الخروج من المسار - بينما في الغالب صحيح ، إذا كنت تعمل مع كبيرة بما يكفي هياكل البيانات ، حتى السليم العودية مسار الخروج لن تساعدك.

بعض الخيارات في هذه الحالة:

لانهائية العودية هو وسيلة شائعة للحصول على كومة تجاوز الخطأ.لمنع - تأكد دائما هناك مخرج الطريق الذي سوف يكون ضرب.:-)

طريقة أخرى للحصول على كومة تجاوز سعة (في C/C++ على الأقل) هو إعلان بعض هائلة متغير على المكدس.

char hugeArray[100000000];

أن عليك أن تفعل ذلك.

تجاوز سعة مكدس يحدث عندما جيف جويل تريد أن تعطي العالم أفضل مكان للحصول على إجابات على الأسئلة التقنية.فوات الأوان لمنع هذا تجاوز سعة مكدس.أن "موقع آخر" قد حالت دون ذلك لا يجري القذر.;)

وعادة ما تجاوز سعة المكدس هو نتيجة لا حصر له دعوة متكررة (بالنظر إلى الكمية المعتادة من الذاكرة القياسية في أجهزة الكمبيوتر في الوقت الحاضر).

عند إجراء مكالمة إلى أسلوب الدالة أو الإجراء "المعيار" أو طريقة صنع تتصل تتكون على:

  1. مما دفع العائد اتجاه الدعوة إلى المكدس(أن الجملة التالية بعد المكالمة)
  2. عادة ما تكون مساحة قيمة الإرجاع الحصول على حجز في كومة
  3. دفع كل معلمة في كومة (ترتيب يحيد و يعتمد على كل مترجم, أيضا بعض منهم في بعض الأحيان المخزنة على سجلات وحدة المعالجة المركزية لتحسين الأداء)
  4. جعل المكالمة الفعلي.

لذا عادة ما يأخذ هذا بعض بايت depeding على عدد و نوع من المعلمات وكذلك الجهاز العمارة.

سترى بعد ذلك أنه إذا كان يمكنك البدء في صنع دعوات متكررة كومة سوف تبدأ في النمو.الآن كومة عادة ما تكون محفوظة في الذاكرة في مثل هذه الطريقة التي تنمو في الاتجاه المعاكس إلى كومة لذلك ، بالنظر إلى عدد كبير من المكالمات من دون "العودة" كومة يبدأ للحصول على كامل.

الآن, في العصور القديمة تجاوز سعة مكدس يمكن أن تحدث ببساطة لأنك exausted كافة الذاكرة المتوفرة مثل ذلك.مع الذاكرة الظاهرية نموذج (تصل إلى 4 جيجابايت على نظام X86) التي كانت خارج نطاق لذا عادة, إذا كنت تحصل على خطأ تجاوز سعة مكدس ، تبدو لانهائية دعوة متكررة.

وبصرف النظر عن شكل تجاوز سعة مكدس التي تحصل عليها من مباشرة العودية (على سبيل المثال Fibonacci(1000000)) أكثر دهاء شكل ذلك لقد شهدت عدة مرات غير مباشر العودية ، حيث المكالمات وظيفة وظيفة أخرى ، مما يدعو آخر ، ثم واحدة من تلك الوظائف المكالمات الأولى مرة أخرى.

هذا يمكن أن يحدث عادة في الوظائف التي تسمى ردا على الأحداث ولكن الذي أنفسهم قد تولد الأحداث الجديدة ، على سبيل المثال:

void WindowSizeChanged(Size& newsize) {
  // override window size to constrain width
    newSize.width=200;
    ResizeWindow(newSize);
}

في هذه الحالة دعوة إلى ResizeWindow قد يسبب WindowSizeChanged() رد يمكن تشغيلها مرة أخرى ، والتي المكالمات ResizeWindow مرة أخرى, حتى كنت قد نفد من المكدس.في مثل هذه الحالات غالبا ما تحتاج إلى تأجيل الرد على هذا الحدث حتى في إطار مكدس عاد ، على سبيل المثال عن طريق نشر رسالة.

ماذا ؟ لا أحد لديه أي حب لمن فتش عن طريق حلقة لا نهائية?

do
{
  JeffAtwood.WritesCode();
} while(StackOverflow.MakingMadBank.Equals(false));

معتبرا هذا كان الموسومة ب "القرصنة" ، أظن أن "تجاوز سعة مكدس الذاكرة المؤقتة" انه اشارة الى دعوة تجاوز سعة مكدس بدلا من مستوى أعلى كومة تجاوز مثل تلك المشار إليها في معظم إجابات أخرى هنا.لا تنطبق على أي المدارة أو تفسير البيئات مثل .NET, Java, Python, Perl, PHP, الخ, والتي تطبيقات الويب عادة ما يكتب في ذلك مسؤوليتك فقط ملقم ويب نفسه الذي ربما هو مكتوب في C أو C++.

تحقق من هذا الموضوع:

https://stackoverflow.com/questions/7308/what-is-a-good-starting-point-for-learning-buffer-overflow

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top