بسم الله الرحمن الرحيم,
تكلمنا في المقال السابق عن مثال بسيط في الهندسة العكسية, وكما ذكرنا سنكمل اليوم بأذن الله التطبيق على برنامج آخر و لكن هذه المرة سيكون برنامجا تجاريا وليس من برمجتنا.
في البداية لابد التنويه -كما تم التنويه في مقال سابق- أن هذا المقال وغيره من المقالات تهدف الى تعليم و نشر الهندسة العكسية, كما أن أي مثال لبرنامج تجاري يتم استخدامه فهو للاستخدام التعليمي فقط, ولا يعني بأي شكل من الأشكال التقليل أو الانتقاص من شركة أو مبرمجي البرنامج, وأي شخص يستخدم تلك المعلومات بشكل غير الذي يهدف اليه المقال فهو المسؤول كاملا عن ذلك.
البرنامج الذي سنطبق عليه اليوم هو برنامج يستخدمه كثير منا, برنامج ارشفة الملفات الشهير Winrar. كثيرا منا يجد حينما يقوم بفتح البرنامج هذه الشاشة التي تظهر بعد بضع ثوان من فتحه, و هي التي تشير أن البرنامج يحتاج الى تفعيل ليتم حذف هذه الشاشة.
اليوم سيكون هدفنا حذف هذه الشاشة, لنتمكن بعد ذلك من فتح البرنامج بدون أن نراها في كل مرة نستخدم البرنامج فيها و لهذا سيكون المقال اليوم قصير مقارنة بسابقه.
طريقة تفكيري الأولية أني سأحاول أن أحاكي مبرمج البرنامج, اذا كنت أنا في مكانه و أردت أن أكتب برنامجا يتأكد اذا كان المستخدم قد دفع مقابل استخدامه هذا البرنامج, فماذا يمكن أن أفعل؟ منطقيا يمكن أن أقوم بهذا بعدة طرق, أذكر هنا بعضا منها, أولها أني سأجعل البرنامج يقوم بالاتصال بالشبكة العنكبوتية للتأكد أن هذا المستخدم فعلا قد دفع مقابل استخدامه البرنامج, و حينها سأكرر هذا الروتين في كل مرة يتم فيها فتح البرنامج. نستطيع أن نخمن أن تلك الطريقة ليست المستخدمة في برنامج Winrar, لأن البرنامج يمكن استخدامه بدون أن يكون الجهاز موصل بالشبكة, و هذا يجعلنا ننتقل للطريقة الأخرى و هي البحث عن ملف ما في الجهاز, و اذا وجدناه نتأكد من بعض القيم بداخله. كما يمكننا أيضا استخدام السجل Registery. اذا قمنا في البداية بتتبع البرنامج قبل أن يقوم برسم الواجهة GUI و البدأ في العمل, سنلاحظ الكثير من النداءات التي تتم على الدالات الآتية:
ReadFile, RegOpenKeyEx, RegQueryValueEx, RegSetValueEx
ReadFile, RegOpenKeyEx, RegQueryValueEx, RegSetValueEx
هذا فعلا يؤكد تخميننا و هو أن البرنامج يستخدم الملفات و السجلات ليعرف اذا كان المستخدم شخص مسجل و قام بالدفع فعليا مقابل استخدام البرنامج أم لا.
حتى الآن هذا ممتاز, لن نتطرق هنا لخوارزمية التأكد من التفعيل لأنها طويلة و نحن لسنا بحاجة اليها لأننا نستطيع التحايل على البرنامج بشكل ابسط بكثير. اذا كان البرنامج يقوم ببعض القراءات و الحسابات قبل أن يقوم بالفتح, فلابد أن هنالك تعليمة أو أكثر تقوم بالتأكد اذا كانت تلك الحسابات التي قام بها ايجابية (اذا فالمستخدم مسجل فعليا و لا يجب اظهار رسالة الدفع له) أم كانت سلبية (اذا فالمستخدم غير مسجل و يجب اظهار الرسالة له). هذه تشبه المتحكمات بالسياق في البرمجة Conditional Code Flow, و نحن نعلم أن المتكمات بالسياق يمكن أن تحدث بكثير من الأشكال, عندنا مثلا في لغة السي C:
goto statement, conditional if
حتى الآن هذا ممتاز, لن نتطرق هنا لخوارزمية التأكد من التفعيل لأنها طويلة و نحن لسنا بحاجة اليها لأننا نستطيع التحايل على البرنامج بشكل ابسط بكثير. اذا كان البرنامج يقوم ببعض القراءات و الحسابات قبل أن يقوم بالفتح, فلابد أن هنالك تعليمة أو أكثر تقوم بالتأكد اذا كانت تلك الحسابات التي قام بها ايجابية (اذا فالمستخدم مسجل فعليا و لا يجب اظهار رسالة الدفع له) أم كانت سلبية (اذا فالمستخدم غير مسجل و يجب اظهار الرسالة له). هذه تشبه المتحكمات بالسياق في البرمجة Conditional Code Flow, و نحن نعلم أن المتكمات بالسياق يمكن أن تحدث بكثير من الأشكال, عندنا مثلا في لغة السي C:
goto statement, conditional if
باختصار, هذين الأمرين يساعداننا بالتحكم في سياق البرنامج, فاذا حدث كذا افعل كذا أو اذهب الى كذا, واذا لم يحدث افعل كذا أو اذهب الى كذا. المتحكمات بالسياق في لغة المجمع Assembly تكون عبارة عن مجموعة من التعاليم تنتهي بتعليمة JXY conditional jump instruction, فمثلا لو عندنا هذا الكود البسيط بلغة السي C:
ستترجم للغة المجمع بهذا الشكل:
كما نرى في الصورة, عندنا الـ if conditional تحولت الى مجموعة من التعليمات في آخر كل مقارنة منها نجد تعليمة قفز لمنطقة كود أخرى Conditional Jump instruction.
فاذا نستنتج أننا يمكن أن نتخطى شاشة التنبيه للدفع في برنامج Winrar من خلال أن نجد الكود الذي يظهر شاشة التنبيه أو الدالة المسؤولة عن ذلك, و ستكون تعليمة القفز متواجدة قبله مباشرة أو بعدة أسطر.
و لكن كيف لنا أن نجد كود اظهار الشاشة؟ هذا أمر هين و يمكن للخبير القيام به بأكثر من طريقة, هنا مثلا سأستخدم طريقة بسيطة جدا, و هي انتظار حتى تظهر تلك الشاشة, و من ثم الذهاب و النظر للمكدس, لأننا نعلم أن برنامج Winrar تمت برمجة واجهته من خلال الواجهة البرمجية لويندوزWin32 API, كيف علمنا هذا؟ اترك هذا السؤال للقارئ و كمساعدة بسيطة, الدالة البرمجية الخاصة باظهار رسالة بشكل معين على الشاشة اسمها:
DialogBoxParamW
هل تستطيع التأكد أن برنامج Winrar يستخدم تلك الدالة؟
و لكن كيف لنا أن نجد كود اظهار الشاشة؟ هذا أمر هين و يمكن للخبير القيام به بأكثر من طريقة, هنا مثلا سأستخدم طريقة بسيطة جدا, و هي انتظار حتى تظهر تلك الشاشة, و من ثم الذهاب و النظر للمكدس, لأننا نعلم أن برنامج Winrar تمت برمجة واجهته من خلال الواجهة البرمجية لويندوزWin32 API, كيف علمنا هذا؟ اترك هذا السؤال للقارئ و كمساعدة بسيطة, الدالة البرمجية الخاصة باظهار رسالة بشكل معين على الشاشة اسمها:
DialogBoxParamW
هل تستطيع التأكد أن برنامج Winrar يستخدم تلك الدالة؟
بعد النظر للمكدس, سنرى كل الدالات التي تم النداء عليها, و حينما نتتبع النداءات للدالات, نستطيع أن نصل لكود البرنامج و سنرى أن قبل النداء على دالة اظهار شاشة التنبيه توجد تعليمة Jump, لنوضح أكثر و نحن نقوم بالشرح فعليا على البرنامج.
في البداية نحمل Winrar بداخل برنامج Immunity Debugger. ثم نقوم بالضغط على اداة تشغيل البرنامج في شريط الأدوات.
بعد ذلك ننتظر حتى يظهر برنامج Winrar و تظهر بعده شاشة التنبيه. حين نرى تلك الشاشة نضغط على أداة الايقاف في برنامج Immunity Debugger في شريط الأدوات.
الآن البرنامج واقف و حالة المعالج و المكدس و الذاكرة واقفة و لن تتغير الا حينما نرجع لتشغيل البرنامج مرة أخرى. الآن لنذهب و نضغط على أداة رؤية المكدس في شريط الأدوات التي يرمز لها بالحرف K.
بعد ذلك ننتظر حتى يظهر برنامج Winrar و تظهر بعده شاشة التنبيه. حين نرى تلك الشاشة نضغط على أداة الايقاف في برنامج Immunity Debugger في شريط الأدوات.
الآن البرنامج واقف و حالة المعالج و المكدس و الذاكرة واقفة و لن تتغير الا حينما نرجع لتشغيل البرنامج مرة أخرى. الآن لنذهب و نضغط على أداة رؤية المكدس في شريط الأدوات التي يرمز لها بالحرف K.
نستطيع أن نرى هنا فعلا أنه تم النداء على الدالة DialogBoxParamW و نستطيع أن نرى أيضا أنها تم النداء عليها من دالة في كود البرنامج نفسه, تلك الدالة من برمجة صاحب البرنامج فلهذا لم يستطع برنامج Immunity أن يجد لها أسما في دالات ويندوز Windows Modules, لأن الدالات تعرف بعناوينها في ملفات المكتبات Modules. نستطيع أن نرى عنوان تلك الدالة اسفل دالة DialgoBoxParamW في المكدس, على جهازي تلك الدالة موجودة في العنوان 0046D740 كما رأينا في الصورة السابقة.
الآن نضغط مرتين على هذا العنوان, ليقوم برنامج Immunity بأخذنا لبداية تلك الدالة, نحن لا نريد بداية الدالة, نحن نريد المكان الذي نودي منه الدالة DialogBoxParamW لننظر قبله بسطور آملين أن نجد تعليمة القفز. نستطيع أن نعرف هذا المكان مباشرة من خلال شاشة المكدس, سنرى بجانب الدالة DialogBoxParamW خانة تحوي المكان الذي نودت منه تلك الدالة, وهو على جهازي 0046DB37.
نذهب لهذا العنوان لنجد هذا الكود, وفعلا قبله بعدة أسطر نجد تعليمة القفز في العنوان 0046DB15.
كود اظهار شاشة الدفع موجود بعد تعليمة القفز, اذا المعالج حينما يصل لتعليمة القفزة لا ينفذها, لأننا نستطيع أن نرى أن القفزة تذهب لمكان آخر للكود غير جزء اظهار الشاشة, فبالتالي شرط القفزة لا يتحقق. اذا كل ما علينا فعله هو تغيير تلك القفزة من قفزة شرطية Conditional jump الى قفزة دائمة من خلال الضغط مرتين على تعليمة القفزة و تغيير التعليمة JE للتعليمة JMP.
بعد ذلك, نضغط الزر الأيمن للفأرة في أي مكان في كود المجمع, و نختار
Copy to executable > All Modifications
Copy to executable > All Modifications
بعد ذلك نرى رسالة صغيرة نختار منها Copy All.
بعد ذلك تظهر لنا شاشة بها كود مجمع باللون الأخضر, نضغط زر الفأرة الأيمن في أي مكان في تلك الشاشة, و نختار Save file.
بعد ذلك نختار مكان ما في الجهاز لحفظ الملف التنفيذي المعدل الجديد, ثم نغلق برنامج Immunity و نذهب للمكان الذي حفظنا فيه الملف الجديد, و نقوم بفتحه بشكل طبيعي من خلال الضغط عليه. اذا كان كل شئ على ما يرام لابد أن نجد برنامج Winrar يفتح لنا بدون شاشة التنبيه, و بذلك بفضل الله تعالى نكون قد نجحنا باخفاء شاشة التنبيه.
في هذا المقال بجزئيه, استطعنا أن نكسر حماية برنامجين من خلال معرفتنا بعلم نظم التشغيل, علم البرمجة, و الوثائق التقنية للدالات الخاصة بواجهة ويندوز البرمجية Win32 API. اعلم أن كلما كثرت خبرتك و معلوماتك في تلك العلوم, كلما كنت على دراية و فهم أعلى بالبرنامج المراد فك حمايته و فهمه و التعديل عليه .
Post A Comment:
0 comments so far,add yours