MSVS

تعلم : استعراض المنافذ و البرامج التي تتحكم فيها

15 ردود في هذا الموضوع

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

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

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

سبق و أن ذكرنا في درس سابق كيفية عرض جدول اتصالات 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

ولكن لنقف قليلاً عند كلمة مؤشر !

ما هو المؤشر ؟

هذا ما سنتحدث عنه في المشاركة التالية بإذن الله تعالى

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شرح مميز اخ MSVS وفعلا بدء اهتمامي بمثل هذه المواضيع ينصب الان بعد

رؤية مثل هذه الدروس الله يكثر من امثالك .... وسأحاول الاستفادة منها ان شالله

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

العفو يا أخي الكريم

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مشكوووووور اخي MSVS ..... فعلا تجميعة دروسك تعتبر دورة كاملة في برمجة الشبكات

جزاك الله خيرا وننتظر المزيد

تحياتي لك

أخوك ناصر

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

نكمل بحمد الله تعالى بعد أن توقفنا عند المؤشرات .

الصورة التالية تحاكي شكل الذاكرة :

Memory_Pointer.JPG

يظهر من الصورة في الأعلى أن الذاكرة مقسمة بشكل بايتات ، أي أن وحدة قياس الذاكرة هو البايت = 8 بت .

أيضاً يظهر من الصورة أن لكل بايت في الذاكرة رقم فريد يتعامل معه الجهاز ليخزن فيه أو يقرأ منه البيانات .

فلو افترضنا أننا أعلنا عن متغير من نوع Byte فإن الجهاز سيحجز لك مساحة بمقدار بايت واحد لتخزن فيه قيمة عددية بين 0 و الـ 255

وكما يظهر أيضاً في الصورة ، فإن المتغير الذي أعلنا عنه باسم bNum هو من نوع Byte وقد حجز له مساحة بمقدار بايت واحد ، ونحن بدورنا خزنا فيه العدد 45

لاحظ أن قيمة البايت لن تتجاوز الحد الأقصى الذي يمنحك إياه الجهاز إذا أعلنت عن متغير من نوع Byte أي 255

حسناً ، لو أمعنا النظر مرة أخرى في الصورة فسنجد عنوان البايت أي موقع البايت في الذاكرة وهذا الذي يسمى المؤشر .

وعلى هذا ،،

فالمتغير bNum مؤشره 1001

والمتغير intNum مؤشره 1004 و بما أنه طوله 2 بايت فسيأخذ البايت الذي يليه مباشرة ، أي سيكون المتغير في المؤشر 1004 و 1005

والمتغير Result مؤشره 1009 وبما أنه طوله 4 بايت فسيأخذ 3 بايتات تلي عنوان البايت 1009 ، أي سيكون المتغير من المؤشر 1009 إلى 1012

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

والآن ،،،

بعض وظائف API تتعامل مع المتغيرات بواسطة المؤشر ، أي عنوان المتغير في الذاكرة .

فإذا :

1 - حصلنا على مؤشر المتغير

2 - وعرفنا طوله

فسنستطيع قراءته بواسطة الدالة CopyMemory

تذكر جيداً ،،،، حصلنا على المؤشر و عرفنا طول المتغير

نعود لموضوعنا .

قلنا أن الوظيفة AllocateAndGetTcpExTableFromStack ستعود بمؤشر البيانات في الذاكرة وبهذا نكون حصلنا على نصف المطلوب و يتبقى أن نعرف طول المتغير (البيانات) لكي يمكننا الوصول إليها في الذاكرة مباشرة .

ولكي نعرف طول المتغير يجب أن نقف عند نقطة . ما هي تركيبة البيانات التي تكتبها الوظيفة في الذاكرة و تعطينا مؤشرها ؟

ربما تتذكر كيف كانت تركيبة البيانات في الدرس السابق (تعلم : قراءة جدول اتصالات TCP الفعالة) لقد كانت على النحو التالي :

Const MAX_ROW  As Integer = 500


Private Type MIB_TCPROW
   dwState As Long
   dwLocalAddr As Long
   dwLocalPort As Long
   dwRemoteAddr As Long
   dwRemotePort As Long
End Type

