الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تعلم كتابة برامج تصحيح الأخطاء

بدأه JAAS في 13 أغسطس 2004 · 13 رد · 12,649 مشاهدة · في مواضيع الأخ JAAS في الأسمبلي وتحليل التطبيقات البرمجية
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

كيف الحال شباب

أعتقد إني فتحت عشرين موضوع مع بعض

ولكن صدقوني كلها تصب في مكان واحد

فهم عمل الكمبيوتر ( وإلى فما معنى مبرمج)

بصراحة : نحن كمبرمجين عرب تعتبر برامجنا ( نكتة عند العالم)

والسبب كثرة الأخطاء ... هل تعرف أي برنامج مبتدأ (ليس عربي بالتحديد)

جرب شغلة -إفتح كل النوافذ الي فية - شغل 20 برنامج في جهازك - نزلة - طلعة

شوف شو بيصير بيظهر مسج ( خطأ غير متوقع - باي ) هذا إذا عرض رسالة

والحل : كيف أصنع برنامج يحل الأخطاء ذاتيا ( ينهار نظام التشغيل ولا ينهار البرنامج ؟؟!)

الموضوع طويل جدا ( ولذلك نقسمة إلى عدة أقسام )

- كتابة كود داخل برنامج ( لتصحيح أي خطأ متوقع أو غير متوقع يتعرض لة البرنامج ومحاولة تصحيحة)

- والقسم الثاني : تصميم برامج الديبغر مثل ( olly - turbo DBG ) و البرامج التي تأتي مع المترجمات

وأكيد لو إفتهم الدرس الأول (سيصبح تصميم برامج التنقيح مجرد تطبيق )

نبدأ الشرح

كتابة برنامج تصحيح ذاتي ( داخل برنامج)

ماذا يمكن أن أستفيد من هذا الموضوع؟ سؤال يطرح نفسة

مثال: شغل مترجم الفجول سي وطبق

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

        char* pstr=NULL;
        strcpy(pstr,"fff");

MessageBox (NULL,"main",NULL,MB_OK);

	return 0;
}

هذا خطأ واضح وشاهد رسالة الخطأ الرهيبة

ولن ينفذ المسج بل سيطرد برنامجك من الذاكرة

سنقوم الآن بكتابة برنامج تصحيح ذاتي

لكي يتفاهم مع النظام ويحل المشكلة (ولاينطرد بسهولة)

لاحظ الكود

#include "stdafx.h"
void FnError(DWORD);
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	__try{
        char* pstr=NULL;
        strcpy(pstr,"fff");

	}
	__except (FnError(GetExceptionCode()))
	{

	}

MessageBox (NULL,"main",NULL,MB_OK);
	return 0;
}

void FnError(DWORD ErrCode)
{
MessageBox (NULL,"Error",NULL,MB_OK);
}

ما رأيك هل فتحنا فرصة للنقاش ومعرفة الخطأ

طريقة عمل البرنامج

يبدأ تنفيذ بلوك try

وأي خطأ يحدث يقوم البرنامج بتنفيذ محتوى except

وهي الدالة

FnError

هذة الدالة هي التي يجب أن تحل المشكلة

ملاحظة(في مثالنا الخطأ بسيط ويمكن أن يحلة نظام التشغيل )

ويستمر تنفيذ البرنامج

ملاحظة يمرر للدالة FnError معرف الخطأ

وهو العائد من الدالة GetExceptionCode

وفي قانون يقول لحل أي مشكلة نبدأ بمعرفة المشكلة

وسيكون الشرح كلة على الدالة FnError

أول شيء نعرفة ماهو الخطأ أو الإستثاء

نبدأ بسرد كل الأخطا التي في النظام

وهي :

