Kernel mode - برمجة Driver Filter
#1
السلام عليكم و رحمة الله
في هذا الموضوع المطلوب هو محاولة برمجة نوع من Driver filter باستعمال SSDT Hook System Service Descriptor Table ، طبعا البرمجة بدلفي و لتسهيل العملية نستعمل واجهة التطوير Meerkat :tong:

المرحة الأولى :
- عمل هوك لــ ZwCreateFile و الحصول على كل ما يمرره النظام لهذه الدالة.
- عمل هوك لــ ZwOpenProcess و الحصول على كل ما يمرره النظام لهذه الدالة.
- عمل هوك لــ ZwLoadDriver و الحصول على كل ما يمرره النظام لهذه الدالة.

بالتوفيق ان شاء الله
الرد
#2
السلام عليكم ورحمة الله
Mohfa و TF6M انني انتظر Smile

حسب رائي نقوم بتنظيم المشروح بهذه الطريقة و لكم الخيار الأخير طبعا...

ننشئ وحدة تحتوي على الدوال و الاجراءات التي تستدعيها وحدات الهوك : KernelUtils.pas
ننشئ كل وحدة هوك على حدى و تحمل اسم الدالة التي يتم عمل لها Monitoring تحت تسمية : ZwXxxHook.pas
ننشئ وحدة المشروع الأساسية التي تقوم باستدعاء وحدات الهوك : DriverFilter.pas

الصورة توضح الفكرة :

[صورة: driverfilter.jpg]
الرد
#3
اخي STRELiTZIA اليس من المستحسن ان نبرمج ال Filter Driver باستعمال ال IFS Kit و ذلك للتعامل مع Flt Manager ..
لقد قمت بتحويل وحدتين مهمتين من ال IFS KIT الى Delphi و هما :
FltUser و NtDefs
اذا اردت ان اضعهما هنا فلا اشكال عندى ....

على كل حال سوف ابداء باذن الله في المشروع .
الرد
#4
إقتباس :اخي STRELiTZIA اليس من المستحسن ان نبرمج ال Filter Driver باستعمال ال IFS Kit و ذلك للتعامل مع Flt Manager ..
لقد قمت بتحويل وحدتين مهمتين من ال IFS KIT الى Delphi و هما :
FltUser و NtDefs
ترجمة IFS KIT الى دلفي عمل جيد جدا... من الأفضل ان تنشئ موضوع مستقل في القسم الخاص ليتسنى المشاركة فيه... لان الهدف من هذا الموضوع هو استغلال SSDT Hook للحصول على ما يمرر لدوال معينة في النظام و التطرق الى ايجابيات و سلبيات SSDT Hook و طرق تجاوزها مع ان كثير من برامج الحماية و الجدران النارية ما زالوا يستعملونها...

ايضا يمكنك اذا اردت ان تنشئ موضوع آخر يخص البتار لتجربة و المنفعة Smile و المناقشة و "تكسار الراس Smile"

إقتباس :على كل حال سوف ابداء باذن الله في المشروع
على بركة الله
الرد
#5
إقتباس :ايضا يمكنك اذا اردت ان تنشئ موضوع آخر يخص البتار لتجربة و المنفعة Smile و المناقشة و "تكسار الراس Smile"

كيف نسيت هاته الفكرة , و اتيت بها انت يا STRELiTZIA .
نعم ساقوم .
الرد
#6
السلام عليكم و رحمة الله و بركاته
شكر خاص للأستاذ STRELiTZIA على هذا الطرح المتميز :bye1: بارك الله فيك .

- أظن أنه قبل أن نبدأ بالعمل أظن أنه يجب شرح بعض المفاهيم المتعلقة بالـ Kernel Mode إظافة على
ذلك فإنه يتيح لي و للأخوة الأعضاء تصحيح الأخطاء (فما بني على باطل فهو باطلSmile) .

==================================================

1-القسم النظري :

//System Service Dispatch Table