Private Type MIB_TCPTABLE
   dwNumEntries As Long                
   table(MAX_ROW) As MIB_TCPROW
End Type

في هذه الوظيفة لن تختلف التركيبة إلا بزيادة عضو (dwProcessId) مع إختلاف قليل بالمسميات ، و ستكون على النحو التالي :

Const MAX_ROW  As Integer = 500

Private Type PMIB_TCPEXROW
   dwStats         As Long
   dwLocalAddr     As Long
   dwLocalPort     As Long
   dwRemoteAddr    As Long
   dwRemotePort    As Long
   dwProcessId     As Long
End Type


Private Type PMIB_TCPEXTABLE
   dwNumEntries    As Long
   Table(MAX_ROW)  As PMIB_TCPEXROW
End Type

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

تلاحظ أن التركيبة PMIB_TCPEXTABLE مكونة من عضوين :

الأول : dwNumEntries من نوع Long أي 4 بايت وسيوضع فيه عدد السجلات .

الثاني: Table(MAX_ROW)0 مصفوفة من نوع PMIB_TCPEXROW وسيوضع فيها سجلات اتصالات Tcp الفعالة .

لتحديد طول التركيبة PMIB_TCPEXROW نقوم بالحسبة التالية :

تذكر أن Long يساوي 4 بايت

6 أعضاء من نوع Long تساوي 6 * 4 = 24 بايت

عرفنا الآن طول التركيبة PMIB_TCPEXROW وهو 24 بايت

إذن ستكون أول 4 بايت للعضو dwNumEntries و الـ 24 بايت التي تليها للعضو Table

وعلى هذا ،

فلو كان عندنا اتصالينTCP سيكون حجم المتغير من تركيبة PMIB_TCPEXTABLE كالتالي :

أول 4 بايت للعضو dwNumEntries

ثم

عدد السجلات * طول الجدول

2 * 24 = 48

إذن سيكون إجمالي المتغير من نوع PMIB_TCPEXTABLE هو 4 + 48 = 52 بايت

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

وعلى ما سبق .

فلو رجعت علينا الوظيفة AllocateAndGetTcpExTableFromStack بالمؤشر 50000 فسنعلم أن البيانات على النحو التالي :

من البايت 1 إلى البايت 4 = dwNumEntries

من البايت 4 إلى البايت 4+24= 28 = (0)Table

من البايت 28 إلى البايت (28+24=52) = (1)Table

و بالمؤشرات ستكون النتيجة كالتالي :

من البايت 50000 إلى البايت 50003 = dwNumEntries

من البايت 50004 إلى البايت 50004+24= 50028 = (0)Table

من البايت 50028 إلى البايت 50028+24= 50052 = (1)Table

سأصاب بالاحباط إن لم تصل إليك فكرة المؤشرات حتى الآن :angry:

والآن بما أننا حصلنا على :

رقم المؤشر

و

طول جدول اتصالات PMIB_TCPEXTABLE

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

وبما أننا قلنا أن أول 4 بايت في الذاكرة سيوضع فيها عدد الاتصالات الفعّالة

إذن سنقرأ أول 4 بايت من الؤشر الذي تعود به الوظيفة AllocateAndGetTcpExTableFromStack .

و على مثالنا السابق المؤشر هو 50000

إذن من البايت 50000 إلى البايت 50003 سيكون متغير من نوع Long يحمل قيمة تمثل عدد الاتصالات الفعالة .

لقراءة أول 4 بايت نكتب الكود التالي :

    Dim nRows As Long
   CopyMemory nRows, ByVal pTable, 4

الآن المتغير nRows سيحمل قيمة أول 4 بايت والتي تمثل عدد الاتصالات الفعالة .

في الدالة CopyMemory السابقة :

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

الوسيط الثالث سيمثل طول البيانات المراد نسخها بالبايت .

الوسيط الأول سيوضع فيه ناتج النسخ .

نوجز ما تعلمناه في هذه المشاركة :

1 - الوظيفة AllocateAndGetTcpExTableFromStack تعبئ الوسيط الأول لها بقيمة مؤشر الذاكرة .

2 - تركيبة PMIB_TCPEXTABLE

3 - أول 4 بايتات من المؤشر تمثل العضو dwNumEntries

