معهد دعم اتش فى اى بى اس لحلول الويب - Powered by vBulletin


 
 
النتائج 1 إلى 1 من 1

الموضوع: أسمبلي 32بت: Windows Hook لنتعلم مع

  1. #1
    عضو جديد


    تاريخ التسجيل: Jun 2011
    رقم العضوية: 7
    المشاركات: 2,181
    HVIPS5 غير متواجد حالياً

    أسمبلي 32بت: Windows Hook لنتعلم مع


    أسمبلي 32بت: Windows Hook لنتعلم مع
    أسمبلي 32بت: Windows Hook لنتعلم مع
    أسمبلي 32بت: Windows Hook لنتعلم مع

    Windows Hook

    سنتعلم في هذا الدرس طريقة لمراقبة الرسائل التي يوّلدها النظام و معالجة بعضها باستعمال "الخطف" (Hook)

    المحتوى:

    كود:
    1. نظرة عامة
                 2. تركيب/فك إجراء خطف الرسائل
                 3. إجراءات خطف الرسائل
                         3. 1. خطف رسائل الفأرة و معالجتها
                         3. 2. خطف رسائل لوحة المفاتيح و معالجتها
                 4. البرنامج


    1. نظرة عامة

    الخطف هو طريقة لمراقبة الرسائل التي تدور داخل النظام و معالجة بعضها (و ذلك حسب نوع الخطف الذي وضعناه) باستعمال إجراء خطف (Hook Procedure) نقوم بتثبيته. عند حدوث أي رسالة يهتم هذا الإجراء بمعالجتها، يقوم النظام باستدعائه قبل أن تصل هذه الأخيرة –الرسالة- إلى وجهتها و هو إجراء النافذة المعني بها.

    يمكن تقسيم الخطف إلى صنفين:

    • الخطف المحلّي (Local Hook): إلتقاط الأحداث التي تحصل في العملية الخاصة ببرنامجك
    • الخطف عن بعد (Remote Hook): إلتقاط الأحداث التي تحصل في العمليات الأخرى



    ينقسم الخطف عن بعد إلى نوعين:

    • خطف يحصل في Thread معين: التقاط الأحداث التي تقع في Thread نحدده حيث يكون هذا الـThread متواجد في عملية أخرى
    • خطف يحصل على كامل النظام: التقاط الأحداث التي تقع في كل الـThreads و في مختلف العمليات


    ملاحظة: سنرى في هذا الدرس الخطف عن بعد لكل الأحداث التي تحصل في كامل النظام و الذي يتطلّب إجراء خطف يتواجد في مكتبة ربط ديناميكي

    يوفّر لنا Windows أنواع مختلفة من الخطف، كل نوع يمنحنا الوصول إلى جانب معين من معالجة الرسائل. على سبيل المثال، يمكننا مراقبة الرسائل التي تُصدرها الفأرة من خلال وضع خطف لرسائل الفأرة باستعمال نوع الخطف WH_MOUSE

    يقوم النظام بإنشاء لائحة تسمى "سلسلة الخطف" (Hook Chain) و التي يضع فيها مؤشرات لمختلف إجراءات الخطف التي تم وضعها لمراقبة الرسائل، و ذلك عند وقوع أي حدث يقوم النظام بالبحث في هذه اللائحة عن إجراء خطف يعالج مثل هذه الأحداث ليرسل إليه معلومات عن الحدث.

    ملاحظة:
    1- عند وضع خطف جديد لنوع معيّن من الرسائل يقوم النظام بتثبيت مؤشر الإجراء المكلّف بالخطف المُنشَأ في أول اللائحة التي تحتوي على مؤشرات إجراءات الخطف
    2- عند وقوع أي حدث يقوم النظام بالبحث عن مؤشر لأول إجراء يهتم بمعالجة مثل هذا الأخير –الحدث- ليستدعيه، عندها يكون للإجراء المستدعي حرية تمكين النظام من إكمال عملية البحث عن باقي الإجراءات.

    2. تركيب/فك إجراء خطف الرسائل

    لتركيب إجراء خطف جديد في "سلسلة الخطف" ليصبح قادر على إستقبال الرسائل و معالجتها، نستعمل الدالة SetWindowsHookEx التي توفّر لنا أنوع مختلفة من الخطف.

    نموذج الدالة:

    كود:
    SetWindowsHookEx PROTO Type:DWORD,pHookProc:DWORD,\
                           hDLL:DWORD,ThreadId:DWORD

    • Type: نحدد نوع إجراء الخطف الذي نريد تثبيته


    يمكننا تحديد قيمة من القيم التالية:
    - WH_KEYBOARD: لتثبيت إجراء خطف يقوم بمراقبة الرسائل التي تصدرها لوحة المفاتيح
    - WH_MOUSE: لتثبيت إجراء خطف يستقبل معلومات عن رسائل الفأرة

    • pHookProc: نمرر مؤشر إلى إجراء خطف موجود في مكتبة ربط ديناميكي
    • hDLL: نمرر مقبض المكتبة التي تحتوي على إجراء الخطف المُحدّد في المعامل السابق (pHookProc)
    • ThreadId: نحدد مقبض الـThread الذي نريد خطف رسائله. إذا أردنا مراقبة رسائل كل الـThreads نمرر صفر



    القيم المرجعة: إذا نجحت الدالة ترجع لنا مقبض إجراء الخطف، ما عدا ذلك ترجع 0

    ملاحظة: يوجد العديد من الأنواع الأخرى للخطف لكننا سندرس تلك التي قمت بعرضها

    تتسبب عملية الخطف في تأثيرات جانبية على أداء النظام حيث يصبح بطيء شيئا فشيئا لذلك علينا التخلص من إجراء الخطف الذي ثبّتناه بعد الإنتهاء من إستعماله -للحفاظ على أداء جيد للنظام- و ذلك بتمرير مقبض الإجراء الذي نريد إزالته إلى الدالة UnhookWindowsHookEx

    3. إجراءات خطف الرسائل

    تتشارك إجراءات مختلف أنواع الخطف في نفس نموذج الإجراء الذي يملك الصيغة التالية:

    كود:
    HookProc PROTO nCode:DWORD, wParam:DWORD, lParam:DWORD
    حيث أنّ الإختلاف يكون في المعلومات التي نستقبلها في معاملات الإجراء و هي تختلف من نوع إلى آخر. يحتوي المعامل nCode على رمز يستعمله الإجراء ليحدد الفعل الذي سيؤدّيه، أما المعاملين wParam و lParam دائما يحتويان على معلومات عن الرسالة التي تم طرحها

    ملاحظة: لنا حرية تغيير إسم إجراء الخطف مع المحافظة على نفس المعاملات

    ضمن هذا الإجراء يمكننا وضع الأكواد المناسبة لمعالجة الرسائل التي نستقبلها، المهم هو بعد الإنتهاء من عملية المعالجة و أردنا تمرير الرسالة التي التقطناها إلى باقي الإجراءات التي تهتم بهذا النوع من الرسائل نستعمل الدالة CallNextHookEx
    كود:
    CallNextHookEx PROTO hHook:DWORD,nCode:DWORD,wParam:DWORD,lParam:DWORD

    • hHook: نمرر مقبض إجراء الخطف الذي استقبل الرسالة
    • nCode-wParam-lParam: نمرر المعلومات التي استقبلناها في المعاملات nCode-wParam-lParam


    3. 1. خطف رسائل الفأرة و معالجتها

    يمكّننا الخطف WH_MOUSE من مراقبة الرسائل التي تحدثها الفأرة و معالجتها باستعمال إجراء MouseProc
    كود:
    MouseProc PROTO nCode:DWORD, wParam:DWORD, lParam:DWORD

    • nCode: إذا كان هذا المعامل يحتوي على القيمة HC_ACTION، يعني أنّ المعاملين wParam و lParam يحتويان على معلومات عن رسالة أحدثتها الفأرة. إذا كان هذا المعامل يحتوي على قيمة أقل من 0 علينا استدعاء الدالة CallNextHookEx
    • wParam: يحتوي على معرّف الرسالة
    • lParam: مؤشر إلى البنية MOUSEHOOKSTRUCT


    ملاحظة: إذا أردنا تمكين النظام من تمرير الرسالة، علينا إرجاع القيمة 0 في المسجل EAX. أما إذا أردنا نبذ الرسالة و رميها من دون تمريرها لباقي الإجراءات و منها إجراء النافذة المعني بها، نرجع قيمة مخالفة للصفر.

    تحتوي البنية MOUSEHOOKSTRUCT على معلومات الحدث الذي وقع بسبب الفأرة. تملك هذه البنية التعريف التالي:

    كود:
    MOUSEHOOKSTRUCT STRUCT
      pt            POINT      <>
      hwnd          DWORD      ?
      wHitTestCode  DWORD      ?
      dwExtraInfo   DWORD      ?
    MOUSEHOOKSTRUCT ENDS

    • pt: مؤشر إلى البنية POINT التي تحتوي على إحداثيات مؤشر الفأرة
    • hwnd: مقبض النافذة التي يشير إليها مؤشر الفأرة


    ملاحظة: باقي المعلومات ليست مهمة بالنسبة لنا

    3. 2. خطف رسائل لوحة المفاتيح و معالجتها

    يمكّننا الخطف WH_KEYBOARD من مراقبة الرسالتين WM_KEYDOWN و WM_KEYUP التي تحدثها لوحة المفاتيح و معالجتها باستعمال إجراء KeyboardProc

    كود:
    KeyboardProc PROTO nCode:DWORD, wParam:DWORD, lParam:DWORD

    • nCode: إذا كان هذا المعامل يحتوي على القيمة HC_ACTION، يعني أنّ المعاملين wParam و lParam يحتويان على معلومات المفتاح الذي تم الضغط عليه. إذا كان هذا المعامل يحتوي على قيمة أقل من 0 علينا استدعاء الدالة

    CallNextHookEx.

    • wParam: يحتوي على كود المفتاح الإفتراضي (Virtual-Key Code) و هو معرّف للزر الذي تمّ الضغط عليه.



    • lParam: يحمل كلمة مضاعفة (DWORD) تحتوي على معلومات إظافية عن المفتاح الذي تم الضغط عليه حيث أنّ كل مجموعة من البتات من هذا المعامل تعني معلومة معيّنة.


    تتمثل هذه المعلومات في عدد مرات الضغط، علم يرفع إذا كان المفتاح Extended (ALT،CTRL،INS،DEL،HOME،END،PAGE UP،PAGE DOWN،مفاتيح الإتجاهات،NUM LOCK،BREAK،PRINT SCRN،/،ENTER، Numeric Keypad)، حالة المفتاح ALT، الحالة السابقة للمفتاح، حالة المفتاح (تم الضغط عليه أو رفع الضغط عليه).

    ملاحظة:
    1- لتمكين النظام من تمرير الرسالة إلى بقية إجراءات الخطف و إجراء النافذة المُستهدف من قبل الرسالة علينا إرجاع القيمة 0 في المسجل EAX. إذا أردنا عكس ذلك نمرر قيمة مخالفة للصفر.
    2- كل مفتاح موجود في لوحة المفاتيح له تعريف عند النظام Windows يدعى "كود المفتاح الإفتراضي. يمكنك الإطلاع على هذه الأكواد في المرجع "Win32 Programmer's Reference" تحت عنوان "Virtual-Key Codes"

    نقره لتكبير أو تصغير الصورة ونقرتين لعرض الصورة في صفحة مستقلة بحجمها الطبيعي

    0-15: عدد مرات الضغط على المفتاح
    24: علم يأخذ القيمة 1 إذا كان المفتاح المضغوط موسّع (Extended Key) ماعدا ذلك يأخذ 0
    29: يأخذ القيمة 1 إذا كان المفتاح ALT مضغوط ماعدا ذلك يأخذ 0
    30: يحمل الحالة السابقة للمفتاح. إذا كان هذا العلم مرفوع (قيمته 1) يعني أنّه تمّ الضغط عن المفتاح قبل حدوث الرسالة، و في حالة كانت قيمته 0 يعني أنه تمّ رفع الضغط عليه
    31: إذا كانت قيمته 1 هذا يعني أنه تمّ الضغط على المفتاح و إذا كانت 0 يعني أنه تمّ رفع الضغط عليه

    عند الحصول على كود المفتاح الإفتراضي يمكننا معرفة المفتاح الذي تم الضغط عليه و الحصول على كود أسكي الخاص به. و يكون ذلك باستعمال الدالتين GetKeyboardState و ToAscii

    GetKeyboardState: نستعمل هذه الدالة لجلب حالة المفاتيح الإفتراضية و ذلك لمعرفة إذا كان المفتاح المضغوط يشير إلى حرف كبير أم صغير و معلومات أخرى عن خصائص الضغط عن المفتاح. تأخذ هذه الدالة معامل واحد وهو مؤشر إلى مصفوفة تتكون من 256 بايت تُرجع فيها الدالة حالة المفاتيح.

    كود:
    GetKeyboardState PROTO pKeyState:DWORD
    بعد الحصول على حالة المفاتيح الإفتراضية، يصبح كل بايت موجود في المخزن المُمرّر يشير إلى معلومة معيّنة. يمكننا تمرير هذا المخزن إلى الدالة ToAscii لتقوم بترجمة كود المفتاح الإفتراضي و حالة المفاتيح الإفتراضية إلى حرف.

    نموذج الدالة:

    كود:
    ToAscii PROTO VirtKey:DWORD,ScanCode:DWORD,\
                  pKeyState:DWORD,pChar:DWORD,Flag:DWORD

    • VirtKey: نمرر كود المفتاح الإفتراضي
    • ScanCode: لا نحتاجه –نمرر NULL-
    • pKeyState: مؤشر إلى مخزن حالة المفاتيح
    • pChar: مؤشر إلى حجرة نستقبل فيها كود أسكي الحرف -لا تتجاوز هذه الحجرة 2 بايت-
    • Flag: لا نحتاجه –نمرر NULL-



    القيم المرجعة:
    إذا كانت القيمة المرجعة 0، يعني أنّ المفتاح المضغوط ليس له مقابل في جدول الأسكي. إذا كانت 1، يعنى أنه تمّ ترجمة حرف. أما إذا كانت 2 فهذا يعني أنه تمّ ترجمة حرفين.

    4. البرنامج

    فكرة البرنامج
    سنكتب برنامج يملك قائمة "Hook" تحتوي على:

    • "Mouse": عند الضغط على هذا العنصر يقوم البرنامج بتثبيت خطف لرسائل الفأرة ثم يخرج لنا صندوق حوار يحتوي على مقبض و صنف النافذة التي يشير إليها مؤشّر الفأرة.



    • "Keyboard": قائمة منسدلة تتكون من عنصرين، الأول وهو "Install" الذي يقوم بتثبيت خطف لمدخلات لوحة المفاتيح لكي تُعرض في صندوق نص يتواجد في مساحة عمل النافذة. و الثاني "UnInstall" و هو الذي يتخلّص من خطف مدخلات لوحة المفاتيح. هذا العنصر يكون مرمّد -غير نشط- عندما لا يكون هناك خطف لرسائل لوحة المفاتيح.



    دوال و رسائل مستعملة
    عندما يستقبل إجراء الخطف رسائل تحدثها الفأرة، يشير المعامل lParam إلى البنية MOUSEHOOKSTRUCT و التي تملك عضو يشير إلى إحداثيات مؤشر الفأرة. من هذه الإحداثيات يمكننا الوصول إلى مقبض النافذة المٌشار إليها بالفأرة من خلال تمريرها إلى الدالة WindowFromPoint:

    كود:
    WindowFromPoint PROTO X:DWORD,Y:DWORD
    كنا نستطيع إستعمال المقبض الموجود في العضو hwnd من البنية MOUSEHOOKSTRUCT لكن في حالة كان المستعمل يحرّك الفأرة و في نفس الوقت يضغط أحد أزرارها –مثل عملية الـDrag & Drop- تكون قيمة هذا العضو خاطئة و لهذا السبب تكون الطريقة السابقة هي الأفضل.

    بعد الحصول على مقبض النافذة يمكننا معرفة صنفها باستعمال الدالة GetClassName:

    كود:
    GetClassName PROTO hWnd;DWORD, pClassName:DWORD, nMaxCount:DWORD




    • hWnd: مقبض النافذة
    • pClassName: مؤشر إلى مخزن نستقبل فيه إسم الصنف
    • nMaxCount: نحدد حجم المخزن الذي يشير إليه المعامل pClassName



    لكل مفتاح من لوحة المفاتيح كود إفتراضي خاص به يميزه عن غيره. إذا كان المفتاح المضغوط حرف أو رمز أو رقم، سيشير الكود الإفتراضي إلى كود أسكي المفتاح المضغوط. أما إذا كان مفتاح موسّع كمفاتيح الوظائف (مفاتيح الإتجاهات، طباعة الشاشة...)، سيحتوي الكود الإفتراضي على قيمة ليس لها مقابل في جدول كود الأسكي و بذلك لا يمكن طباعتها مباشرة. للحصول على إسم أي مفتاح، نستعمل الدالة GetKeyNameText:

    كود:
    GetKeyNameText PROTO lParam:DWORD, pKeyName:DWORD, nSize:DWORD


    • lParam: نمرر قيمة المعامل lParam الذي نحصل عليه في إجراء خطف رسائل لوحة المفاتيح
    • pKeyName: مؤشر إلى مخزن نستقبل فيه إسم المفتاح
    • nSize: حجم المخزن الذي يشير إليه المعامل السابق



    يختلف إرسال الرسائل من دالة لأخرى، فمثلا الدالة SendMessage ترسل الرسالة إلى نافذة و لا تعود إلا بعد ما ينتهي إجراء النافذة من معالجتها. في المقابل، تقوم الدالة PostMessage بطرح رسالة في صفّ رسائل الـThread الذي أنشأ النافذة و تعود مباشرة.

    نموذج هذه الدالة:

    كود:
    PostMessage PROTO hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

    شرح البرنامج

    يتكون مشروع البرنامج من ملفين:

    • HookLib.asm: مكتبة ربط ديناميكي تصدّر لنا الدالة InstalHook و التي تقوم بتثبيت خطف سواء كان للفأرة أو للوحة المفاتيح، و الدالة UninstalHook التي تقوم بحذف الخطف التي قامت به الدالة السابقة.



    • WindowsHook.asm: ملف البرنامج الرئيسي و الذي يحتوي على أكواد إنشاء النوافذ ومعالجة الرسائل التي ترسلها إجراءات الخطف.



    1- شرح الملف HookLib.asm

    نموذج الدالة InstalHook:

    كود:
    InstallHook PROTO nHookProc:DWORD,hWnd:DWORD

    يُستعمل المعامل nHookProcفي تحديد نوع الخطف الذي نريده. فإذا كان 1، تقوم الدالة بخطف رسائل الفأرة و ما عد ذلك يكون الخطف لمدخلات لوحة المفاتيح. أمّا المعامل hWnd نحدد فيه مقبض النافذة التي سنرسل معلومات ما تمّ خطفه إلى الإجراء الخاص بها.

    لحذف آخر إجراء تمّ تثبيته من قِبَل الدالة InstallHook، نستعمل الدالة UninstallHook:
    كود:
    UninstallHook PROTO
    إجراء خطف رسائل الفأرة:
    كود:
    MouseHook proc nCode:DWORD,wParam:DWORD,lParam:DWORD
       .IF nCode<0
           invoke CallNextHookEx,hHook,nCode,wParam,lParam
       .ELSEIF nCode==HC_ACTION ;
           mov   EAX,lParam    ; EAX=MOUSEHOOKSTRUCT يشير إلى البنية
           invoke WindowFromPoint,[EAX],[EAX+4]
           invoke PostMessage,hWin,WM_MOUSEMSG,EAX,NULL
           invoke CallNextHookEx,hHook,nCode,wParam,lParam
       .ENDIF
        xor   EAX, EAX
        ret
    MouseHook endp
    عندما يحتوي المعامل nCode على القيمة HC_ACTION، نضع مؤشر البنية MOUSEHOOKSTRUCT في المسجل EAX، أول عضو في هذه البنية هو البنية POINT و التي تحتوي على كلمتين مزدوجتين فيهما الإحداثيتين X و Y. قيمة الإحداثي X تكون موجودة في العنوان الذي يشير إليه المسجل EAX و الإحداثي Y موجود في العنوان الذي يشير إليه EAX زائد حجم كلمة مزدوجة و هو 4 بايتات. بعد الحصول على مقبض النافذة من الدالة WindowFromPoint، نستعمل الدالة PostMessage لإرساله مع الرسالة WM_MOUSEMSG (وهي رسالة مستعمل نقوم بتعريفها). و في الأخير نمرّر معلومات الخطف لباقي الإجراءات.

    إجراء خطف مدخلات لوحة المفاتيح:

    كود:
    KeyBoardHook proc nCode:DWORD,wParam:DWORD,lParam:DWORD
       .IF nCode<0
           invoke CallNextHookEx,hHook,nCode,wParam,lParam
       .ELSEIF nCode==HC_ACTION
           mov   EAX, lParam ; (1)
           AND   EAX, 80000000h ; (2)
           JZ    NextHook ; (3)
           invoke GetKeyboardState,addr KeyState
           invoke ToAscii,wParam,NULL,addr KeyState,addr PressedKey,NULL
           cmp   wParam,'A' ; (4)
           JL    EXTENDED
           cmp   wParam,'Z' ; (5)
           JG    EXTENDED
           invoke PostMessage,hWin,WM_CHARKEY,PressedKey,NULL ; (6)
           jmp   NextHook
    EXTENDED: ; (7)
           invoke PostMessage,hWin,WM_EXTKEY,lParam,NULL
    NextHook:
           invoke CallNextHookEx,hHook,nCode,wParam,lParam
        .ENDIF
        xor   EAX, EAX
        ret
    KeyBoardHook endp


    (1): نضع في المسجل EAX المعلومات الإظافية للمفتاح الذي تمّ الضغط عليه.
    (2): يمثّل البت رقم 32 من قيمة المسجل EAX حالة المفتاح. إذا كان 1 يعني أنه تمّ الضغط على المفتاح و إذا كان 0 يعني أنه تمّ رفع الضغط عليه. لفحص هذا البت نستعمل التعليمة AND على المسجل EAX و القيمة h80000000 (تحتوي على 1 في البت رقم 32 و 0 في باقي البتات).
    (3): إذا كانت قيمة EAX أصبحت 0 بعد التنفيذ التعليمة AND، هذا يعني أنه تمّ رفع الضغط على المفتاح. نفهم من هذا أنّ المفتاح قمنا بمعالجته عند الضغط عليه لذلك نقفز إلى العلامة NextHook لتفادي تكرار معالجته.
    (4)-(5): بعد ترجمة المفتاح إلى كود أسكي، نتثبّت من أنه حرف أبجدي و ذلك بفحص الكود أسكي الذي يجب أن يكون ضمن المجال ['A'..'Z']. إذا كان كذلك نكمل التنفيذ إلى (6)، و إن لم يكن فنعتبر أنّ المفتاح موسّع (حتى و لم يكن كذلك) و نقفز لتنفيذ (7)
    (6): نرسل الكود أسكي مع الرسالة WM_CHARKEY (وهي رسالة مستعمل نقوم بتعريفها) إلى إجراء النافذة ليقوم بإظهار الحرف في صندوق النص.
    (7): نرسل المعلومات الإظافية للمفتاح مع الرسالة WM_EXTKEY (رسالة نقوم بتعريفها) إلى إجراء النافذة ليقوم بجلب إسم المفتاح و إظهاره في صندوق النص.

    2- شرح الملف WindowsHook.asm

    كود:
    ...
    .data
    ...
    StartSymb DB "[",0
    EndSymb   DB "]",0
    .data?
    ...
    Char      DW ? ; (1)
    HandleBuf DB 9 dup(?) ; (2)
    ClassName DB 20 dup(?) ; (3)
    DownKeys  DB 255 dup(?) ; (4)
    KeyName   DB 20 dup(?) ; (5)
    (1): متغيّر نضع فيه كود أسكي الحرف الذي نستلمه من الرسالة WM_CHARKEY
    (2): مخزن نضع فيه المقبض الذي نحصل عليه من الرسالة WM_MOUSEMSG بعد تحويله إلى حروف قابلة للطباعة
    (3): مخزن نضع فيه صنف النافذة التي نحصل على مقبضها من رسالة الفأرة (WM_MOUSEMSG)
    (4): كل مفتاح نضغط عليه نقوم بتخزينه في هذا المخزن
    (5): نضع فيه إسم المفتاح الذي نحصل على معلوماته من الرسالة WM_EXTKEY

    كود معالجة الرسالة WM_CHARKEY:

    كود:
    .ELSEIF uMsg==WM_CHARKEY
            mov   EAX, wParam
            mov   BYTE PTR[Char], AL ; (1)   
            invoke lstrcat,addr DownKeys,addr Char ; (2)
            invoke SetWindowText,hEdit,addr DownKeys ; (3)
    عند إلتقاط الرسالة WM_CHARKEY، يحتوي المعامل wParam على كود أسكي المفتاح الذي تم خطفه. (1): نضع كود أسكي الحرف في البايت العلوي للمتغير Char لنكوّن نص ينتهي بـ0 نستطيع تمريره إلى الدالة lstrcat
    (2): نستعمل الدالة lstrcat لإظافة الحرف الذي تحصلنا عليه إلى باقي المفاتيح التي تمّ الضغط عليها
    (3): بعد إظافة الحرف الجديد، نستعمل الدالة SetWindowText لوضع محتوى المخزن DownKeys في صندوق النص

    كود معالجة الرسالة WM_EXTKEY:

    كود:
    .ELSEIF uMsg==WM_EXTKEY
       invoke GetKeyNameText,wParam,addr KeyName,SizeOf KeyName
       invoke lstrcat,addr DownKeys,addr StartSymb
       invoke lstrcat,addr DownKeys,addr KeyName
       invoke lstrcat,addr DownKeys,addr EndSymb
       invoke SetWindowText,hEdit,addr DownKeys
    يقوم هذا الكود بجلب إسم المفتاح المضغوط و إضافته إلى المخزن DownKeys بعد وضعه بين معقفّين ثم إظهاره في صندوق النص.


    حمل الملف المرفق


    أسمبلي 32بت: Windows Hook لنتعلم مع
    أسمبلي 32بت: Windows Hook لنتعلم مع
    أسمبلي 32بت: Windows Hook لنتعلم مع
    الملفات المرفقة

 

ضوابط المشاركة

  • لا تستطيع إضافة مواضيع جديدة
  • لا تستطيع الرد على المواضيع
  • لا تستطيع إرفاق ملفات
  • لا تستطيع تعديل مشاركاتك
  •