الـ SSDT عبارة عن جدول يقع في الكيرنل لاند يقوم بإدارة الـ SYSCALL
كمثال على بعض الإستدعاءات :

NtDeleteFile / NtCreateFile .... هدا من أجل التعامل مع الملفات !!! .

[صورة: mod.gif]

حيث يتم وضع ZwOpenFile في جدول التعريفات وهكذا يتم تنفيذ كل الدوال المسجل بطريقة
متسلسلة .

//كيف ننشأ دريفر

1- كل دريفر يبدأ بالدالة DriverEntry كما يوحي اسمها هي نقطة دخول أو بداية الدريفر , يقوم الكيرنل بتنفيذ التعليمات أو الكود المكتوب في الدريفر و ذلك
عن طريق إرسال طلبات الإدخال و الإخراج I/O request packets - IRPs على سبيل المثال في Win32 يتم إستقبال الدالة ReadFile
على أنها طلب من أجل القراءة read IRP , و عليه يمكن أن نحدد كل دالة من اليوزد مود و طبيعة تعاملها مع الدريفر :

CreateFile == IRP_MJ_CREATE
CloseHandle == IRP_MJ_CLEANUP & IRP_MJ_CLOSE
WriteFile == IRP_MJ_WRITE
ReadFile == IRP_MJ_READ
DeviceIoControl == IRP_MJ_DEVICE_CONTROL

2- يقوم الكيرنل بإستدعاء DriverEntry عند تحميل الدريفر كما يمكن أيضا أن تستدعي العديد من الدوال أو الأجراءات الأخرى , يعني أنه كل ما
يتم فيها تهيئة الدريفر للتحميل فأنه يسجل كافة الدوال و الإجراءات المدعومة من الكيرنل فقط , عندها يقوم الكيرنل بإستدعاء هده الدوال أو
الإجراءات وفق روتينات و حالات خاصة

3- بطريقة عملية و مثالية يمكن لنا أن نقسم نقطة الدخول أو التحميل الخاصة بالدريفر هكدا :

DriverEntry : نقطة البداية أو الدخول يتم على مستواها تسجيل كل الإستدعاءات المبرمجة نحو الكيرنل .
Unload : إلغاء تحميل الدريفر .
IRP Handlers : مقابض روتينات الإرسال و الإستقبال التي نريد التعامل معها .

يمكن أيضا إظافة :

StartIo : روتين لجلب مقابض IRPs بشكل متسلسل .
Interrupt Service Routine - ISR : الإتصال بمقابض قطاعات الجهاز .

إذن الشكل العام للدريفر (على أساس تنظيم المشروع ) DriverFilter :

PHP كود :
var
    
DeviceName, SymbolicLinkName: UNICODE_STRING;
    
   
procedure DriverUnload(p_DriverObject: PDRIVER_OBJECT); stdcall;
   
begin
    
if IoDeleteSymbolicLink(@SymbolicLinkName) <> STATUS_SUCCESS then
     DbgPrint
('DeleteSymbolicLink Fail!');
    
IoDeleteDevice(p_DriverObject^.DeviceObject);
   
end;
   
   function 
DispatchCreate(p_DeviceObject: PDEVICE_OBJECT; p_Irp: PIRP):
   
NTSTATUS; stdcall;
   
begin
    DbgPrint
('DisPatchCreate!');
    
p_Irp^.IoStatus.Status := STATUS_SUCCESS;
    
p_Irp^.IoStatus.Information := 0;
    
IofCompleteRequest(p_Irp, IO_NO_INCREMENT);
    
result := STATUS_SUCCESS;
   
end;
    
   function 
_DriverEntry(pDriverObject: PDRIVER_OBJECT; RegistryPath:
   
PUnicodeString): NTSTATUS; stdcall;
   var
    
pDeviceObject: TDeviceObject;
    
   
begin
    Result 
:= STATUS_DEVICE_CONFIGURATION_ERROR;
    
RtlInitUnicodeString(DeviceName, '\DriverFilter');
    
