23-08-2025, 05:44 PM
ما هو EasyHook؟
EasyHook مكتبة مفتوحة المصدر (MIT) تُبسّط تنفيذ API Hooking في ويندوز: اعتراض/استبدال استدعاءات الدوال الأصلية (native) بدوال مخصّصة تكتبها أنت — حتى لو كانت هذه الدوال في DLL غير مُدار — وكل ذلك من بيئة .NET مُدارة وعلى أنظمة 32-بت و64-بت. يدعم EasyHook بناء مكتبات حقن مُدارة (.NET 3.5/4.0+) وكذلك DLLs غير مُدارة، ويوفّر واجهات عالية المستوى مثل
لماذا قد أحتاج إلى Hooking أصلاً؟
هذا المثال يتّبع نفس خطوات درس «Creating a local hook» الرسمي (تحديد العنوان عبر
نموذج الحقن البعيد: إطلاق عملية و«حقن» تجميعة مُدارة ثم تركيب Hooks بداخلهاللتعامل مع عمليات أخرى لديك طريقتان:
Create & Inject: إنشاء العملية مُعلّقة ثم حقن مكتبتك قبل أن يبدأ كودها (مفيد لتعطيل مضادّات الـ hook مبكرًا):
2. Inject إلى عملية قائمة عبر PID:
بعد الحقن، تُنشئ داخل مكتبة الحقن «Hooks» محلية (مثل
نقاط تصميم مهمّة عند الاستخدام
بدائل أخرى مشهورة:
https://github.com/EasyHook/EasyHook
EasyHook مكتبة مفتوحة المصدر (MIT) تُبسّط تنفيذ API Hooking في ويندوز: اعتراض/استبدال استدعاءات الدوال الأصلية (native) بدوال مخصّصة تكتبها أنت — حتى لو كانت هذه الدوال في DLL غير مُدار — وكل ذلك من بيئة .NET مُدارة وعلى أنظمة 32-بت و64-بت. يدعم EasyHook بناء مكتبات حقن مُدارة (.NET 3.5/4.0+) وكذلك DLLs غير مُدارة، ويوفّر واجهات عالية المستوى مثل
LocalHook
وRemoteHooking
، إضافةً إلى مميّزات مثل قوائم تحكّم بالخيوط (Thread ACL) وميزة “حاجز الجمود” لتجنّب حالات التعليق أثناء الاعتراض.لماذا قد أحتاج إلى Hooking أصلاً؟
- مراقبة وتتبع السلوك: تسجيل عمليات الملفات/الشبكة، تشخيص أخطاء الإنتاج، بناء أدوات مراقبة خفيفة. (يوجد درس «RemoteFileMonitor» الذي يلتقط CreateFile/ReadFile/WriteFile ويبلّغ عبر IPC).
- الاختبار/التطعيم (Instrumentation): حقن سلوك مؤقّت لتجريب سيناريوهات نادرة بدون تعديل المصدر الأصلي.
- توسيع تطبيقات مغلَقة: إضافة hooks محددة بدل بناء إضافات معقّدة.
MessageBeep
الفكرة: نعترض user32!MessageBeep
ونبدّل نتيجتها.using System;
using System.Runtime.InteropServices;
using EasyHook;
class Program
{
// 1) مُمثّل يطابق توقيع الدالة الأصلية
[UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError = true)]
private delegate bool MessageBeepDelegate(uint uType);
// 2) استيراد الأصلية (اختياري إذا ستستدعي الأصل لاحقًا)
[DllImport("user32.dll")] static extern bool MessageBeep(uint uType);
// 3) معالج الـ Hook
private static bool MessageBeepHook(uint uType)
{
Console.Write("...intercepted...");
return false; // منع الصافرة (أو: return MessageBeep(uType); لتمريرها)
}
static void Main()
{
// 4) إنشاء الـ Hook وتفعيله لهذا الخيط فقط
using var hook = LocalHook.Create(
LocalHook.GetProcAddress("user32.dll", "MessageBeep"),
new MessageBeepDelegate(MessageBeepHook),
null);
hook.ThreadACL.SetInclusiveACL(new[] { 0 }); // 0 == الخيط الحالي
Console.WriteLine("Calling MessageBeep while hooked:");
MessageBeep(0x40);
}
}
هذا المثال يتّبع نفس خطوات درس «Creating a local hook» الرسمي (تحديد العنوان عبر
GetProcAddress
، تعريف المُمثّل، كتابة المعالج، ثم LocalHook.Create
وتهيئة ACL).نموذج الحقن البعيد: إطلاق عملية و«حقن» تجميعة مُدارة ثم تركيب Hooks بداخلهاللتعامل مع عمليات أخرى لديك طريقتان:
Create & Inject: إنشاء العملية مُعلّقة ثم حقن مكتبتك قبل أن يبدأ كودها (مفيد لتعطيل مضادّات الـ hook مبكرًا):
EasyHook.RemoteHooking.CreateAndInject(
targetExePath, args, 0,
injectionLibrary32, injectionLibrary64,
out int processId,
/* optional IPC args ... */);
2. Inject إلى عملية قائمة عبر PID:
EasyHook.RemoteHooking.Inject(
processId, InjectionOptions.Default,
injectionLibrary32, injectionLibrary64,
/* optional IPC args ... */);
بعد الحقن، تُنشئ داخل مكتبة الحقن «Hooks» محلية (مثل
CreateFileW
)، وتبلّغ التطبيق المُضيف عبر آلية IPC نقاط تصميم مهمّة عند الاستخدام
- المطابقة المعمارية (x86/amd64): حمّل DLL المناسب (32/64) بحسب عملية الهدف؛ يمكن استخدام تجميعات AnyCPU لكن الحقن يمرّ عبر EasyHook32/64 الأصليين. EasyHook
- Thread ACL: تحكّم بمن يتأثر بالـ hook (
/SetInclusiveACL
) لتقليل الأثر الجانبي. EasyHookSetExclusiveACL
- الاتّصال بين العمليات: جهّز قناة IPC آمنة/موثوقة لإرجاع النتائج. درس «RemoteFileMonitor» يعرض قالبًا جاهزًا. EasyHook
- الاستقرار والأداء: استخدم الـ hooks لأغراض دقيقة ومحدودة، وتجنّب العمل الثقيل داخل معالج الـ hook. ميزة “Thread Deadlock Barrier” تساعد، لكنها ليست عصًا سحرية
MessageBeep
)Imports System.Runtime.InteropServices
Imports EasyHook
Module Module1
<UnmanagedFunctionPointer(CallingConvention.StdCall, SetLastError:=True)>
Private Delegate Function MessageBeepDelegate(uType As UInteger) As Boolean
<DllImport("user32.dll")>
Private Function MessageBeep(uType As UInteger) As Boolean
End Function
Private Function MessageBeepHook(uType As UInteger) As Boolean
Console.Write("...intercepted...")
Return False
End Function
Sub Main()
Using hook = LocalHook.Create(
LocalHook.GetProcAddress("user32.dll", "MessageBeep"),
New MessageBeepDelegate(AddressOf MessageBeepHook),
Nothing)
hook.ThreadACL.SetInclusiveACL({0})
MessageBeep(&H40UI)
End Using
End Sub
End Module
بدائل أخرى مشهورة:
- Microsoft Detours (شائع جدًا في C/C++، رُخَصُه متنوّعة)،
- MinHook (خفيف لـ C/C++)،
- madCodeHook (تجاري).