void FnError(DWORD ErrCode)
{
switch (ErrCode)
{
case STATUS_WAIT_0:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_ABANDONED_WAIT_0:
MessageBox (NULL,"",NULL,MB_OK);
break;
case STATUS_USER_APC:
MessageBox (NULL,"",NULL,MB_OK);
break;  

case STATUS_TIMEOUT:
MessageBox (NULL,"",NULL,MB_OK);
break;  
   
case STATUS_PENDING:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_SEGMENT_NOTIFICATION:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_GUARD_PAGE_VIOLATION:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_DATATYPE_MISALIGNMENT:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_BREAKPOINT:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_SINGLE_STEP:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_ACCESS_VIOLATION:
MessageBox (NULL,"",NULL,MB_OK);
break;
   
case STATUS_IN_PAGE_ERROR:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_INVALID_HANDLE:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_NO_MEMORY:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_ILLEGAL_INSTRUCTION:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_NONCONTINUABLE_EXCEPTION:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_INVALID_DISPOSITION:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_ARRAY_BOUNDS_EXCEEDED:
MessageBox (NULL,"",NULL,MB_OK);
break;
   
case STATUS_FLOAT_DENORMAL_OPERAND:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_FLOAT_DIVIDE_BY_ZERO:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_FLOAT_INEXACT_RESULT:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_FLOAT_INVALID_OPERATION:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_FLOAT_OVERFLOW:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_FLOAT_STACK_CHECK:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_FLOAT_UNDERFLOW:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_INTEGER_DIVIDE_BY_ZERO:
MessageBox (NULL,"",NULL,MB_OK);
break;
   
case STATUS_INTEGER_OVERFLOW:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_PRIVILEGED_INSTRUCTION:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_STACK_OVERFLOW:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_CONTROL_C_EXIT:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_FLOAT_MULTIPLE_FAULTS:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_FLOAT_MULTIPLE_TRAPS:
MessageBox (NULL,"",NULL,MB_OK);
break;
  
case STATUS_ILLEGAL_VLM_REFERENCE:
MessageBox (NULL,"",NULL,MB_OK);
break;
}
}

هذة أعتقد أنها كل الأخطاء التي يمكن أن تحدث

في ملاحظة : كل الأخطاء التي تبدأ ب STATUS_ أو EXCEPTION

فإنها نفس الشيء

مثال :EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION

وفي شيء ثاني في دالة المقارنة تركت كل المسجات فاضية لكي تكتب فيها

ما تريد أن يظهر لتمييز الأخطاء - أنا عن نفسي أكتب إسم الخطأ نفسة

إكتب إسماء الأخطاء ونفذ البرنامج

تلاحظ أن الخطأ هو :STATUS_ACCESS_VIOLATION

وهو أكثر خطأ حدوث في البرامج

ومعناة ( موقع القرائة أو الكتابة في الذاكرة غير موجود أو لا يمكن الوصول إلية)

الدالة أو المايكرو لم يجد مكان للكتابة في الذاكرة ولذلك سيظهر خطأ مباشر

يكفي أن نعرف في هذا الدرس ماهو الخطأ

وبالطبع لا أقدر شرح كل خطأ وطرح أمثلة لها

لأن بعضها لم يعد يحدث في النظام وبعضها لة أكثر من طريقة وبعضها لا أعرفها

ولكني أعدك بأن تعرف أغلبها عند الإنتهاء من سلسلة الدروس

والسبب : لأن كل خطأ يجب أن يقال في وقتة

نكمل الشرح :

بعد أن نحدد ماهو الخطأ يجب أن نصححة

ولتصحيحة يجب أن نعرف موقعة في الذاكرة

ونعرف كل قيم مسجلات المعالج

بريحك ( كل هذة المعلومات) تشملهم دالة واحدة

وهي : GetExceptionInformation

ولا تطلب منك إدخال أي بارمتر ولكنها تعيد الكثير

تعيد مؤشرين لسجلين مهمين وهما

PEXCEPTION_RECORD

PCONTEXT

المؤشر الأول عبارة عن مؤشر لمسجل الإستثنائات

ماهو جدول الإستثنائات : PEXCEPTION_RECORD

بإختصار يهمنا أو يكفي أن نعرف من هذا السجل

متغيرين فقط هما ( رقم الخطأ - عنوان الخطأ في البرنامج)

وهما : ExceptionCode - ExceptionAddress

أولا رقم الخطأ أوشفرة الخطأ هو نفسة الذي تحدثنا عنة

والتي تعيدة الدالة GetExceptionCode

أما العنوان فهو الذي يهمنا (وهو عنوان الخطأ)

المؤشر الثاني : PCONTEXT

وهو جدول لمسجلات المعالج -eax,ebx,esp,....

ومسجلات المقاطع - DS,CS,ES....

