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

) .
==================================================
1-
القسم النظري :
//
System Service Dispatch Table
الـ SSDT عبارة عن جدول يقع في الكيرنل لاند يقوم بإدارة الـ SYSCALL
كمثال على بعض الإستدعاءات :
NtDeleteFile / NtCreateFile .... هدا من أجل التعامل مع الملفات !!! .
حيث يتم وضع 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;
أكتفي بهذا القدر مع الذكر بأني لم أجرب تشغيل الكود أعلاه
لكن فقط إستنتاجات ... أكمل المرة القادمة إن شاء الله .