بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
نواصل بحمد الله تعالى هذه السلسلة من الدروس والتي نرجو من الله أن ينفع بها كاتبها و قارئها إنه سميع مجيب .
سبق و أن ذكرنا في درس سابق كيفية عرض جدول اتصالات TCP الفعّالة على جهازك عن طريق الدالة GetTcpTable و التي هي إحدى دوال IP Helper API و الموجوده في المكتبة iphlpapi.dll
في هذا الدرس سنتعرف على وظيفة تقدم معلومة إضافية عن الوظيفة السابقة ، نستطيع أن نستثمر تلك المعلومة لنتعرف على البرنامج الذي يتحكم في المنفذ ، لتبنى بعد ذلك قراراتك :
هل البرنامج موثوق أم مشبوه ؟
وما هي درجة الأمان لهذا البرنامج ؟
وهل في كل مرة يفتح نفس المنفذ أم أنه يتغير ؟
باختصار تستطيع أن تعمل برنامج مشابه لبرنامج Zone Alarm الشهير .
حسناً ،،،
الفكرة باختصار هي : أن الوظيفة AllocateAndGetTcpExTableFromStack تعرض جميع اتصالات TCP الفعالة مع أرقام العمليات (Process ID) سنربط بين أرقام العمليات في هذه الوظيفة مع أرقام العمليات الفعالة في نظام التشغيل و المستخرجة بواسطة الوظيفة Process32First و الوظيفة Process32Next وعندها سنتوصل للملف الذي يتحكم بالمنفذ .
في ثنايا هذا الدرس سنتعرف على الوظائف التالية :
1 - الوظيفة : AllocateAndGetTcpExTableFromStack
و يعلن عنها كالتالي :
Declare Function AllocateAndGetTcpExTableFromStack Lib "iphlpapi.dll" _ (pTcpTableEx As Any, _ ByVal bOrder As Long, _ ByVal heap As Long, _ ByVal zero As Long, _ ByVal flags As Long) As Long
هذه الوظيفة لها 5 وسائط (بارامترات) :
الأول : pTcpTableEx سيوضع فيه مؤشر الذاكرة الذي سيكون أول بايت للبيانات .
الثاني: bOrder سيحدد الفرز ، سنمرر له القيمة صفر .
الثالث : heap وهو مقبض كومة المعالجة الحالية ، نحصل على هذه القيمة بواسطة الوظيفة GetProcessHeap
الرابع : zero سنمرر له صفر .
الخامس:flags و سنمرر له الرقم 2 .
للأسف لم أجد أي وثائق في ميكروسوفت تتحدث عن هذه الدالة .
ستعود هذه الوظيفة بصفر حال النجاح و غير ذلك حال الفشل .
2 - الوظيفة : CreateToolhelp32Snapshot
ويعلن عنها كالتالي :
Declare Function CreateToolhelp32Snapshot Lib "kernel32" _ (ByVal lFlags As Long, _ ByVal lProcessID As Long) As Long
وهي لأخذ صورة من العمليات و المسارات الحالية في نظام التشغيل ، تعيد المقبض المفتوح في حال النجاح والذي سيستخدم في وظائف أخرى و -1 في حال الفشل .
لها وسيطين :
الأول :
نوع الصورة المراد إلتقاطها ، ويأخذ أحد قيم هذه الثوابت :
Const TH32CS_SNAPHEAPLIST = &H1 Const TH32CS_SNAPPROCESS = &H2 Const TH32CS_SNAPTHREAD = &H4 Const TH32CS_SNAPMODULE = &H8 Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32 CS_SNAPMODULE) Const TH32CS_INHERIT = &H80000000
الثاني :
يستخدم في حالة تمرير أحد الثابتين TH32CS_SNAPHEAPLIST أو TH32CS_SNAPMODULE للوسيط الأول ، و ما عدا ذلك يهمل.
3 - الوظيفة : CloseHandle
ويعلن عنها كالتالي :
Declare Sub CloseHandle Lib "kernel32" _ (ByVal hPass As Long)
تستخدم لإغلاق مقبض الكائن ، و سنستخدمها مع مقبض الكائن الذي فتحناه في الوظيفة السابقة .
كما يظهر من الوظيفة فهي لا تعود بقيمة .
للفائدة : يمكن أن تعود هذه الوظيفة بقيمة (صفر في حال الفشل و غير ذلك في حال النجاح) ولكن يجب أن تعلن عن هذه الوظيفة على النحو التالي :
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
لاحظ أننا استخدمنا Function بدل Sub .
على أية حال ،،
تأخذ هذه الوظيفة وسيط واحد عبارة عن مقبض الكائن المراد إغلاقه .
4 - الوظيفة : GetProcessHeap
ويعلن عنها كالتالي :
Declare Function GetProcessHeap Lib "kernel32" () As Long
تعيد مقبض كومة المعالجة في حال النجاح ، ليس لها وسائط كما هو مشاهد .
5 - الوظيفة : Process32First
و يعلن عنها كالتالي :
Declare Function Process32First Lib "kernel32" _ (ByVal hSnapShot As Long, _ uProcess As PROCESSENTRY32) As Long
تزودنا بأول عملية موجودة في الصورة المؤخوذة لعمليات النظام ، لها وسيطين :
الأول : hSnapShot وهو مقبض صورة العمليات في النظام و الذي حصلنا على بواسطة الوظيفة CreateToolhelp32Snapshot
الثاني : uProcess كائن من نوع PROCESSENTRY32 وهي كالتالي :
Private Type PROCESSENTRY32 dwSize As Long cntUsage As Long th32ProcessID As Long th32DefaultHeapID As Long th32ModuleID As Long cntThreads As Long th32ParentProcessID As Long pcPriClassBase As Long dwFlags As Long szExeFile As String * MAX_PATH End Type
ستقوم الوظيفة بتعبئة الوسيط الثاني بقيمة أول عملية في الصورة الملتقطة لعمليات النظام .
في هذا الوسيط يوجد العضو szExeFile والذي سيحمّل باسم الملف الخاص بالعملية .
6 - الوظيفة : Process32Next
وهي شقيقة الوظيفة السابقة ، و يعلن عنها كالتالي :
Declare Function Process32Next Lib "kernel32" _ (ByVal hSnapShot As Long, _ uProcess As PROCESSENTRY32) As Long
تزودنا بالعملية التالية في الصورة المأخوذة لعلميات النظام ، تأخذ نفس عدد الوسائط و أنوعها ، وتعبئ الوسيط الثاني بقيمة العملية التالية في النظام .
7 - الوظيفة : CopyMemory
ويعلن عنها كالتالي :
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, _ Source As Any, _ ByVal Length As Long)
و تقوم بنسخ طول محدد من الذاكرة من متغير لأخر أو من بداية مؤشر إلى مكان آخر حسب نوع تمرير الوسائط (بالقيمة أو بالمرجع). و تأخذ الوسائط التالية :
الأول : pDst وهو الهدف ، و هذا سيوضع فيه القيمة المراد نسخها .
الثاني: pSrc وهو المصدر ، وهذا الذي سوف ينسخ منه .
الثالث : ByteLen وهو طول السلسلة المراد نسخها و تقاس بالبايت.
هذه الوظيفة لا تعيد قيمة .
8 - الوظيفة : htons
ويعلن عنها كالتالي :
Declare Function htons Lib "ws2_32.dll" _ (ByVal dwLong As Long) As Long
وتقوم بتحويل الرقم الممر لها من رقم طويل Long بحجم 4 بايت إلى رقم قصير Integer بحجم 2 بايت ، و الفائدة هي أن تحول الرقم المعطي إلى رقم منفذ بين 0 و 65535
تأخذ هذه الوظيفة وسيط واحد من نوع Long و تعود برقم قصير Integer يمثل رقم المنفذ .
هذه الوظيفة سبق أن صنعنا وظيفة تحاكيها في الدرس السابق (تعلم : كيف تقرأ جدول اتصالات Tcp الفعالة) وكانت على النحو التالي :
Private Function GetTcpPortNumber(DWord As Long) As Long GetTcpPortNumber = DWord / 256 + (DWord Mod 256) * 256 End Function
عوماً ،،،
تستطيع استخدام إحدى الوظيفتين إما htons API أو الوظيفة GetTcpPortNumber وكلاهما سيعود بنفس النتيجة .
والآن على بركة الله نبدأ ...
إن أول وظيفة سنستخدمها في برنامجنا هي الوظيفة AllocateAndGetTcpExTableFromStack والتي سبق أن قلنا أنها تأخذ 5 وسائط ، إذن سنكتب التالي :
nRet = AllocateAndGetTcpExTableFromStack(pTable, 0, GetProcessHeap, 0, 2)
وكما يظهر في السطر السابق فإننا مررنا الوظيفة GetProcessHeap في الوسيط رقم 3 .
وقد تلاحظ أننا مررنا للوسيط الأول المتغير pTable و الذي هو من نوع Long و الذي سيوضع فيه رقم مؤشر الذاكرة الذي سيكون أو بايت في جدول الاتصالات الفعالة .
كذلك ناتج الوظيفة سيوضع في المتغير nRet و الذي هو من نوع Long .
إذن كان الواجب علينا أن نعلن عن متغيرين من نوع Long قبل أن نكتب السطر السابق ، وعلى هذا سيكون أول ما نكتبه في برنامجنا هو التالي :
Dim pTable As Long Dim nRet As Long nRet = AllocateAndGetTcpExTableFromStack(pTable,0, GetProcessHeap, 0, 2)
إن ناتج الوظيفة السابقة (وكما أشرت سابقاً) سيكون :
1 - مؤشر الذاكرة و سيوضع في المتغير pTable
2 - ناتج الوظيفة و سيوضع في المتغير nRet
ولكن لنقف قليلاً عند كلمة مؤشر !
ما هو المؤشر ؟
هذا ما سنتحدث عنه في المشاركة التالية بإذن الله تعالى
والسلام عليكم ورحمة الله وبركاته

