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

[ تمت الإجابة ]دوال مكتبة الأدوات المساعدة

مغلق
بدأه Diox83 في 23 فبراير 2006 · 4 رد · 2,165 مشاهدة · في أرشيف قسم Windows APIs
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

-9

إخواني الأعزاء السلام عليكم.

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

ثانيا أحببت أن أشارك بكتابة هذا الموضوع المتواضع عن دوال مكتبة الأدوات المساعدة Tool Help Library فأرجو أن يلقى إعجابكم.

هذا الموضوع ليس لبرنامج متقدم و إنما موضوع اخباري و يهم المبتدئين قبل المحترفين.

مقدمة:

تساعد دوال مكتبة الأدوات المساعدة Tool Help Library المطورين على الحصول على معلومات حول التطبيقات جارية التنفيذ على الجهاز Processes. وتحتوي هذه المكتبة على اثنتا عشر دالة، و يتم استخدام هذه الدوال مثلا في برامج التنقيح كبرنامج Task Manager .

هذه الدوال هي:

CreateToolhelp32Snapshot

Heap32First

Heap32ListFirst

Heap32ListNext

Heap32Next

Module32First

Module32Next

Process32First

Process32Next

Thread32First

Thread32Next

Toolhelp32Read

ProcessMemory

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

1 - الدالة CreateToolhelp32Snapshot و هي الأهم.

تقوم هذه الدالة بأخذ لقطة Snapshot أو صورة تحتوي على معلومات تتعلق بالتطبيقات جارية التنفيذ processes وأيضا المراكم heaps و الوحدات modules (متلا مكتبات (DLL و الخيوط threads المستعملة من طرف هذه التطبيقات.

تعريف:

HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);

المعطيات:

dwFlags -a

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

TH32CS_SNAPPROCESS : تحديد قائمة جميع التطبيقات جارية التنفيذ.

TH32CS_SNAPTHREAD : تحديد قائمة جميع الخيوط جارية التنفيذ.

TH32CS_SNAPHEAPLIST : تحديد قائمة المراكم لتطبيق جاري التنفيذ.

TH32CS_SNAPMODULE : تحديد قائمة الوحدات لتطبيق جاري التنفيذ.

TH32CS_SNAPALL : تكافئ تحديد كل هذه القيم TH32CS_SNAPHEAPLIST و TH32CS_SNAPMODULE و TH32CS_SNAPPROCESS و TH32CS_SNAPTHREAD.

th32ProcessID -b

يأخذ قيمة معرِّف تطبيق جاري التنفيذ ProcessID فقط عند استعمال TH32CS_SNAPMODULE و TH32CS_SNAPMODULE في المعطى الأول، أو يأخذ القيمة 0 فيما عدا ذلك.

القيمة المعادة:

في حالة نجاح الدالة تقوم بإرجاع مقبض للقطة Snapshot التي تم إنشاؤها والتي تحمل المعلومات التي قمنا بتحديدها بواسطة المعطيات الممررة، أما في حالة أي خطأ تقوم الدالة بإرجاع العدد 1-.

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

ملحوظة : المعلومات الموجودة في اللقطة Snapshot هي للقراءة فقط.

عند الانتهاء من اللقطة Snapshot نقوم باستدعاء الدالة CloseHandle لتحرير مساحة الذاكرة التي تشغلها هذه اللقطة.

2 - الدالة Process32First

تقوم بأخذ المعلومات المتعلقة بالتطبيق جاري التنفيذ(Process) الأول المصادَفة في اللقطة، ووضعها في حقول تسجيل أو بنية struct .

تعريف:

BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);

المعطيات :

hSnapshot -a

مقبض اللقطة التي تم إنشاؤها سابقا.

Lppe -b

عنوان البنية PROCESSENTRY32 التي يتم وضع المعلومات داخلها.

القيمة المعادة:

تقوم الدالة بإرجاع القيمة TRUE في حالة نجاحها بنقل المعلومات المتعلقة بالتطبيق جاري التنفيذ الأول ووضعها في حقول البنية، أو FALSE في حالة فشلها.

