تم إنشاء الوحدة كجزء من رسالة الماجستير الخاصة بي في عام 2010. موضوع أطروحة الماجستير هو Keylogging في Linux kernel . كانت الفكرة الرئيسية هي اكتشاف طريقة لاعتراض دعوات النظام لـ x 64 arch Linux kernel ، وخاصة kernel 2.6.34.7-61.fc13.x86_64.
مقدمة
كان هناك الكثير من المقالات المختلفة حول اعتراض استدعاء النظام لـ x32 arch. كجزء من البحث ، واجهت مشكلة كيفية اعتراض دعوات النظام لـ x86_64 arch عبر Linux-kernel module.
كيف يمكننا اعتراض مكالمة النظام؟
- معرفة عنوان الجدول syscall.
- استبدال استدعاء النظام الأصلي من جديد.
عنوان جدول Syscall
IDT ( I nterrupt D escription T قادرة) حدود المعالج رمز المقاطعة . في الوضع المحمي ، IDT عبارة عن مجموعة من الواصفات المخزنة في الذاكرة. كل معالج لديه سجل IDTR خاص. يتكون السجل من عنوان IDT الفعلي وطول IDT. كان الافتراض الأول هو الحصول على عنوان IDT من سجل IDTR وبعد ذلك حساب عنوان جداول syscall. ومع ذلك ، كان الافتراض خاطئًا ، لأنه في هذه الحالة ، حصلنا على عنوان معالج x32.
وكان الافتراض الثاني أكثر إثارة للاهتمام. قبل المتابعة ، أود وصف MSR (Macodell Specific R egister). MSR هي أي من سجلات التحكم المختلفة في مجموعة تعليمات x86 المستخدمة للتصحيح وتتبع تنفيذ البرنامج ومراقبة أداء الكمبيوتر وتبديل بعض ميزات وحدة المعالجة المركزية. دعونا نتحدث عن MSR_LSTAR
- 0xc0000082
(الهدف SYSCALL طويل الوضع). يمكنك الحصول على قائمة كاملة على /usr/include/asm/msr-index.h
.
MSR_LSTAR
بتخزين إدخال استدعاء النظام للعمارة x86-64. يمكنك الحصول على العنوان:
int i, lo, hi; asm volatile("rdmsr" : "=a" (lo), "=d" (hi) : "c" (MSR_LSTAR)); system_call = (void*)(((long)hi<<32) | lo);
دعنا نذهب أبعد من ذلك. لقد حصلت على العنوان \xff\x14\xc5
عن \xff\x14\xc5
. \xff\x14\xc5
هي أرقام سحرية. إذا نظرت إلى رمز kernel 2.6.34.7-61.fc13.x86_64 ، خاصة ، system_call
، system_call
أن وحدات البايت الأربع التالية هي عنوان syscall_table.
لقد عرفنا عنوان جدول syscall ، فهذا يعني أنه يمكننا الحصول على عنوان معالج syscall واستبداله / اعتراضه.
شفرة المصدر:
unsigned char *ptr; for (ptr=system_call, i=0; i<500; i++) { if (ptr[0] == 0xff && ptr[1] == 0x14 && ptr[2] == 0xc5) return (void*)(0xffffffff00000000 | *((unsigned int*)(ptr+3))); ptr++; }
اعتراض استدعاء النظام
واجهت مشكلة. حدث خطأ في حالة تغيير عنوان في جدول استدعاء النظام. لحسن الحظ ، كان من السهل كما فطيرة:
- تعطيل حماية الذاكرة.
- أعد كتابة عنوان معالج syscall.
- تمكين حماية الذاكرة.
إذا كنت ترغب في تعطيل حماية الذاكرة ، فيجب أن تعرف: السجل CR0
يتكون من الأعلام. الأعلام إدارة سلوك المعالج. العلم WP هو Write Protect
، وهذا هو 48 بت في CR0
.
تعطيل حماية الذاكرة:
asm("pushq %rax"); asm("movq %cr0, %rax"); asm("andq $0xfffffffffffeffff, %rax"); asm("movq %rax, %cr0"); asm("popq %rax");
تمكين حماية الذاكرة:
asm("pushq %rax"); asm("movq %cr0, %rax"); asm("xorq $0x0000000000001000, %rax"); asm("movq %rax, %cr0"); asm("popq %rax");
الخاتمة
من ناحية ، يجب أن يكون كافياً للتعامل مع اعتراض استدعاء النظام ، لكن من ناحية أخرى ، لست متأكدًا من أنه لم يتغير شيء منذ عام 2010. لذا استخدمه كما هو. شفرة المصدر يقع في github.com/ultral/linux-keylogger .
PS