ومسجلات الحالة (بإختصار وكأن برنامجك داخل منقح برامج)

وأكيد بعد ما نعرف كل شيء عن البرنامج وقت الخطأ

يسهل التصحيح .

ولآن بعد أن عرفنا معنى الأخطأ خلنا نكتب الكود الصحيح

بهذا الشكل يكتب كود تصحيح الأخطا

#include "stdafx.h"
void FnError(LPEXCEPTION_POINTERS);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	__try{
        char* pstr=NULL;
        strcpy(pstr,"fff");

	}
	__except (FnError(GetExceptionInformation ()))
	{

	}
MessageBox (NULL,"main",NULL,MB_OK);
	return 0;
}


void FnError(LPEXCEPTION_POINTERS ErrRec)
{
char reg[MAX_PATH];

LPCONTEXT pcontext=ErrRec->ContextRecord;
LPEXCEPTION_RECORD exrec=ErrRec->ExceptionRecord;
////إظهار مسجلات المعالج
wsprintf(reg,"EAX=%X - EBX=%X - ECX=%X - EDX=%X",pcontext->Eax,pcontext->Ebx,pcontext->Ecx,pcontext->Edx);
MessageBox (NULL,reg,NULL,MB_OK);

switch (exrec->ExceptionCode)
{
case STATUS_WAIT_0:
MessageBox (NULL,"",NULL,MB_OK);
break;

case STATUS_ABANDONED_WAIT_0:
MessageBox (NULL,"",NULL,MB_OK);
break;
case STATUS_USER_APC:
MessageBox (NULL,"",NULL,MB_OK);
break;  
...
...
..كل الإحتمالات
...
...
}}

أعتقد لوفهمت هذا الدرس

يكفي اليوم..

في ملاحظة

مسجل PCONTEXT

لايحتوي مسجلات المعالج للبرنامج فقط

وإنما يحتوي مسجلات الهاردوير(نقط توقف للأجهزة)

كما يحتوي على مسجلات الديبغر للنظام

كما يحتوي على مسجلات لمعالجات أخرى

وسيتم شرح كل شيء في وقتة

أهم شيء

مافي برامج عربية بأخطاء

هذا والله أعلم

وبالتوفيق

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#2

السلام عليكم ,,

ماشاء الله عشنا وشفنا ,,

بالمناسبة مالفرق بين ال except__ وال catch__ ؟

يبدو أن لهما نفس العمل ,,

اقتباس
مسجل PCONTEXT

لايحتوي مسجلات المعالج للبرنامج فقط

وإنما يحتوي مسجلات الهاردوير(نقط توقف للأجهزة)

كما يحتوي على مسجلات الديبغر للنظام

كما يحتوي على مسجلات لمعالجات أخرى

كلام وزنو ذهب ,,شكرا جزيلا ,, لك على هذه الكنز :)

استمر على هذا المنوال ,, وبالمناسبة يمكن أن نفتح موضوع نقاش آخر لو أمكن لمناقشة تقنيات كتابة برامج Debugging حتى ,,

وأنا آسف فلم أستطع أن أوفي بوعدي في أكثر من مرة لأن أضيف معك ,, بس يعلم الله مافي ,,

أمر آخر لو تم طرح هذا الموضوع في قسم السي ,, أعتقد أن كان سيكون أكثر فائدة ,, مع التكنيك واحد ,, لكن اللغة الأم تقريبا في مثل هذه الأمور هي السي,,

بالتوفيق وفي انتظار الدرس القادم ,,

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#3

مرحبا HGB

فكرت أن أفتح هذا الدرس في منتدى السي

ولكن باقي الدروس قد لا تهم مبرمج السي .

أما عن تصميم برامج التنقيح

هذا الموضوع مقدمة

وإذا أردت الدخول مباشرة سأضع كود قد كتبتة لبرنامج تنقيح

ولكن أتوقع أنة لن يفتهم بدون مقدمات

وفي كل الحالات سيكتب الكود آخر الدرس

---

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#4

الله يخليك ,, خلاص انت الاستاذ والمنهج منهجك وفي انتظار الدروس ,, وكل ماستطعت صدقني سأكتب في الموضوع ,,