4 - كل 24 بايت من بعد الـ 4 بايت الأولى تمثل سجل واحد في جدول اتصالات TCP الفعالة .

5 - لقراءة البايتات مباشرة من الذاكرة نستخدم الدالة CopyMemory

ولعلنا نتوقف عند هذه النقطة .

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

سأخبرك بأمر ، لا أعلم هل سيكون دافعاً لك لتكملة الدرس أم أنه محبط لك ؟

هل تعلم أن كل ما كتبته سابقاً هو شرح لهذه الأسطر فقط :

Const MAX_ROW  As Integer = 500

Private Type PMIB_TCPEXROW
   dwStats         As Long
   dwLocalAddr     As Long
   dwLocalPort     As Long
   dwRemoteAddr    As Long
   dwRemotePort    As Long
   dwProcessId     As Long
End Type


Private Type PMIB_TCPEXTABLE
   dwNumEntries    As Long
   Table(MAX_ROW)  As PMIB_TCPEXROW
End Type


   Dim pTable As Long  
   Dim nRet As Long
   Dim nRows As Long

   

   nRet = AllocateAndGetTcpExTableFromStack(pTable, 0, GetProcessHeap, 0, 2)

   
   CopyMemory nRows, ByVal pTable, 4

ولكن ،،، تأكد أنه شرحاً مفصلاً سيجعلك تفهم ما يجري بكل وضوح .

لقد كان بإمكاني أن أقول :

نعلن عن 3 متغيرات Long

و نكتب الوظيفة و نمرر لها الوسائط اللازمة لتعود لنا بقيمة المؤشر .

ولكن ،،، هدفنا هنا هو التعلم ولذلك تجد أن الشرح بالتفصيل و ربما الممل أيضاً:)

عموماً ،،،

توقفنا في المشاركة السابقة عند كود الحصول على عدد السجلات في جدول اتصالات TCP الفعالة بواسطة الدالة CopyMemory

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

والعملية بكل بساطة هي :

عدد السجلات * طول السجل الواحد

على افتراض أن عدد السجلات هو 8 ، إذن :

8 * 24 = 192 بايت

يضاف عليها 4 بايت للعضو dwNumEntries والخاص بعدد السجلات

فتكون النتيجة الإجمالية = 192 + 4 = 196 بايت

إذن ، ننسخ 196 بايت ابتداءً من رقم المؤشر الذي أعادته لنا الوظيفة AllocateAndGetTcpExTableFromStack ونضع الناتج في متغير من نوع تركيبة PMIB_TCPEXTABLE كالتالي :

    Dim TcpTableEX As PMIB_TCPEXTABLE

   CopyMemory TcpTableEX, ByVal pTable, ((nRows * 24) + 4)

الآن المتغير TcpTableEX يحمل قيم اتصالات TCP الفعالة مع أرقام العمليات لكل اتصال .

وبهذا نكون قطعنا نصف المسافة ، و تبقى لنا أن نحصر العمليات الحالية في النظام ثم نربط بين رقم كل عملية في النظام مع الرقم العملية المساوي لها في في جدول اتصال Tcp و التي سبق أن وضعناها في المتغير TcpTableEX

وهذا ما سنشرحه في مشاركة قادمة بإذن الله .

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

والآن بعد أن حملنا المتغير TcpTableEX بجدول اتصالات Tcp ننتقل للخطوة التالية و هي ربط هذا الجدول مع العمليات الحالية في النظام .

لمعرفة العمليات الحالية في النظام يجب أن نأخذ (نلتقط) صورة أولاً لعمليات النظام .

ويكون هذا بواسطة الوظيفة CreateToolhelp32Snapshot و التي تأخذ وسيطين ، سنمرر الثابت TH32CS_SNAPALL كوسيط أول و 0& كوسيط ثاني ، لتعود الوظيفة بمقبض كائن صورة عن جميع (انظر لنوع الوسيط الأول ولاحظ اسمه ALL) العمليات الحالية في النظام . إذن نكتب الكود التالي :

    Dim hSnapShot As Long
   hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)

بعد هذا نعلن عن متغير من نوع PROCESSENTRY32 ، كالتالي :

    Dim uProcess As PROCESSENTRY32