RtlInitUnicodeString(SymbolicLinkName, '\??\DriverFilterApp');
    if (
IoCreateDevice(pDriverObject, 0, @DeviceName, FILE_DEVICE_UNKNOWN,
   
0, FALSE, pDeviceObject) = STATUS_SUCCESS) then
    begin
     
if (IoCreateSymbolicLink(@SymbolicLinkName, @DeviceName) = STATUS_SUCCESS)
   
then
     begin
      pDriverObject
^.MajorFunction[IRP_MJ_CREATE] := @DispatchCreate;
      
//pDriverObject^.MajorFunction[IRP_MJ_CLOSE] := @DispatchClose;
      //pDriverObject^.MajorFunction[IRP_MJ_WRITE] := @DispatchWRITE;
      //pDriverObject^.MajorFunction[IRP_MJ_READ] := @DispatchREAD;
      
pDriverObject^.DriverUnload := @DriverUnload;
      
Result := STATUS_SUCCESS;
     
end else
     
begin
      DbgPrint
('IoCreateSymbolicLink fail!');
      
IoDeleteDevice(@pDeviceObject);
     
end;
    
end else
     
DbgPrint('IoCreateDevice Fail!');
    
result := STATUS_SUCCESS;
   
end; 

أكتفي بهذا القدر مع الذكر بأني لم أجرب تشغيل الكود أعلاه
لكن فقط إستنتاجات ... أكمل المرة القادمة إن شاء الله .


الملفات المرفقة
.rar   KernelUtils.rar (الحجم : 6.3 ك ب / التحميلات : 31)
I'M Fly Like A G6

الرد
#7
السلام عليكم و رحمة الله
System Service Dispatch Table
هذا الجانب الذي يخص تبادل الاتصال بين الــ User mode و الــ Kernel mode و انشاء [FONT=Simplified Arabic Fixed]SymbolicLink و تسسير الأحداث Events سنتطرق اليه ان شاء الله في بعد لانه بعيد عن الموضوع...

اذا اردت البحث عن كيفة التعمل مع : System Service Descriptor Table حاول فهم :

KeServiceDescriptorTable
InterlockedExchange

بالتوفيق ان شاء الله
الرد
#8
و عليكم السلام

1- لم يكن الهدف التطرق لـ SSDT بوجه الخصوص فقط مقدمة لترسيخ المعلومات
2- لم أكمل بعد ... **** وضع رسم تخطيطي للميكانيزم و المناقشة في جزئيات تفيد .
3- طريقة الإقتناص و تبديل مسار الـ SysCall لدوال الـ Hook التي سنضيفها نظريا ...

إذا كان مخالف عذرا و سألتزم بالموضوع المطروح .
I'M Fly Like A G6

الرد
#9
افضل المشاركة بهذه الطريقة :
- يقوم كل مشارك بطرح العمل المنجز دون ملفات مصدرية.
- تتم تجربة المرفق..
- ثم يقوم كل مشارك بوضع شرح للطريقة نظريا و طبعا اضافة الملفات المصدرية.

فائدة هذه الطريقة من العمل هو الاستفادة من تعدد الأفكار الكاملة -المنجزة-
يعني بحث ثم فهم ثم تجريب ثم طرح الانجاز و بعدها مناقشته مع طرح الملفات المصدرية و اخيرا نشره في المنتدى العام -خارج القسم الخاص- Smile
الرد
#10
[COLOR="Red"]لم اكن اعلم اني من الأعضاء المميزين Big Grin

جئت القي التحية والسلام على صديقي وزميل الكفاح الأخ STRELiTZIA Smile
اشتقنا اليك كثيرا ، لتوّي انتهيت من الامتحانات وامامي 4 شهور كاملة لنلعب فيها بالكرنل .
لدي أشياء ستعجبك في KD STRELiTZIA Edition لكن أترك هذا لوقته :beta:

سلامي لكم .

P.S. هذا ليس Filter driver .[/COLOR]
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم