يوفر Windows message Manager إمكانية وصول التطبيقات إلى تدفقات الرسائل التي يتم التحكم فيها.
آلية الخطاف (HOOK) المزعومة لـ 'c4'. هناك العديد من أنواع الخطافات، يستخدم كل منها لالتقاط نوع أو نطاق معين من الرسائل. مثل: رسائل لوحة المفاتيح، ورسائل الماوس، وما إلى ذلك. نحن نستخدم فقط استخدام خطافات لوحة المفاتيح كمثال هنا لمناقشة كيفية كتابة برامج DLL ضمن DELPHI وكيفية تثبيت وظائف ربط لوحة المفاتيح واستخدامها في برامجك الخاصة، ونناقش أيضًا كيفية مشاركة البيانات عندما تستخدم برامج مختلفة نفس ملف DLL .
1. تعليمات لكتابة وظائف مرشح الخطاف
نظرًا لأن وظيفة مرشح الخطاف يجب أن تكون في وحدة نمطية مستقلة، فهذا يعني أنه يجب علينا أولاً إنشاء إطار عمل DLL، ثم إضافة رمز وظيفة الخطاف ورموز الوظائف الأخرى ذات الصلة إليه. هنا نأخذ كتابة وظيفة مرشح ربط لوحة المفاتيح كمثال للتوضيح. الخطوات المحددة هي كما يلي:
1. قم أولاً بإنشاء سلة DLL 2
2. اكتب وظيفة مرشح ربط لوحة المفاتيح الخاصة بك
يجب أن تكون وظيفة مرشح الخطاف وظيفة رد اتصال، وتكون وظيفتها بالشكل التالي:
وظيفةKeyHookPRoc(
كود:عدد صحيح;
wParam:WPARAM;
lParam:LPARAM ): LRESULT;
أضف وظيفة معالجة ربط لوحة المفاتيح الخاصة بك إلى إطار عمل DLL الذي تم إنشاؤه للتعامل مع رسائل لوحة المفاتيح.
الكود كالتالي:…
إذا (iCode>=0) ثم ابدأ
النتيجة: = 0؛ // قيمة إرجاع التهيئة
// أضف الكود الخاص بك هنا
نهاية آخر
يبدأ
النتيجة:=CallNextHook(hOldKeyHook,iCode,wParam,lParam);
//hOldKeyHook هل هي وظيفة مرشح لوحة المفاتيح الأصلية المحفوظة؟
نهاية؛
3. قم بتثبيت وظيفة مرشح ربط لوحة المفاتيح
لتثبيت خطاف، يجب أن تستدعي وظيفة التصفية _fd الدالة SetWindowsHookEx (أصبحت وظيفة تثبيت الخطاف SetWindowsHook لنظام التشغيل Windows 3.0 قديمة الآن). النموذج الأولي لهذه الوظيفة هو كما يلي:
مجموعة HHOOKWindowsHookEx(
int idHook, // تم التثبيت؟_b3 النوع الفرعي
HOOKPROC lpfn, //مرشح الخطاف??عنوان رقم f
HINSTANCE hMod, // مقبض المهمة
DWord dwThreadId // الغرض من الخطاف
);
تجدر الإشارة إلى أن: ?_a8 يجب في كثير من الأحيان استدعاء الدالة MakeProcInstance للحصول على عنوان الإدخال الخاص بمقدمة دالة الإخراج، ثم استخدام هذا العنوان كمعلمة ثانية lpfn لـ SetWindowsHookEx. ومع ذلك، بما أن دلفي توفر "رد اتصال ذكي"، فيمكن حذف MakeProcInstance ويمكن استخدام اسم وظيفة مرشح الخطاف مباشرة كعنوان إدخال.
بهذه الطريقة، عندما تقرأ الدالة _c3GetMessage أو PeekMessage الخاصة بالتطبيق الرسائل من قائمة انتظار الرسائل أو تحتوي على رسائل أساسية (WM_KEYDOWN أو WM_KEYUP) لتتم معالجتها، سيقوم النظام باستدعاء وظيفة تصفية الخطاف KeyHookProc لمعالجة رسائل لوحة المفاتيح.
4. قم بإلغاء تثبيت وظيفة مرشح الخطاف.
عندما لا تكون هناك حاجة إلى وظيفة الربط، يجب استدعاء UnHookWindowsHookProc لإلغاء تثبيت الخطاف المثبت لتحرير موارد النظام.
قائمة البرامج الكاملة هي كما يلي؟_ba
مكتبة المفاتيح؛
يستخدم ويندوز.
const BUFFER_SIZE=16*1024;
const HOOK_MEM_FILENAME='SAMPLE KEY_HOOK_MEM_FILE';
const HOOK_MUTEX_NAME ='SAMPLE KEY_HOOK_MUTEX_NAME';
يكتب
TShared=سجل
المفاتيح: الصفيف [0..BUFFER_SIZE] من Char؛
عدد المفاتيح: عدد صحيح؛
نهاية؛
PShared=^TShared;
فار
MemFile,HookMutex: Thandle;
هولدكي هوك: هوك؛
ProcSaveExit: المؤشر؛
مشترك: PShared؛
// وظيفة مرشح ربط لوحة المفاتيح
وظيفة KeyHookProc(iCode: Integer; wParam: WPARAM ; lParam: LPARAM):LRESULT
تصدير.
const KeyPressMask = 80000000 دولار؛
يبدأ
إذا iCode <0 ثم
النتيجة: = CallNextHookEx(hOldKeyHook, iCode, wParam, lParam)
آخر تبدأ
إذا ((lParam و KeyPressMask) = 0) ثم // الضغط على المفتاح
يبدأ
Shared^.Keys[Shared^.KeyCount]:=Char(wParam and $00ff);
Inc(Shared^.KeyCount);
إذا كانت Shared^.KeyCount>=BUFFER_SIZE-1 ثم Shared^.KeyCount:=0;
نهاية؛
كود:=-1;
النتيجة := CallNextHookEx(hOldKeyHook, iCode, wParam, lParam);
نهاية؛
نهاية؛
// قم بتعيين وظيفة مرشح الخطاف
وظيفة EnableKeyHook: تصدير BOOL؛
يبدأ
Shared^.KeyCount:=0;//تهيئة مؤشر لوحة المفاتيح
إذا كان hOldKeyHook=0 فابدأ
hOldKeyHook := SetWindowsHookEx(WH_KEYBOARD,
كيهوكبروك,
مثيل،
0)؛
نهاية؛
النتيجة := (hOldKeyHook <> 0);
نهاية؛
// التراجع عن وظيفة مرشح الخطاف
وظيفة DisableKeyHook: تصدير BOOL؛
يبدأ
إذا كان hOldKeyHook<> 0 ثم
يبدأ
UnHookWindowsHookEx(hOldKeyHook);
hOldKeyHook:= 0;
مشترك^.KeyCount:=0;
نهاية؛
النتيجة := (hOldKeyHook = 0);
نهاية؛
// احصل على عدد ضغطات المفاتيح في المخزن المؤقت للوحة المفاتيح
وظيفة GetKeyCount: تصدير عدد صحيح؛
يبدأ
النتيجة:=مشتركة^.KeyCount;
نهاية؛
// احصل على مفاتيح المخزن المؤقت للوحة المفاتيح
وظيفة GetKey(index:Integer): تصدير Char؛
يبدأ
النتيجة:=مشتركة^.Keys[index];
نهاية؛
// امسح المخزن المؤقت للوحة المفاتيح
إجراء تصدير ClearKeyString؛
يبدأ
مشترك^.KeyCount:=0;
نهاية؛
// DLL عملية معالجة الخروج
إجراء KeyHookExit البعيد؛
يبدأ
إذا كان hOldKeyHook <> 0 ثم DisableKeyHook؛
UnMapViewOfFile(Shared); // حرر ملف صورة الذاكرة
CloseHandle(MemFile); // أغلق ملف الصورة
ExitProc := ProcSaveExit;
نهاية؛
الصادرات // تحديد وظيفة الإخراج
تمكينKeyHook,
ديسابليكي هوك,
جيتكيكونت,
كليركيسترينغ,
GetKey;
يبدأ
// جزء تهيئة DLL
HookMutex:=CreateMutex(nil,True,HOOK_MUTEX_NAME);
// شارك الذاكرة عن طريق إنشاء ملف صورة الذاكرة
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,
HOOK_MEM_FILENAME);
إذا MemFile = 0 ثم
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,
SizeOf(TShared) ,HOOK_MEM_FILENAME);
Shared:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
ReleaseMutex(HookMutex);
CloseHandle(HookMutex);
ProcSaveExit := ExitProc; // احفظ ExitProc الخاص بملف DLL
ExitProc := @KeyHookExit; // قم بتعيين ExitProc الجديد لملف DLL
نهاية.
// نهاية كود المصدر
2. استخدم وظيفة مرشح ربط لوحة المفاتيح المعدة في برنامجك الخاص.
بعد تجميع وظيفة الخطاف، فهي في الواقع سهلة الاستخدام للغاية: قم أولاً باستدعاء SetWindowsHookEx لتثبيت وظيفة مرشح الخطاف الخاصة بك، وفي نفس الوقت احفظ عنوان وظيفة مرشح الخطاف الأصلي. في هذا الوقت، يتم تشغيل وظيفة الخطاف، وسوف تتعامل مع رسائل لوحة المفاتيح وفقًا لمتطلباتك. عند انتهاء تشغيل البرنامج أو أنه لم يعد من الضروري مراقبة رسائل لوحة المفاتيح، قم باستدعاء الدالة UnHookWindowsHookProc لإزالة تثبيت وظيفة الخطاف المثبتة واستعادة عنوان وظيفة عامل تصفية الخطاف الأصلي.
فيما يلي مثال على استخدام وظيفة الخطاف المترجمة أعلاه:
الوحدة 1؛
واجهة
الاستخدامات
Windows، الرسائل، SysUtils، الفئات، الرسومات، عناصر التحكم، النماذج، مربعات الحوار،
StdCtrls، ExtCtrls؛
يكتب
TForm1 = الفئة (TForm)
مذكرة 1: مذكرة؛
اللوحة 1: لوحة T؛
bSetHook: TButton؛
بإلغاء الخطاف: TButton؛
مفاتيح القراءة: TButton؛
مفاتيح واضحة: TButton؛
اللوحة 2: لوحة T؛
الإجراء bSetHookClick(Sender: TObject);
الإجراء bCancelHookClick(Sender: TObject);
الإجراء bReadKeysClick(Sender: TObject);
الإجراء bClearKeysClick(Sender: TObject);
نهاية؛
فار Form1: TForm1؛
تطبيق
{$R *.DFM}
وظيفة EnableKeyHook: BOOL خارجي 'KEYHOOK.DLL'؛
وظيفة DisableKeyHook: BOOL الخارجية 'KEYHOOK.DLL'؛
وظيفة GetKeyCount: عدد صحيح خارجي؛
وظيفة GetKey(idx:Integer): Char خارجي 'KEYHOOK.DLL'؛
الإجراء ClearKeyString الخارجي "KEYHOOK.DLL"؛
الإجراء TForm1.bSetHookClick(Sender: TObject); // تعيين خطاف لوحة المفاتيح 7ó
يبدأ
this.EnableKeyHook;
bSetHook.Enabled :=False;
bCancelHook.Enabled:=True;
bReadKeys.Enabled :=True;
bClearKeys.Enabled :=True;
Panel2.Caption:='تم ضبط ربط لوحة المفاتيح';
نهاية؛
الإجراء TForm1.bCancelHookClick(Sender: TObject); // إلغاء تثبيت خطاف لوحة المفاتيح
يبدأ
this.DisableKeyHook;
bSetHook.Enabled :=True;
bCancelHook.Enabled:=False;
bReadKeys.Enabled :=False;
bClearKeys.Enabled :=False;
Panel2.Caption:='لم يتم ضبط ربط لوحة المفاتيح';
نهاية؛
الإجراء TForm1.bReadKeysClick(Sender: TObject); // الحصول على سجل ضغطات المفاتيح
فار ط:عدد صحيح؛
يبدأ
Memo1.Lines.Clear; // عرض سجل ضغطات المفاتيح في Memo1
لأني:=0 إلى GetKeyCount-1 افعل
Memo1.Text:=Memo1.Text+GetKey(i);
نهاية؛
الإجراء TForm1.bClearKeysClick(Sender: TObject); // مسح سجل ضغطات المفاتيح
يبدأ
مذكرة 1. واضح؛
ClearKeyString;
نهاية؛
نهاية.
// نهاية كود المصدر
3. تنفيذ الذاكرة المشتركة في DLL ضمن Windows95
في ملف DLL حيث توجد وظيفة الخطاف أعلاه، يجب استخدام الذاكرة المشتركة، أي أنه يتم تخزين كافة سجلات ضغطات المفاتيح في نفس مقطع البيانات. لماذا نفعل هذا؟ وذلك لأن أسلوب استدعاء DLL لنظام التشغيل Windows95 يختلف عن أسلوب Windows3.X. عندما يقوم كل مؤشر ترابط بتسجيل الدخول إلى مكتبة الارتباط الديناميكي، فسوف يقوم بتمرير مقبض مثيل جديد (أي مقبض مقطع بيانات DLL) إلى مكتبة الارتباط الديناميكي. يسمح هذا لمثيلات DLL المختلفة بعدم التداخل مع بعضها البعض، ولكنه يجلب بعض الصعوبات عندما تشترك جميع مثيلات DLL في مجموعة من المتغيرات. من أجل حل هذه المشكلة، قمنا بحلها هنا عن طريق إنشاء ملف معين للذاكرة. وهذا يعني استخدام OpenFileMapping وCreateFileMapping و
MapViewOfFile ثلاث وظائف لتحقيقها. كيفية استخدامه:
…
MemFile هو نوع Thandle، Shared هو نوع مؤشر، وHOOK_MEM_FILENAME عبارة عن سلسلة ثابتة.
…
MemFile:=OpenFileMapping(FILE_MAP_WRITE,False,
HOOK_MEM_FILENAME); // فتح ملف معين للذاكرة
إذا MemFile = 0 ثم // إذا فشل الفتح؟_c2 قم بإنشاء ملف معين للذاكرة
MemFile:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,
SizeOf(TShared) ,HOOK_MEM_FILENAME);
// تعيين الملفات إلى المتغيرات
Shared:=MapViewOfFile(MemFile,File_MAP_WRITE,0,0,0);
حتى الآن، أنت تعرف بالفعل مدى سهولة تجميع وظائف الخطاف في دلفي. أخيرًا، يجب أن أذكر الجميع: على الرغم من أن وظيفة الخطاف قوية نسبيًا، إلا أنها ستؤثر بشكل خطير على كفاءة النظام إذا تم استخدامها بشكل غير صحيح، لذا حاول تجنب استخدام خطافات النظام. ويجب توخي المزيد من الحذر عند استخدامه، بحيث يؤثر على تشغيل النظام بأقل قدر ممكن.
[نهاية النص الكامل]