سنستخدم المتغير uProcess كمخزن مؤقت "Buffer" للعملية الحالية .

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

Const MAX_PATH As Integer = 260

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

يجب أن نحدد جحم المتغير uProcess كالتالي :

uProcess.dwSize = Len(uProcess)

وهنا قد يطرح سؤال : ما الفائدة من مقبض الصورة hSnapShot و متغير العمليات uProcess ؟

والجواب هو : كي نستخدمهما وسيطين للوظيفة Process32First و الوظيفة Process32Next

إذن نكتب الكود التالي :

    r = Process32First(hSnapShot, uProcess)

هنا سنحمل المتغير uProcess بأول عملية في مقبض الصورة hSnapShot ، لو استعرضت أعضاء المتغير uProcess بعد هذا السطر لوجدت بيانات عن أول عملية .

ستعود هذه الوظيفة بقيمة صحيحة في حال تعبئة المتغير uProcess و خطأ في حال الفشل .

والآن بعدما حصلنا على أول عملية نقارن بين رقم العملية مع أرقام العمليات في جدول TcpTableEX ، فإذا وجدنا تطابق بين رقمي العمليتين نأخذ اسم الملف من المتغير uProcess و نضعه في أداة للعرض (في مثالنا أداة ListView) و نضع كذلك بقية بيانات جدول TcpTableEX و التي تحوي على أرقام المنافذ و العناوين و الحالة . كل هذا يستدعي وجود تكرارين ، الأول للعمليات الحالية في النظام و الثاني لكل اتصال في جدول TcpTableEX . و سيكون الكود كالتالي :

    Dim strFileName As String
   Dim F As Integer
   
   F = 0
   
   Do While r

       strFileName = UCase(Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0)))
       For F = 0 To TcpTableEX.dwNumEntries - 1
           If TcpTableEX.Table(F).dwProcessId = uProcess.th32ProcessID Then
               With TcpTableEX.Table(F)
                   Set lvItem = ListView1.ListItems.Add(, , strFileName)
                   lvItem.SubItems(1) = .dwProcessId
                   lvItem.SubItems(2) = GetIPAddress(.dwLocalAddr)
                   lvItem.SubItems(3) = GetPort(.dwLocalPort)
                   lvItem.SubItems(4) = GetIPAddress(.dwRemoteAddr)
                   lvItem.SubItems(5) = GetPort(.dwRemotePort)
                   lvItem.SubItems(6) = UCase(GetState(.dwStats))
               End With
           End If
       Next F
       'Retrieve information about the next process recorded in our system snapshot
       r = Process32Next(hSnapShot, uProcess)
   Loop
   'close our snapshot handle
   CloseHandle hSnapShot

شرح الكود السابق :

** أعلنا عن متغير نصي strFileName لنضع فيه اسم الملف المستخرج من المتغير uProcess

** أعلنا عن متغير عددي F لنستخدمه في التكرار ، لعرض جدول اتصالات TCP

** نعمل تكرار Do While طالما المتغير r صحيح ، وهذا المتغير يحمل نتيجة نجاح أو فشل العملية للوظيفة Process32First و الوظيفة Process32Next

** نقوم بتعبئة المتغير strFileName باسم الملف .

** نعمل تكرار أخر لنستعرض كافة العمليات في جدول TcpTableEX

** في السطر If TcpTableEX.Table(F).dwProcessId = uProcess.th32ProcessID Then نقارن بين رقمي العمليتين فأذا تطابقا نعرض النتيجة على أداة ListView

** بعد أن قارنا بين رقم العملية في النظام مع كافة عمليات جدول اتصالات TCP نحمل المتغير uProcess بقيمة العملية التالية في النظام بواسطة الوظيفة Process32Next

** إذا انتهينا من التكرار نغلق مقبض الصورة بواسطة الدالة CloseHandle

والآن و بعد أن انتهينا من هذا الدرس أكتب شفيرة البرنامج كاملة : (يجب أن تضع الأدوات التالية : ListView1 , Text1 , Command1 )

Option Explicit


Const MAX_PATH As Integer = 260
Const MAX_ROW  As Integer = 500
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 TH32CS_SNAPMODULE)

