من الممكن فخ الكتابة إلى عنوان (x86 - لينكس)

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

  •  03-07-2019
  •  | 
  •  

سؤال

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

أود أن تكون قادرة على القيام بذلك في وقت التشغيل (ربما gdb لديه هذه الميزة, ولكن بصفة خاصة تطبيق أسباب gdb إلى تعطل).

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

المحلول

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

نصائح أخرى

ما تحتاجه هو الوصول إلى X86 تصحيح السجلات: http://en.wikipedia.org/wiki/Debug_register

سوف تحتاج إلى تعيين نقطة توقف عنوان في واحدة من DR0 إلى DR3 ثم الشرط (كتابة البيانات) في DR7.المقاطعة سوف تحدث يمكنك تشغيل رمز التصحيح قراءة DR6 و تجد ما تسبب في توقف.

إذا GDB لا يعمل ، قد حاولت أبسط/أصغر المصحح مثل http://sourceforge.net/projects/minibug/ - إذا كان هذا لا يعمل, يمكنك على الأقل أن تذهب من خلال رمز وفهم كيفية استخدام التصحيح الأجهزة على معالج نفسك.

أيضا هناك مجموعة كبيرة IBM المطور الموارد على اتقان لينكس تقنيات التصحيح التي ينبغي أن توفر بعض الخيارات الإضافية:

http://www.ibm.com/developerworks/linux/library/l-debug/

معقول مقالة جيدة على القيام بذلك هو ويندوز هنا (أعلم أنك تعمل على لينكس, ولكن البعض الآخر قد تأتي جنبا إلى جنب على هذا السؤال الرغبة في القيام بذلك في نظام التشغيل windows):

http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx

-آدم

وGDB لديها هذه الميزة: ويطلق عليه watchpoints الأجهزة، وأنها مدعومة بشكل جيد جدا على لينكس / إلى x86:

(gdb) watch *(int *)0x12345678

إذا تعطل التطبيق الخاص بك GDB، وبناء GDB الحالي من CVS رئيس .

وإذا كان هذا لا يزال GDB فشل ملف GDB علة .

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

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

كما آدم قال: ما تريد إلى التلاعب في تصحيح السجلات.على ويندوز, أنا استخدم هذا: http://www.morearty.com/code/breakpoint/ وعملت كبيرة.أنا أيضا استدار إلى ماخ-O (Mac OS X) ، وعملت كبيرة أيضا.كان من السهل أيضا ، لأن ماخ-O thread_set_state () ، وهو ما يعادل SetThreadContext().

المشكلة مع لينكس هو أنه لا يملك مثل هذه حكمه.وجدت ptrace, ولكن أعتقد أن هذا لا يمكن أن يكون ذلك ، يجب أن يكون هناك شيء أكثر بساطة.ولكن ليس هناك.بعد.أعتقد أنهم يعملون على hw_breakpoint API لكل نواة الفضاء المستخدم.(انظر http://lwn.net/Articles/317153/)

ولكن عندما وجدت هذا: http://blogs.oracle.com/nike/entry/memory_debugger_for_linux حاولت و لم يكن سيئا.على ptrace الأسلوب يعمل من قبل بعض "خارج العملية" بوصفها "المصحح" إرفاق البرنامج الخاص بك ، بالحقن قيم جديدة من أجل تصحيح سجلات تنتهي مع البرنامج تواصل مع الأب تعيين نقطة توقف.الشيء هو, يمكنك إنشاء هذا "الخارج" عملية نفسك باستخدام شوكة(), (ليس لدي أي نجاح مع pthread) و تفعل هذه الخطوات البسيطة المضمنة في التعليمات البرمجية الخاصة بك.

على addwatchpoint رمز يجب أن تتكيف مع العمل مع 64 بت لينكس, ولكن هذا مجرد تغيير USER_DR7.... الخإلى offsetof(البنية المستخدم ، u_debugreg[7]).شيء آخر هو أنه بعد PTRACE_ATTACH ، عليك أن تنتظر debuggee للتوقف عن الواقع.ولكن بدلا من إعادة محاولة POKEUSER في مشغول حلقة ، الشيء الصحيح القيام به سيكون waitpid() على pid.

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

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