ما هو Stack Smashing؟ هل يمكن إصلاحه؟

جدول المحتويات:

ما هو Stack Smashing؟ هل يمكن إصلاحه؟
ما هو Stack Smashing؟ هل يمكن إصلاحه؟
Anonim

كل دقيقة من توقف الإنتاج ستكلف عمومًا أموال الشركة. إذا كان تطبيقك به مشكلة خطيرة تتسبب في تحطيم المكدس ، فأنت في جولة. تعرف على ماهية تحطيم المكدس مقدمًا وما الذي يمكن فعله حيال ذلك

ما هو Stack Smashing؟

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

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

Stack smashing هو مصطلح فضفاض إلى حد ما قد يشير إلى قضايا مختلفة ويمكن أن يأتي من مجموعة متنوعة من المصادر. أهم مشكلتين يمكن أن تتسبب في تحطيم المكدس هما ؛ 1) للكتابة / الإفراط في تخصيص الكثير من البيانات في جزء معين من المكدس ، وبالتالي الكتابة فوق جزء آخر من المكدس ، و 2) حيث قام مصدر خارجي (ضار أو غير ضار) بالكتابة فوق مكدس برنامج آخر ، على الرغم من أن هذا أقل شيوعًا

إذن ما هو المكدس؟ هذا ، أيضًا ، مصطلح غير محدد التعريف. بشكل عام ، يشير المكدس إلى مكدس معالجة البرنامج ، وهو مجموعة من الوظائف كما هو محدد في برنامج / رمز معين.

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

صورة
صورة

صورة أن كل بلاطة مكدسة هي وظيفة في برنامج الكمبيوتر. الوظيفة الأساسية موجودة في الأسفل ، ويمكن أن تكون على سبيل المثال الوظيفة

main ()في برنامج C أو C ++. C و C ++ هما لغتا برمجة تستخدمان المكدس على نطاق واسع.

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

فيما يتعلق بمثال البلاط أعلاه ، تخيل شخصًا ما بمطرقة يضرب البلاط الأول بقوة كبيرة جدًا وبالتالي يحطم كل البلاط الآخر. إيه فويلا كومة تحطيم ؛)

القياس يعمل لأنه ، تمامًا كما تم كسر جميع المربعات في صورة الذاكرة الوهمية لدينا ، فإن المكدس المحطم سينتج عنه "وظائف معطلة" إذا صح التعبير. كل إزاحة للبلاط هي وظيفة متداخلة بشكل أعمق - المزيد عن الوظائف المعطلة في القسم التالي.

تصحيح المكدس المحطم

في حين أن الإشارة الفنية إلى `` الوظائف المعطلة '' قد لا تكون صحيحة تمامًا ، أي أنه من المحتمل أن تكون هناك وظيفة واحدة معطلة ، وقد لا تكون هناك وظيفة معطلة عندما يكون هناك هجوم خارجي أو برنامج معطل ، فهو كذلك طريقة رائعة للتفكير في المكدس المحطم

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

بشكل عام ، عندما ننظر إلى backtrace ، سيكون له تدفق واضح للوظائف التي تم استدعاؤها. بينما لا يمكن تسمية برنامج التعطل على الفور بأنه "سليم" من حيث التتبع الخلفي / تصحيح الأخطاء ، فهذا ما يبدو عليه التتبع الخلفي "الصحي":

مكدس "صحي" عبر backtrace (bt) باستخدام GDB
مكدس "صحي" عبر backtrace (bt) باستخدام GDB

عندما يكون المكدس تالفًا ، يصبح تصحيح الأخطاء أكثر صعوبة. قد يبدو المكدس كما يلي:

تفريغ مكدس محطم تم إنشاؤه بواسطة mysqld ، خادم قاعدة بيانات MySQL
تفريغ مكدس محطم تم إنشاؤه بواسطة mysqld ، خادم قاعدة بيانات MySQL

هذا مثال على مشكلة تحطيم المكدس التي حدثت في MySQL ، خادم قاعدة البيانات (انظر

log.txt

المرفق إلى MySQL Bug 37815 للإخراج الكامل) في عام 2008 ، مما تسبب خادم قاعدة البيانات الخفي (

mysqld) للإنهاء.

بينما مكتبة نظام التشغيل

libc.so.6

، في هذه الحالة ، يبدو أنها تعاملت مع تحطيم المكدس جيدًا (باستخدام بعض الوظائف المحصنة في

__ fortify_failfunction) ، المشكلة موجودة في مكان ما في الكود وتم إصلاحها منذ ذلك الحين.

لاحظ أيضًا أنه في هذه الحالة ، لا نرى أسماء الوظائف التي تم حلها ، ولا يظهر لنا سوى الاسم الثنائي (المثير للاهتمام ، يبدو أن المشكلة كانت في العميل (

mysql) تسبب في إنهاء الخادم (

mysqld

)) وهو

mysql

، مع عنوان ذاكرة الوظيفة:

mysql [0x8051565]

،

mysql [0x80525c7]

و

mysql (main + 0x4f8) [0x8053198]

عادةً ، عندما نستخدم رموز تصحيح الأخطاء (المرجع أدناه لمقال عن GDB يشرح بالتفصيل رموز تصحيح الأخطاء) ، سنرى أسماء الوظائف مع المتغيرات ، وحتى مع وجود بعض مستويات التحسين / التصغير الثنائية في المكان ، سنرى على الأقل أسماء الوظائف ، تمامًا مثل ما نراه في التتبع الخلفي الأول "الصحي" أعلاه.

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

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

ماذا تفعل عندما تواجه Stack Smashing؟

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

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

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

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

do_the_mathsفي تتبع المكدس الأصلي 'الصحي') يمكن وضعها في المفضلة لديك محركات البحث.

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

قم دائمًا بتسجيل تقرير خطأ جديد إذا لم يظهر أن المشكلة قد تم تسجيلها عبر الإنترنت حتى الآن (قد تساعد الآخرين الذين يرون نفس الشيء!) وقم بتوفير أكبر قدر من المعلومات حول المشكلة كما يمكنك العثور عليها.يتم تسجيل الآلاف من تقارير الأخطاء المتعلقة بالعديد من التطبيقات عبر الإنترنت كل يوم. نأمل أن يكون فريق الدعم لتطبيق تحطيم المكدس في متناول اليد للمساعدة بسرعة.

قد ترغب أيضًا في قراءة مقال التصحيح باستخدام GDB: Getting Started التالي ، لأنه يعتمد بشكل أكبر على كيفية تصحيح برامج C و C ++ (وغيرها) باستخدام مصحح أخطاء GDB. كما يشرح كذلك مفاهيم المكدس بالتفصيل.

موضوع شعبي