Const ERROR_NOT_SUPPORTED As Long = 50&
Const ERROR_SUCCESS As Long = 0&



Private Type PMIB_TCPEXROW
   dwStats         As Long
   dwLocalAddr     As Long
   dwLocalPort     As Long
   dwRemoteAddr    As Long
   dwRemotePort    As Long
   dwProcessId     As Long
End Type


Private Type PMIB_TCPEXTABLE
   dwNumEntries    As Long
   Table(MAX_ROW)  As PMIB_TCPEXROW
End Type


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


Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" _
               (ByVal lFlags As Long, _
                ByVal lProcessID As Long) As Long
               
Private Declare Function Process32First Lib "kernel32" _
               (ByVal hSnapShot As Long, _
                uProcess As PROCESSENTRY32) As Long
               
Private Declare Function Process32Next Lib "kernel32" _
               (ByVal hSnapShot As Long, _
                uProcess As PROCESSENTRY32) As Long
               
Private Declare Sub CloseHandle Lib "kernel32" _
               (ByVal hPass As Long)

Private Declare Function GetProcessHeap Lib "kernel32" () As Long

Private Declare Function htons Lib "ws2_32.dll" _
               (ByVal dwLong As Long) As Long

Private 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


Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
               (Destination As Any, _
                Source As Any, _
                ByVal Length As Long)
               


Private Function GetIPAddress(dwAddr As Long) As String
   Dim arrIpParts(3) As Byte
   CopyMemory arrIpParts(0), dwAddr, 4
   GetIPAddress = CStr(arrIpParts(0)) & "." & _
   CStr(arrIpParts(1)) & "." & _
   CStr(arrIpParts(2)) & "." & _
   CStr(arrIpParts(3))
End Function

Private Function GetPort(ByVal dwPort As Long) As Long
   GetPort = htons(dwPort)
End Function



Private Function GetState(StateOf As Long) As String

   Select Case StateOf
   
       Case 1:  GetState = "Closed"
       Case 2:  GetState = "Listening"
       Case 3:  GetState = "SYN Sent"
       Case 4:  GetState = "SYN Recieved"
       Case 5:  GetState = "Established"
       Case 6:  GetState = "FIN Wait 1"
       Case 7:  GetState = "FIN Wait 2"
       Case 8:  GetState = "Close Wait"
       Case 9:  GetState = "Closing"
       Case 10: GetState = "Last ACK"
       Case 11: GetState = "Time Wait"
       Case 12: GetState = "Delete TCB"
   End Select

End Function

Private Sub Command1_Click()

   ListView1.ListItems.Clear
   
   Dim pTable As Long
   Dim nRet As Long
   Dim nRows As Long
   Dim lvItem As ListItem
   Dim lvItem2 As ListItem
   

   nRet = AllocateAndGetTcpExTableFromStack(pTable, 0, GetProcessHeap, 0, 2)
   
   If nRet <> 0 Then
       MsgBox "?UC? C?EOU?? ?C ?I?? ??? C?IC?E"
       Exit Sub
   End If
   
   CopyMemory nRows, ByVal pTable, 4

   
   Dim TcpTableEX As PMIB_TCPEXTABLE
   
   CopyMemory TcpTableEX, ByVal pTable, (nRows * 24) + 4
   
   Text1.Text = "Pointer : " & pTable & " By Hex = " & Hex(pTable) & _
               vbNewLine & "Rows : " & vbTab & TcpTableEX.dwNumEntries
   
   If nRows = 0 Or pTable = 0 Then
       MsgBox "?C ???I CE?C?CE ??C?E"
       Exit Sub
   End If


   Dim F As Integer


   
   Dim hSnapShot As Long, uProcess As PROCESSENTRY32, r As Long
   
   hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0&)
   

   uProcess.dwSize = Len(uProcess)

   r = Process32First(hSnapShot, uProcess)
   
   Dim strFileName As String
   
   F = 0
   
   Do While r

       strFileName = UCase(Left$(uProcess.szExeFile, IIf(InStr(1, uProcess.szExeFile, Chr$(0)) > 0, InStr(1, uProcess.szExeFile, Chr$(0)) - 1, 0)))
       For F = 0 To TcpTableEX.dwNumEntries - 1
           If TcpTableEX.Table(F).dwProcessId = uProcess.th32ProcessID Then
               With TcpTableEX.Table(F)
                   Set lvItem = ListView1.ListItems.Add(, , strFileName)
                   lvItem.SubItems(1) = .dwProcessId
                   lvItem.SubItems(2) = GetIPAddress(.dwLocalAddr)
                   lvItem.SubItems(3) = GetPort(.dwLocalPort)
                   lvItem.SubItems(4) = GetIPAddress(.dwRemoteAddr)
                   lvItem.SubItems(5) = GetPort(.dwRemotePort)
                   lvItem.SubItems(6) = UCase(GetState(.dwStats))
               End With
           End If
       Next F
       'Retrieve information about the next process recorded in our system snapshot
       r = Process32Next(hSnapShot, uProcess)
   Loop

   CloseHandle hSnapShot
   