ملحوظة: قبل استدعاء هذه الدالة يجب أن تضع في الحقل dwSize للبنية PROCESSENTRY32 قيمة سعة هذه البنية (sizeof(PROCESSENTRY32 .

لاسترجاع معلومات التطبيق جاري التنفيذ التالي نقوم باستدعاء الدالة Process32Next.

3 - البنية PROCESSENTRY32

typedef struct tagPROCESSENTRY32 { 
    DWORD dwSize; 
    DWORD cntUsage; 
    DWORD th32ProcessID; 
    DWORD th32DefaultHeapID; 
    DWORD th32ModuleID; 
    DWORD cntThreads; 
    DWORD th32ParentProcessID; 
    LONG  pcPriClassBase; 
    DWORD dwFlags; 
    char szExeFile[MAX_PATH]; 
} PROCESSENTRY32;

4 - الدالة Process32Next

تقوم باسترجاع المعلومات المتعلقة بالتطبيق جاري التنفيذ التالي المصادَفة في اللقطة، ووضعها في حقول البنية PROCESSENTRY32 .

المعطيات :

hSnapshot -a

مقبض اللقطة التي تم إنشاؤها سابقا.

Lppe -b

عنوان البنية PROCESSENTRY32 التي يتم وضع المعلومات داخلها.

القيمة المعادة:

تقوم الدالة بإرجاع القيمة TRUE في حالة نجاحها بنقل المعلومات المتعلقة بالتطبيق جاري التنفيذ التالي ووضعها في حقول البنية، أو FALSE في حالة فشلها.

والآن بعد هذه المطالعة القصيرة سنقوم بإنشاء تطبيق يقوم بسرد أسماء التطبيقات جارية التنفيذ(Processes) .

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

تطبيق 1:

1 - لكي نقوم بسرد أسماء التطبيقات جارية التنفيذ (Processes) يجب أن نأخذ لقطة لها وذلك باستدعاء الدالة CreateToolhelp32Snapshot و أن نمرر لها المعطيان TH32CS_SNAPPROCESS و 0 كما هو مبين في الشرح أعلاه، ثم نضع الناتج أي مقبض اللقطة hSnapShot الذي سنحتاجه فيما بعد في متغير وسعه 4byte .

hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

يجب أن نعرف المتغير hSnapshot.

var
   hSnapshot: THandle;

THandle = LongWord و LongWord عدد صحيح موجب يمتد بين 0 و 2^32 .

يوجد منكم من سيقول أن الدالة تعيد قيمة سالبة وهي 1- ، لذاك سنستعمل القيمة $FFFFFFFF المكافئة ل 1-.

2 - في حالة فشل الدالة ننهي البرنامج.

سنقوم باستدعاء الدالة Halt لتقوم بإنهاء البرنامج في حالة فشل الدالة السابقة.

If hSnapshot = $FFFFFFFF then Halt(0);

3 - يجب أن نتفحص معلومات اللقطة باستعمال الدالتين Process32First و Process32Next، ولكن قبل ذلك نقوم بتعريف البنية التي ستحوي هذه المعلومات.

var
   ProcessEntry: TProcessEntry32;

TProcessEntry32 = tagPROCESSENTRY32 فإن لم تكن هذه البنية معرفة في بيئتك البرمجية فقم بتعريفها بنفسك.

سنقوم بإعطاء قيمة أولية للحقل dwSize وهي سعة البنية.

ProcessEntry.dwSize := SizeOf(ProcessEntry);

بعد ذلك نستدعي الدالة Process32First التي ستقوم بنقل المعلومات المتعلقة بالتطبيق جاري التنفيذ(Process) الأول المصادَفة في اللقطة ووضعها في حقول البنبة ProcessEntry ، ثم بعد ذلك نقوم باستخراج الاسم.

if Process32First(hSnapshot, ProcessEntry) then
begin
   Writeln(ProcessEntry.szExeFile);
end;

الحقل szExeFile بحتوي اسم التطبيق جاري التنفيذ(Process) الأول بعد ملئه من طرف الدالة Process32First

الدالة Writeln تقوم بإخراج الاسم إلى الشاشة.

والآن مادامت هناك معلومات حول تطبيقات جارية التنفيذ أخرى سنقوم بتفحصها باستعمال الدالة Process32Next ووضعها في حقول البنبة ProcessEntry ، ثم استخراج الاسم منها.

while Process32Next(hSnapShot, ProcessEntry) do
      Writeln(ProcessEntry.szExeFile);

لقد انتهينا من سرد أسماء التطبيقات جارية التنفيذ، والآن يجب علينا تحرير مساحة الذاكرة التي تشغلها اللقطة.

CloseHandle(hSnapShot);

الكود كامل:

program Project1;

{$APPTYPE CONSOLE}

uses
   //SysUtils,
   TlHelp32,
   Windows;

var
   hSnapshot: THandle;
   ProcessEntry: TProcessEntry32;

begin
   hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
   if hSnapshot = $FFFFFFFF then Halt(0);
   ProcessEntry.dwSize := SizeOf(ProcessEntry);
   if Process32First(hSnapshot, ProcessEntry) then
   begin
      Writeln(ProcessEntry.szExeFile);
      while Process32Next(hSnapshot, ProcessEntry) do
         Writeln(ProcessEntry.szExeFile);
   end;
   CloseHandle(hSnapshot);
   Readln;
end.

تطبيق 2 :

هذا التطبيق يقوم بسرد أسماء ومسارات الوحدات ( مكتبات (DLL التي يستعملها.

program Project2;

{$APPTYPE CONSOLE}

uses
  //SysUtils,
  TlHelp32,
  Windows;

var
  hSnapshot: THandle; // تعريف مقبض اللقطة
  ModuleEntry: TModuleEntry32; // تعريف البنية الخاصة بمعلومات الوحدات
begin
//إنشاء اللقطة
  hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId);

//نقوم بإنهاء البرنامج في حالة فشل الدالة السابقة 
  if hSnapshot = $FFFFFFFF then Halt(0);
//وهي سعة البنية dwSize نقوم بإعطاء قيمة أولية للحقل  
  ModuleEntry.dwSize := SizeOf(ModuleEntry);

//ModuleEntry نقوم بنقل المعلومات المتعلقة بالوحدة الأولى المصادَفة في اللقطة ووضعها في حقول البنية
  if Module32First(hSnapshot, ModuleEntry) then
begin
//szExePath و szModule إخراج اسم ومسار الوحدة إلى الشاشة الموجودان في الحقلين 
    Writeln(ModuleEntry.szModule + ' - "' + ModuleEntry.szExePath + '"');

//مادام هناك وحدات أخرى أخرج  أسماءها ومساراتها إلى الشاشة
    while Module32Next(hSnapshot, ModuleEntry) do
      Writeln(ModuleEntry.szModule + ' - "' + ModuleEntry.szExePath + '"');
  end;

//تحرير مساحة الذاكرة التي تشغلها اللقطة
 CloseHandle(hSnapshot);
  Readln;

end.

تطبيق 3 :

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

في حالة نجاح هذه الدالة تعيد لنا القيمة True .

إذن تعريف هذه الدالة سيكون على الشكل التالي

function TerminateTask(exeFileName: string): Boolean;

لكي ننهي تطبيق جاري التنفيذ معين نحتاج إلى الدالة TerminateProcess . هذه الدالة تحتاج معطيين، الأول هو مقبض التطبيق جاري التنفيذ hProcess و كود الخروج uExitCode الذي سنعطيه القيمة 0 .

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

لكي نحصل على مقبض تطبيق جاري التنفيذ معين نحتاج إلى الدالة OpenProcess . هذه الدالة تحتاج ثلاث معطيات، الأول هو راية تحدد صلاحيات التعامل مع التطبيق جاري التنفيذ dwDesiredAccess، الثاني bInheritHandle يحدد إمكانية وراثة المقبض أم لا، والثالث هو معرف التطبيق جاري التنفيذ dwProcessId المراد مقبضه.

نعلم أن أسماء ومعرفات التطبيقات جاري التنفيذ نستطيع الحصول عليهما بأخذ لقطة باستعمال الدالة CreateToolhelp32Snapshot إذن فقد حللنا المشكل.

أولا نقوم تفحص اللقطة و مقارنة المعطى exeFileName مع أسماء التطبيقات جاري التنفيذ الواردة في اللقطة،

فإن وجدنا ضالتنا نقوم بأخذ المعرف dwProcessId المكافئ للاسم و نمرره للدالة OpenProcess التي بدورها تعيد لنا المقبض hProcess، هذا المقبض نمرره للدالة TerminateProcess لكي تقوم بإنهاء التطبيق جاري التنفيذ صاحب هذا المقبض.

function TerminateTask(exeFileName: string):Boolean;
var
   hSnapshot: THandle;
   ProcessEntry: TProcessEntry32;
   Loop: Boolean;
   hProcess: THandle;
begin
   Result := False;
//إنشاء اللقطة
   hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
//False الخروج من الدالة في حالة فشل الدالة السابقة معيدين القيمة
   if hSnapshot = $FFFFFFFF then
   begin
      Result := False;
      Exit;
 end;
//وهي سعة البنية dwSize نقوم بإعطاء قيمة أولية للحقل
   ProcessEntry.dwSize := SizeOf(ProcessEntry);
//ProcessEntry نقوم بنقل المعلومات المتعلقة بالوحدة الأولى المصادَفة في اللقطة ووضعها في حقول البنية

   Loop := Process32First(hSnapshot, ProcessEntry);
   while Loop do
 begin
//مع أسم التطبيق جاري التنفيذ الوارد في اللقطة exeFileName مقارنة المعطى
      if UpperCase(exeFileName) = UpperCase(ProcessEntry.szExeFile) then
  begin
//hProcess استرجاع مقبض التطبيق جاري التنفيذ المراد إنهاؤه و وضعه في
         hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, ProcessEntry.th32ProcessID);
//إنهاء التطبيق جاري التنفيذ المراد إنهاؤه و إعادة قيمة نجاح أو فشل العملية
         Result := TerminateProcess(hProcess, 0);
//الخروج من الحلقة
         Break;
  end;
//العودة إلى الحلقة مادام هناك المزيد
      Loop := Process32Next(hSnapshot, ProcessEntry);
   end;
//تحرير مساحة الذاكرة التي تشغلها اللقطة
   CloseHandle(hSnapshot);
end;

للمهتمين ببرامج أحصنة طروادة Trojan يمكنكم استخدام هذه الدالة في برمجة الخادم Server وذلك بتمريرلها أسماء مكافحات الفيروسات و الجدران النارية Firewalls لتقوم بإنهاء عملهم.

يمكنكم تحميل الأكواد من المرفقات.

لقد انتهيت، أرجو أنكم استفدتم و استمتعتم بهذا الموضوع.

إليكم خالص تمنياتي بالتوفيق، و السلام عليكم.

SourceCode.rar

function Factorial(N: LongWord):LongWord; assembler;
asm
	CMP	 EAX, 1
	JLE	 @END
	MOV	 ECX, EAX
	DEC	 ECX
@CONTINUE:
	MUL	 ECX   
	LOOP	 @CONTINUE
	RET	
@END:
	XOR	 EAX, EAX 
	INC	 EAX
end;
#2

السلام عليكم

تم فصل المشاركة عن موضوع التهاني حتى لا تضيع بين المشاركات.

ومرحباً بك Diox83 كعضو جديد فى المنتدى.

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

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#3

مشكور أخي احمد غريب على الترحيب :)

function Factorial(N: LongWord):LongWord; assembler;
asm
	CMP	 EAX, 1
	JLE	 @END
	MOV	 ECX, EAX
	DEC	 ECX
@CONTINUE:
	MUL	 ECX   
	LOOP	 @CONTINUE
	RET	
@END:
	XOR	 EAX, EAX 
	INC	 EAX
end;
#4

شرح رائع أخ Diox83

ملحوظة بسيطة على :

اقتباس
يتم استخدام هذه الدوال مثلا في برامج التنقيح كبرنامج Task Manager .

حسب معلوماتي البسيطة أن Task Manager لا يستدعي تلك الدوال ...

ما اتحدث عنه في نظام Windows XP SP2 واظن نفس الشئ في بقية الأنظمة من عائلة NT ...

Task Manager يستدعي دوال من النوع Native API ومنهاNtQuerySystemInformation ...

وضعت شرح مبسط عنها في قسم الدلفي ....

Task Manager أيضاً يستدعي الدالة VDMEnumTaskWOWEx لعمل 16-Bit Processes Enumeration ...

طبعاً هذا الكلام بعد نظره سريعة على taskmgr.exe باستخدام IDA pro ...

هذا مقال ربما يفيد أيضاً

How To Enumerate Applications Using Win32 APIs

===

إضافة :

طبعاً عمل Disassemble لـ kernel32.dll الذي يحوي دوال ToolHelp سنلاحظ أن هذه الدوال بدورها تستدعي دوال Native API ...

تم تعديل هذه المشاركة بواسطة cipher في 24 فبراير 2006 في 13:22

"First they ignore you, then they laugh at you, then they attack you, then you win"

===

اقتباس

حُكَّامُـنَا إِنْ تَصَـدّوا لِلْحِمَــى اقْتَحَمُـوا ***** وَإِنْ تَصَدَّى لَـهُ المُسْتَعْمِـرُ انْسَحَبُـوا

هُمْ يَفْرشـُونَ لِجَيْـشِ الغَــزْوِ أَعْيُنَـهُـمْ ***** وَيَدَّعُــونَ وُثُـوبَـاً قَـبْـلَ أَنْ يَثِـبُــوا

الحَاكِمُـونَ و«وَاشُنْـطُـنْ» حُكُومَتُـهُـمْ ***** وَاللامِعُــونَ وَمَـا شَعَّـوا وَلا غَرَبُــوا

القَاتِلُـــونَ نُبُــوغَ الشَّـعْــبِ تَرْضِـيَـــةً ***** لِلْمُعْتَدِيــنَ وَمَـا أَجْـدَتْـهُـمُ الـقُــرَبُ

لَهُمْ شُمُـوخُ «المُثَنَّـى» ظَاهِـرَاً وَلَهُـمْ ***** هَـوَىً إِلَـى بَابَـك الخَرْمِـيّ يُنْتَسَـبُ

البردوني "أبو تمام وعروبة اليوم" 1971

===

اقتباس
عبيد الهوى يحكمون البـلاد ***** ويحكمهــم كلّهـــم درهــــــم

و تقتـادهـم شهـوة لا تنــام ***** وهـــم فـي جـهالتهــم نــــوّم

ففــي كـــلّ ناحيــة ظـالـــم ***** غبــــــيّ يسـلـّطــــه أظلـــم

أيا من شبعتم على جوعــنا ***** وجـــوع بنينـا ألـم تتخمـــوا ؟

ألم تفهموا غضبة الكادحين ***** على الظلـم ؟ لا بدّ أن تفهموا

البردوني "نحن و الحاكمون "

#5

أخي الكريم cipher شكرا لك على التشجيع والمعلومات القيمة.

function Factorial(N: LongWord):LongWord; assembler;
asm
	CMP	 EAX, 1
	JLE	 @END
	MOV	 ECX, EAX
	DEC	 ECX
@CONTINUE:
	MUL	 ECX   
	LOOP	 @CONTINUE
	RET	
@END:
	XOR	 EAX, EAX 
	INC	 EAX
end;

هذا الموضوع مغلق.

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