أمر آخر هل تستخدم كتاب جون روبنز Application Debugging for Windows ,, كمرجع لبرامج ال Debugging ,, وهل يوجد غيره تراه مناسبا ؟

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#5
اقتباس
أمر آخر هل تستخدم كتاب جون روبنز Application Debugging for Windows ,, كمرجع لبرامج ال Debugging ,, وهل يوجد غيره تراه مناسبا ؟

مشكلتي أني لا أحفظ أسامي المؤلفين

ولكن أعتقد أني قرأت كتاب واحد فقط في هذا المجال ( مترجم للعربي )

أتذكر أنة من إصدارات مايكروسفت والله أعلم

أما عن المرجع MSDN قد يفيدك في هذا الموضوع

وأهم مرجع ( تنقيح برامج التنقيح ؟؟!! )

أتوقع أنة أفضل حل لمعرفة طريقة عمل أي برنامج

وبالتوفيق

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#6

السلام عليكم ورحمة الله

---------------------

تكملة الموضوع

---------------------

كتابة برامج التنقيح لها عدة مراحل.

المرحلة الأولى : إدخال برنامج إلى حلقة تصحيح

توجد طريقتين لإدخال البرنامج

إذا كان في الذاكرة (بمعنى أن البرنامج يعمل ) نستخدم الدالة DebugActiveProcess

وتمرر لها رقم العملية فقط. وهذة الطريقة متقدمة تتطلب القيام بأعمال

متقدمة مثل (فحص أقسام البرنامج - تغيير في خصائص الأقسام-للقرائة فقط أو للكتابة)

وسنناقشها بعد فهم عملية التنقيح (الإعتيادية)

أما الطريقة الشائعة وهي إختيار برنامج من القرص ليتم تشغيلة

وإدخالة في دورة للتصحيح تتم كالتالي

الحصول على مسار البرنامج المراد تنقيحة وهناك عدة طرق مثل

أضف كود للقيام بإظهار نافذة لإستعراض البرامج(وعندما تقوم بإسترجاع مسار الملف)