End Sub

وهذا ملف البرنامج

Enum.rar

تم تعديل بواسطه MSVS
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم

ماشاء الله تبارك الله

اخي الكريم "أبو عابد" و الله متل هذه الدروس تعد من التحف التي

يتشرف بها و بك هذا القسم

تحياتي لك بالتوفيق :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

اتمنى منك ان تترجم هذا الدرس والدروس الاخرى الى برنامج كامل لمراقبه الاتصالات الفعالة في النظام مع امكانيه عرض رقم الايبي لها والبرنامج المسؤل عنها وغلقها وامور اخرى ... وسيكون البرنامج العربي الوحيد في هذا المجال ..

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اشكر جميع الاخوة على تشجيعهم ، و ارفق صورة لنافذة البرنامج

Program_Window.JPG

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

جازاك الله خيرا يا اخي و أسأل الله عز وجل ان يجعل هذا في ميزان حسناتكم

فعلا الموضوع ممتاز............و جاري فهم الموضوع :lol: لانه شوي بده تركيز

جازاك الل خيرا.....................

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
السلام عليكم

ماشاء الله تبارك الله

اخي الكريم "أبو عابد" و الله متل هذه الدروس تعد من التحف التي

يتشرف بها و بك هذا القسم

تحياتي لك بالتوفيق :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

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

كل الشكر والتقدير لك أخوي MSVS

يا أستاذي / MSVS عندي سؤال بسيط لو سمحت

أنا تابعت الجزء الأول من الموضوع والحمدالله عديناها بصعوبة

لكن عندما قراءة الجزء الثاني من الموضوع واجهتني أول مشكلة !!

وهي من أين أتيت بالدالة AllocateAndGetTcpExTableFromStack مع البارتات

لأني بحثت في برنامج API-Guide وبعض المواقع المتخصصة بالدوال ولم أحصل شيئا عنها !!

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

عذرا أخي على السؤال ولكني أريد أن أحتفظ بجميع الدوال مع البارتات وكنت أعتقد أن برنامج API-guide خير مثال لحفظه

ولكن الأن لا أعتقد ذالك ..

يعطيك العافية

تحياااااتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

وعليكم السلام

لكن عندما قراءة الجزء الثاني من الموضوع واجهتني أول مشكلة !!

وهي من أين أتيت بالدالة AllocateAndGetTcpExTableFromStack مع البارتات

من Google :)

لأني بحثت في برنامج API-Guide وبعض المواقع المتخصصة بالدوال ولم أحصل شيئا عنها !!

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

عذرا أخي على السؤال ولكني أريد أن أحتفظ بجميع الدوال مع البارتات وكنت أعتقد أن برنامج API-guide خير مثال لحفظه

ولكن الأن لا أعتقد ذالك ..

البرنامج API-guide لا يستوعب كل دوال API ولكن المشهور منها فقط .

ولن تجد مكان يستوعب كل دوال API حتى MSDN :rolleyes:

أنظر مثلاً الدوال المستخدمة في هذا المقال لكن تجدها في MSDN .

عن نفسي وصلت لتلك الدالة بالصدفة في أحد المواقع عندما كنت أبحث عن شرح لدالة GetTcpTable

والسلام عليكم

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

محتاجة للكود

خاصة اذا كان يفحص البرنامج هل هو موثوفق اولا

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
زوار
This topic is now closed to further replies.

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .