Windows Driver (Part 1)
Introduction to Windows Drivers
ال Drivers هي عبارة عن برامج تعمل كوسيط بين نظام التشغيل والاجهزة المتصلة. عند تركيب hardware جديد على الجهاز مثل GPU نظام التشغيل يبحث عادةً عن Drivers المناسب ويثبتها تلقائيًا. يتم تشغيل Drivers في Kernel Mode وهذا يسمح لها الحصول على تحكم كامل على الجهاز.

Environment Configuration
قامت Microsoft بتقديم policy جديدة بأسم Driver Signing لنظام Windows 10 والأصدارات الحديثة للمحافظة على نظام التشغيل من البرامج الخبيثة. هذه ال Policy تجبر الشركات على توقيع (Sign) ال drivers الخاصة بهم لكي تتمكن من العمل في Kernel Mode. يمكن تحويل النظام الى Test Mode لتخطي Policy. شغل CMD بصلاحيات Administrator ونفذ الأوامر التالية لتفعيل Test Mode و Kernel Debugging:
شغل WinDBG في الجهاز الثاني ودخل Port Number و Key في File > Kernel Debug > NET

أذا سويت restart للجهاز الأول رح تشوف شي مشابه للصورة هذه:

Creating Our First Driver
نعرف Prototype او ال Parameters الي ياخذهم DriverEntry:
طالما نقدر نسوي debug لل driver عن طريق WinDBG نقدر نطبع رسالة عن طريق ()DbgPrint :
من اهم الأشياء الي لازم تصير اذا رح نسوي unload لل driver هو free our resources عشان ما يكون في اي Memory leaks. رح نسوي function يسوي هذه العملية لنا بس اول شي خلونا نحجز مكان في Memory:
اذا صارت عملية unload ال DriverUnload رح ينادي DriverFree function ومحتواها بسيط فقط بتسوي
:free the allocated memory
لازم ننشئ service حتى نقدر نشغل ال Driver:
اول ما يشتغل ال Driver وتوقفه رح تقدر تشوف كل شي في WinDBG:

IRP Major Function Codes
ال IRP هو اختصار ل I/O Request Packet كل IRP يكون فيها MajorFunction code (IRP_MJ_XXX) والي تساعد driver يعرف ايش العملية لتلبية طلب I/O Request. كل Driver لازم يوفر dispatch routines لل Major Function الي يدعمها هذه بعض ال Major Function:

رح نستخدم IRP_MJ_CREATE و IRP_MJ_CLOSE حتى نقدر نفتح و نغلق ال Device:
كل Driver لازم يكون له Device Object و Symlink حتى نقدر نتواصل مع Driver من ال User Mode. نقدر نسوي هذه العملية عن طريق IoCreateDevice و IoCreateSymbolicLink :
رح نستخدم IOCTLs عشان يقدر ال client يحدد اي function ال driver رح يستخدم. تقدر في نفس project تنشئ header file عشان نعرف IOCTL. واجهة عدة مشاكل في تعريفهم لكن هذه article ساعدتني.
ننشئ function جديد وضيفته يستخرج ال IOCTL من Client:
رح نستخدم IRP_MJ_DEVICE_CONTROL الي رح يتحكم في I/O control requests :
ال Client Code رح يكون بسيط, كل الي رح نسويه هو فتح handle لل Driver عن طريق CreateFile. وبعدها رح نستخدم DeviceIoControl والي رح ينادي IRP_MJ_DEVICE_CONTROL:


Send and Receive Data
اخر حاجة رح اشرحها هو كيف نقدر نرسل بيانات ونستلمها من ال Driver وطبعاً هذا كله يتم من خلال DeviceIoControl . في البداية رح نسوي two structures واحد خاص بال Client Input والثاني بال Results/Response:
الان رح نخلي ال Driver يستلم البيانات و يرجعها لل Client. أضفت checks عشان نتفادى BSOD:
طيب من ناحية ال Client Code رح نستخدم نفس ال header file لأن فيه ال Structure الي نحتاجه. بس الي علينا اننا نعرف متغير فيه البيانات الي رح ترسل ومتغير يستلم الأجابة:

References
Last updated
Was this helpful?