نبدأ في إنشاء عملية في الذاكرة وتشغيل البرنامج (كما هو موضح في الكود

static STARTUPINFO           StartupInfo; 
static LPSTARTUPINFO         lpStartupInfo = &StartupInfo; 
static PROCESS_INFORMATION   ProcessInfo; 
static LPPROCESS_INFORMATION lpProcessInfo = &ProcessInfo; 
lpStartupInfo->cb          = sizeof( STARTUPINFO ); 
lpStartupInfo->lpDesktop   = NULL; 
lpStartupInfo->lpTitle     = NULL; 
lpStartupInfo->dwX         = 0; 
lpStartupInfo->dwY         = 0; 
lpStartupInfo->dwXSize     = 0; 
lpStartupInfo->dwYSize     = 0; 
lpStartupInfo->dwFlags     = STARTF_USESHOWWINDOW|STARTF_FORCEOFFFEEDBACK; 
lpStartupInfo->wShowWindow = SW_SHOWDEFAULT; 
lpStartupInfo->hStdError =GetStdHandle( STD_ERROR_HANDLE);
lpStartupInfo->hStdOutput =GetStdHandle( STD_OUTPUT_HANDLE);
lpStartupInfo->hStdInput  =GetStdHandle( STD_INPUT_HANDLE);
lpProcessInfo->hProcess = NULL; 

CreateProcess(NULL,filephat,NULL,NULL,FALSE,DEBUG_ONLY_THIS_PROCESS|
                       CREATE_NEW_PROCESS_GROUP|CREATE_DEFAULT_ERROR_MODE|
                      NORMAL_PRIORITY_CLASS,NULL,FileDir ,lpStartupInfo ,lpProcessInfo );

ملاحظات : filephat = مسار البرنامج كامل -FileDir= مسار مجلد البرنامج

لاحظ هذة الدالة : CreateProcess

هذة الدالة تستخدم في إنشاء عملية في الذاكرة ولا كن في مثالنا

مررنا لها ثابت يدل على أننا نريد إستخدام العملية للتنقيح

لاحظ الثابت : DEBUG_ONLY_THIS_PROCESS

هذا الثابت يخبر نظام التشغيل أن يقوم بإدخال هذة العملية تلقائيا

إلى دورة تصحيح للبرنامج مع تمكين البرنامج الحالي من التحكم الكامل في الملف المستهدف

بعد أن قمنا بإدخال البرنامج يجب أن نبني دورة للتحكم في سير البرنامج

بهذة الطريقة

CONTEXT con;
DEBUG_EVENT debug;

for(;;){

if(!WaitForDebugEvent (&debug,INFINITE))
break;

switch(debug.dwDebugEventCode )
{
case CREATE_THREAD_DEBUG_EVENT:
// قام البرنامج بإنشاء ثريد جديد
break;

case CREATE_PROCESS_DEBUG_EVENT:
// قام البرنامج بإنشاء عملية جديدة
break;

case EXCEPTION_DEBUG_EVENT: 
// حدوث إستثاء
break; 

case LOAD_DLL_DEBUG_EVENT:
// يقوم البرنامج بتحميل مكتبة ربط للذاكرة
break;

case EXIT_PROCESS_DEBUG_EVENT:
// خروج البرنامج وإنهاء العملية
break;

case EXIT_THREAD_DEBUG_EVENT:
// إنهاء ثريد في البرنامج
break;

case UNLOAD_DLL_DEBUG_EVENT:
// إنهاء مكتبة ربط وحذفها من الذاكرة
break;

}

//دالة إستمرار  تنقيح البرنامج
ContinueDebugEvent (debug.dwProcessId ,debug.dwThreadId ,DBG_CONTINUE );


}

البنية :CONTEXT قد تم شرحها في الدرس السابق.

أما الجديد فهو : DEBUG_EVENT

وهي البنية التي تمثل أحداث التصحيح بدرجة تفصيلية

وتتكون من : dwProcessId معرف العملية (البرنامج تحت التنقيح)

dwThreadId = معرف الثريد الحالي

dwDebugEventCode = الحدث أو التغيير

بالإضافة إلى بنية مهمة وهي u

هذة البنية تحتوي على معلومات الأحداث

مثال نفرض أن الحدث إنشاء عملية نفذ وهو CREATE_PROCESS_DEBUG_EVENT

في هذة الحالة يجب أن نعرف معلومات عن هذة العملية مثل: عنوانها في الذاكرة - رقم العملية .....وأشياء كثيرة

هذة المعلومات كلها في بنية u في قسم إنشاء العملية كمايلي

debug.u.CreateProcessInfo

وهكذا مع كل الأحدث ( ستوضح الطريقة عند فهم الأحداث)

شرح الكود:

بدأت الحلقة بدورة غير منتهية بشرط

وداخل الدروة تنفذ الدالة : WaitForDebugEvent

وهي تقوم بالإنتضار إلى أن يقوم البرنامج المستهدف بعمل أي حدث ليتم

تنفيذ المقارنة كما هو موضح في الكود

أما المتغير : INFINITE

معناة لا تقم بتنفيذ مقارنة الأحداث إلى إذا تم فعل حدث

وتستطيع أن تجعل هذا المتغير 1 او 2 أو أي رقم (على حسب طلبك)

ليتم المقارنة بعد الزمن الذي حددتة (وهذة الطريقة متقدمة)

وحددنا إنتها الدورة بفشل الدالة

بعد ذلك تبدأ مقارنة الأحداث (بهذة الطريقة)

الحدث الأول : CREATE_THREAD_DEBUG_EVENT

معناة قام البرنامج بإنشاء ثريد(خيط) جديد

ويلزمك في هذة الحالة بناء جدول ليتم تخزين عنوان كل ثريد بة

ونقل تحكم الدالة للثريد الذي تم إنشاءة للأنة يعتبر الثريد الحالي

مع ملاحظة أن النظام لا يقوم بنقل التحكم بشكل تلقائي

الحدث : CREATE_PROCESS_DEBUG_EVENT

هذا الحدث إنشاء عملية في الذاكرة وهو يحدث مرة واحدة

عند تشغيل البرنامج (ولكن قد يحدث أكثر من مرة (نادرا)في بعض البرامج مثل الماسنجر)

وطبعا هنا أيضا نقوم ببناء جدول للعمليات مع ملاحظة :كل عملية تنشأ معها على الأقل ثريد واحد

الحدث : EXCEPTION_DEBUG_EVENT

هنا يبدأ العمل ( راجع الإستثنائات- التي تم شرحها في الدرس الأول) عددها كثير

أكثر الإستثئنائات حدوث هي نقطة التوقف : STATUS_BREAKPOINT

هنا تصنع نقطة التوقف ( لو أردت كتابة نقطة توقف ماذا تفعل)

مثال( طلب المستخدم من البرنامج كتابة نقطه توقف في العنوان 44556677

أول شيء يقوم بة البرنامج قرائة أول بايت عند العنوان المحدد وتخزينة مؤقتا

يكتب عند العنوان المحدد بايت واحد وهو 0xCC هذا البايت معناة int3

تتم الكتابة بالدالة : WriteProcessMemory

وهو نقطة توقف وبعد ذلك شغل البرنامج

وسيتم تنفيذ الكود أول ما يجد النظام بايت cc يقوم بإصدار حدث إستثناء ونوعة نقطة توقف

يقوم البرنامج بقرائة العنوان ومسح نقطة التوقف cc ويستبدلها بالبايت الأصلي (الذي تم تخزينة)

وينفذ دالة إستمرار التنفيذ.

ملاحظة عنوان نقطة التوقف تجدها في (debug.u .Exception .ExceptionRecord .ExceptionAddress)

البنية u لا تنساها متى ما إحتجت معلومات عن الحدث تجدها في هذة البنية تحت إسم الحدث

ولكن هذة الطريقة تمسح نقطة التوقف نهائيا بمعنى لن يعرف البرنامج إذا نفذت

مستقبلا ولذلك علينا تنفيذ خطوة واحدة والرجوع لكتابة نقطة التوقف من جديد

وهذا ما يعرف في المعالجات بالخطوة step والراية هي TF

ذكرنا في الدرس السابق بنية CONTEXT ولاحظ أننا عرفناها في الكود ب con

وذكرنا أن هذة البنية تتحكم بالمعالج والهارد وير وسجلات المعالج

هذة الكتلة يكتب ويقرأ منها بدوال من ضمن هذة الدوال

GetThreadContext

SetThreadContext

لجعل المعالج ينفذ خطوة واحدة (لإعادة كتابة نقطة التوقف) نغير

في أعلام المعالج بهذة الطريقة

con.EFlags |=0x0100;
SetThreadContext(hthread,&con);

والمئة بالرقم الست عشري قيمتها بالثنائي هو 100000000

تلاحظ أن 1 في الخانة رقم 9 وهي خانة علم أو راية TF

عند تنفيذ هذة الشفرة سيقوم المعالج بالإنتقال من بايت نقطة التوقف وسيصدر النظام

إستثاء جديد وهو أن المعالج قام بتغيير علم الخطوة وهذا الإستثناء هو :STATUS_SINGLE_STEP

وتقوم بكتابة كود تحت هذا الإستثناء هذا الكود عبارة عن إرجاع نقطة التوقف التي مسحناها

وبعد ذلك يقوم المعالج بالعودة لهذة النقطة مع عدم تنفيذها. ودون تغيير سجلات المعالج

(في الأصل يقوم بتغيرها ولكن ترجع :: لانريد أن نفتح ثلاثين موضوع مع بعض)

أما باقي الإستثنائات فهي أخطاء (ولكن لن يتم إستمرار تنفيذ البرنامج إذا وجد خطأ)

وهنا نستخدم طريقة التجاهل مع إستمرار التنفيذ وهي

ContinueDebugEvent (debug.dwProcessId ,debug.dwThreadId ,DBG_EXCEPTION_NOT_HANDLED );

لاحظ الفرق بين دالة الإستمرار في المثال وهذة الدالة

الحدث : LOAD_DLL_DEBUG_EVENT

هذا الحدث معناة قام البرنامج بتحميل مكتبة ربط إلى الذاكرة

وتجد معلومات المكتبة في البنية u .LoadDll

ولكن هذة البنية لا تعطيك إسم المكتبة ( تعطيك شيء مهم وهو عناونها في الذاكرة)

وبعنوانها تستطيع معرفة إسمها والدوال المستوردة للملف والمصدرة وكل المعلومات

عن طريق قوانين يجب معرفتها.( وأنا لم أنسى طرح هذة القوانين)

إذا كنت من المتابعين للدروس راجع موضوع (تعلم كيف تعمل مترجمات لغات البرمجة)

فالموضوع مرتبط بهذا الدرس

الحدث : EXIT_PROCESS_DEBUG_EVENT:

تمت إنهاء العلمية

وتستخدم هنا دالة إنها العملية وهي : ExitProcess والبارمتر لها تجدة في البنية u

ويجب هنا أن تضع كود مقارنة للجدول الذي أنشأناه للعمليات وعندما تجد رقم العملية تحذفها من الجدول

وإذا وجدت أنها العملية الرئيسية أي لا يوجد في الجدول إلى عملية وحدة وتم إنهائها تقوم بإقاف التنقيح

وينتهي البرنامج

الحدث : EXIT_THREAD_DEBUG_EVENT

تم إنها ثريد وهي نفس الحدث السابق (تقوم بمقارنة رقم الثريد المحذوف)

في الجدول الذي أنشأناه الخاص بالثريد

وتحذفة من الجدول.

الحدث : UNLOAD_DLL_DEBUG_EVENT

تم إنهاء مكتبة ربط ( لمعرفة معلومات المكتبة - وهي نفس الحدث تحميل المكتبة)

----

وفي نهاية دورة التنقيح يتم وضع دالة الإستمرار للبرنامج وهي

ContinueDebugEvent

هذا بإختصار مبدأ عمل برامج التنقيح

وتشمل الدوال التالية ( التي ذكرناها)

WaitForDebugEvent

DebugActiveProcess

ContinueDebugEvent

WriteProcessMemory

ReadProcessMemory

GetThreadContext

SetThreadContext

وبقي دوال أخرى مثل

FlushInstructionCache

وهذة الدالة تقوم بعمل تحديث للذاكرة المعالج

فمثلا عندما نكتب بايت ونعيد تغيرة قد لا يتغير في ذاكرة

المعالج نستخدم هذة الدالة للتحديث الذاكرة

وطبعا هذة الدالة تستخدم في الأجهزة متعددة المعالجات

وتستخدم دوال أخرى في عمليات متقدمة مثل

GetThreadSelectorEntry

وتوجد طرق أخرى للتنقيح مثل تنقيح الأجهزة (الهارد وير)

وتشملهم مسجلات بنية CONTEXT مثل Dr7,Dr3 ...

--------------

إذا كنت لا تريد التعمق في هذا الموضوع فقرائتة

وفهمة يفتح لك سر من أسرار البرمجة ألى وهو

(دوال التزامن والإنتظار )

هذة الدوال مهمممة جدا في عالم البرمجة فمثلا منها

WaitForMultipleObjects

هذا الدالة تمكنك من مراقبة أكثر من حدث أو عملية

في نفس الوقت والحدث يعني أي شيء مثل (إنشاء ملف -حذف ملف - تشغيل برنامج)

إلى درجة أنك يمكن أن تعرف أول ما يتم عملية تغيير في مفتاح في سجل النظام

ولو حرف واحد أو حتى تغير إسم المفتاح( وتشمل كل أحداث النظام تقريبا )

WaitCommEvent

هذا الدالة تمكنك من مراقبة كل بايت يدخل أو يخرج من منفذ تسلسلي

وترجع لك أحداث الإرسال والإستقبال والخطأ و..و كل شيء عن المودم

WaitForInputIdle

هذة الدالة (أسرع دالة في البرمجة ) تمكنك من معرفة العملية

الي عليها الدور في الذاكرة وتعرفك على التبديل بين المهام و..و.

WaitNamedPipe

دالة خوادم الإتصالات المؤقتة

WaitForSingleObjectEx

مراقبة حدث أو عملية واحدة

وتوجد دوال كثيرة و أفكار أكثر في عالم البرمجة

ولايمكن أن تكشفها إلى بفهم ( كيف يعمل البرنامج)

لهذا السبب أحاول أن أتعمق في هذة الدروس قدر المستطاع

لأني لا أريد أن أعطيك السمكة جاهزة ولا كن أريد أن أعلمك كيف تصطاد

ولا أقصد من هذة الدروس تشويش الأفكار وتعقيد الموضوع ( لأنة في الأصل معقد )

فقد بذلت كل جهد لتبسيطة ولا كن يجب أن يكون عند المتابع للدروس خلفية وفهم

لمعنى البرمجة وليس معرفة كتابة الكود .

وإن شاء الله سأقوم بمراجعة الحسابات ودون تجاهل الأخوة المبتدئين

ونبدأ من جديد في سلسلة دروس من الصفر لنفهم كيف تعمل البرامج قبل أن نتعلم كيف نكتبها

--

وإلى اللقاء

هذا والله أعلم

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#7

---| إقتباس |---

كلام وزنو ذهب ,,شكرا جزيلا ,, لك على هذه الكنز

-----------------

زادك الله علما

#8

والله يا احمد jaas كنز بذاته للمنتدى واكثر ان شاء الله، رائع يا jaas.

يعني جملتك ترن في اذني

اقتباس
تعتبر برامجنا ( نكتة عند العالم)

39_22.gif

تزود من التقوى فإنك لا تدري *** إذا جن ليل هل تعيش إلى الفجر

فكم من فتى أمسى وأصبح ضاحكاً *** وقد نسجت أكفانه وهو لا يدري

لقراءة القرآن الكريم و سماعه و تفسيره ........

ماذا يعني انني مسلم سني؟

قصة غريبة

ConflictResolution.gif

#9

جزاك الله خيرا أخى jaas

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

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

فما الاحتمال القائم لهذه المشكلة؟

#10

شكراً لمشاركات الأعضاء ( والمشرفين:) )

أخي anwarica

أول مرة أسمع عن هذا الحل من قبل برنامج ( وبصراحة لا أعتقد أن يقوم بة برنامج)

ولو توضح المسألة ( أو تضع رابطة للبرنامج )

سأحاول أن أتأكد ( إذا كان الموضوع يهمك )

وبالتوفيق

http://www.jaascois.com

*************************************************

مجموعة مواضيع - إحتراف البرمجة -

ّ~~~~~~~~~~~~~~~~~~~~~~

البرمجة المتقدمة & الهندسة العكسية & برمجة وأمن الأنظمة

/index.php?showtopic=45002

آخر المواضيع :

+- تحليل جرائم الكمبيوتر -+

أنظمة اليونكس(Solaris,HP, AIX,SCO)وانواع المعالجات

ثغرة SMS لأجهزة الجوال Siemens 3568i !

أخطاء وثغرات البرامج العربية !!!

سلسلة مواضيع - أمن وحماية مواقع الويب -

E البرمجة المتقدمة X للملفات التنفيذية E

سلسلة مواضيع ثغرات الأنظمة وإختراق الأجهزة

**************************************************

<span style='font-size:14pt;line-height:100%'>الإرادة تحـــقق السيـــادة</span>

**************************************************

#11

أخى jaas

البرنامج اسمه قاموس زاد التعليمى ZAD واسف لكتابة اسم الشركة على الأقل لحماية الأفراد من استخدامه .. ليس عندى وصله والمشكلة أننى مسحته منذ عمل هذه الحركة (أو بالأصح مسحت الملف الوحيد المتبقى منه) ولكن اعتقد ان مساحته تفوق 100 ميجا..

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

قد يكون هناك أخطاء فى الكود تسبب مثل هذه الحالة الغريبة أو تضارب حتى .. لا أدرى صراحة :(

وجزاك الله خيرا

#12

السلام عليكم

عند تطبيق الأمثلة التي في الأول على Visual C++ يظهر لي الكومبيلر التالي

C:\Program Files\Microsoft Visual Studio\MyProjects\cpp2\cpp2.cpp(1) : fatal error C1083: Cannot open include file: 'stdafx.h': No such file or directory

فكيف أجد المكتبة stdafx.h????

Web Developer using JSP & Servlet

اللهم انصر الإسلام والمسلمين وأهلك الكفرة أعداء الدين

#13

موضوع رائع شكر

Nothing to mention except that I am Muslim

Using your brain is not bad as you think

My Blog

logo.jpg

#14

شكرا اخي على الموضوع الشيق والمفيد

لتنزيل اخر البرامج المساعده للمبرمجين والبرامج بشكل عام

http://www.tahmeelnet.blogspot.com

مواضيع مشابهة