الأساليب المتقدمة لبرمجة وكتابة برامج مقاومة الفايروسات AntiVirus وبرامج التجسس Anti-Spyware

عام 0 geek4arab
Spread the love

موضوع مقاومة الفايروسات موضوع طويل ومعقد ومتجدد بإستمرار ولكن الأساسيات باقية إلى اليوم
القاعدة التي تبنى عليها برامج مكافحة الفايروسات هي:تحليل الفايروس ثم إصدار توقيع ثم إصطيادة
هذه الثلاث نقاط الاساسية هي موضوعنا في هذا البحث , الأمثلة في هذا الموضوع تتطلب برامج هكس
وديسمبلي وسنأخذ olly + مترجم لغة سي وسنأخذ الفيجول سي.

نبدأ في الموضوع:
لنفرض انه ظهر فايروس جديد يدخل الأجهزة ويخترق الانظمة بإستغلال احدى الثغرات الامنية وتم إيجاد
هذا الفايروس بإستخدام برامج المرقبة التي درسناها في هذا الموضوع
http://www.jaascois.com/research/36601015

الآن وبعد معرفة الفايروس نريد كتابة برنامج Anti Virus ونريد توزيعه على المستخدمين ليتم حذفه
من أجهزتهم , كيف ؟ سنأخذ هذا المثال على الاساسيات
في هذا الرابط تجد ملف تنفيذي exe عادي سنفرض انه ملف الفايروس الذي وجدناه بعد مراقبه النظام
http://www.jaascois.com/research/36601021/virus.exe

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

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

لو بدئنا بدراسه هذه المقدمه لوجدنا انها تنقسم إلى ثلاث اقسام وهي
1- مقدمه DOS ثم 2- مقدمه PE ثم وفي النهايه section او الاقسام

1- مقدمه DOS
لمشاهدة هذه المقدمه من خلال برنامج olly ومن القائمة veiw إختر file ثم تجول في جهازك
وإختر مثالنا virus.exe ,, سيظهر لك محتوى الملف بصيغه الهكس , وإذا اردنا عرض
الملف بصيغه المقدمات إضغط بالزر الأيمن للماوس وإختر Special ثم PE header كما تشاهد في الصورة

بعد ان تغير طريقة العرض إلى PE header ستظهر لك عند العنوان صفر مقدمه الدوس
بمعنى ان اول مقدمه عند اول بايت في الملف تمثل مقدمه الدوس كما تشاهد

الآن سنكتب معنى كل بايت في مقدمه الدوس مع ملاحظة ان كل الارقام ستكون بالنظام الست عشري hex
اول بايت في اي ملف تنفيذي
00: MZ
الحرفين M و Z تمثلان توقيع الملف التنفيذي وتم إضافه للمقدمه لشغله مهمه وهي ان الملفات التنفيذيه لها
انواع كثيرة جدا مثل ملفات dll وocx و sys و vxd و scr وcpl و…..
لكثر انواع الملفات التنفيذية تم إضافه توقيع للملف ليعرف النظام انه ملف تنفيذي
بعد ذلك تبدأ بقيه البيانات التي في الحقيقة ليست لها اهميه في نظام وندوز اهميتها كانت ايام دوس

02: عدد البايتات في آخر بلوك البلوك مكون من 512 بايت DOS_PartPag
04: مجموع عدد البلوكات في الملف التنفيذي DOS_PageCnt
ملاحظه القيمه الأولى ضرب القيمه الثانيه يساوي حجم الملف التنفيذي

06: عدد مداخل الكتل الذاكريه المتحركه أو المتنقله DOS_ReloCnt
08: حجم ترويسه الفقره DOS_HdrSize
0A: الحد الأدنى من الفقرات في الملف التنفيذي DOS_MinMem
0C: الحد الأعلى من الفقرات في الملف التنفيذي DOS_MaxMem
0E: قيمه المكدس SS ويمثل DOS_ReloSS
10:قيمه دليل المكدس SP ويمثل DOS_ExeSP
12: مدقق المقارنه DOS_ChkSum
14: قيمه دليل الكود CS:IP ويمثل DOS_ExeIP
16: بدابه عناوين الكتل الذاكريه ويمثل قسم الكود DOS_ReloCS
18: علامه تدل على بدايه كتله ذاكريه DOS_TablOff
وهذا البايت قد يكون مفيد لتحديد الكتله الذاكريه التاليه وهي مقدمه pe الخاصه بنظام وندوز
1A: قيمه هذه الكلمه دائما صفر لتدل على بدايه البرنامج من الداله الرئيسيه DOS_Overlay

وبعد هذه المقدمه يجب ان تعرف ان الفايروسات نادرا ماتستخدم هذه المقدمه لان اغلب المعلومات
بها لايستخدمها النظام.

نكمل وندخل اكثر في الموضوع ,, قلنا ان البايت 18 بالهكس يمثل الكتله الذاكريه التاليه
خلونا نستخدمه لنحصل على عنوان كتله pe لو لاحظت ان البايت 18 يساوي القيمه 40
توجه للسطر 40 ( ملاحظة كل الارقام في هذا الموضوع بالصيغه الهكس )
ستجد عند العنوان 40 رقم آخر هو C8 ويمثل عنوان بدايه pe توجه للإزاحه C8 ولاحظ مقدمه pe

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

00:علامه بدايه تروسه البرنامج مكونه من 4 بايت PE signature
04:نوع الآله التي يعمل عليها البرنامج Machine وتدل على نوع المعالج مثل 386
06: عدد الأقسام في البرنامج قسم الكود وقسم البيانات وهكذا NumberOfSections
08: وقت إنشاء البرنامج TimeDateStamp
0C: مؤشر إلى جدول الرموز الرموز تستخدم في التنقيح ولا تستخدم في البرنامج النهائي PointerToSymbolTable
10: عدد الرموز NumberOfSymbols
14: حجم ترويسه الملف غير متضمنه حجم الأقسام وهي متساويه في كل البرامج SizeOfOptionalHeader
16:خصائص البرنامج Characteristics مثل برنامج نظام او مكتبه ربط او….انواع الملفات التنفيذية
18:نوع ترويسه الملف MagicNumber
1A:رقم إصدار الرابط النهائي MajorLinkerVersion الرابط هو احد اقسام مترجم لغه البرمجه
1B:رقم إصدار الرابط الأولي أو التجريبي يساوي 0 MinorLinkerVersion
1C:حجم قسم الكود في البرنامج التنفيذي SizeOfCode
20: حجم قسم البيانات للبرنامج SizeOfInitializedData
ملاحظه بعض المترجمات تعتبر كل الأقسام بيانات وتكون القيمه هنا الحجم الوهمي لكل الأقسام
بعضها لا يعتبر قسم الكود بيانات وتكون القيمه هنا الحجم الوهمي لكل الأقسام عدى قسم الكود
24:حجم قسم البيانات الغير متغير SizeOfUninitializedData
28: عنوان بدايه تنفيذ البرنامج AddressOfEntryPoint
2C:عنوان بدايه قسم الكود BaseOfCode
30: عنوان بدايه قسم البيانات BaseOfData
34: عنوان البرنامج في الذاكره ImageBase
ملاحظه بعد ما يشتغل البرنامج وينقل إلى الذاكره كل العنواين مثل عنوان بدايه البرنامج وعناوين الأقسام
يضاف إليها عناون البرنامج في الذاكره وهو عنوان وهمي

38: يحتوي إزاحه أول قسم في البرنامج وعاده يكون قسم الكود والفائده ترتيب أقسام البرنامج SectionAlignment
3C: يحتوي على تنسيق الأقسام والفرق بين حجم القسم الفعلي والوهمي ولذلك سيتم شرحها مع الأقسام FileAlignment
3E:إصدار نظام التشغيل النهائي MajorOSVersion
40: إصدار نظام التشغيل الأولي MinorOSVersion
ملاحظه أي إصدار أولي أو تجريبي يساوي صفر
42: إصدار العنوان الوهمي للبرنامج راجع الإزاحه 34 وغالبا يساوي إصدار نظام التشغيل MajorImageVersion
44: الإصدار الأولي للعنوان يساوي 0 MinorImageVersion
46: إصدار النظام الفرعي النهائي يساوي إصدار نظام التشغيل MajorSubsystemVersion
48: الإصدار الأولي للنظام الفرعي يساوي 0 MinorSubsystemVersion
4A: محجوز للنظام
4E:حجم عنوان البرنامج يساوي العنوان الفعلي لآخر قسم +حجم القسم الفعلي SizeOfImage
52: حجم كل الترويسات بمعنى أول مايبدأ شفره البرنامج بعد الترويسه SizeOfHeaders
56:مدقق المقارنه CheckSum وهو عباره عن إعطاء الملف توقيع لا يشبه اي ملف آخر , سندخل في هذا الموضع نهايه الدرس

5A: خصائص إظهار البرنامج برنامج رسومي أو كونسل مثل الدوس ولكن 32 بت Subsystem
5C: خصائص ربط المكاتب بالثريد أو العمليه DLLCharacteristics
5E:الحجم الإفتراضي للمكدس وهو دائما يساوي واحد ميجابايت SizeOfStackReserve
62: الحجم الحالي للمكدس SizeOfStackCommit
66: الحجم الإفتراضي للكومه وهو دائما يساوي واحد ميجا SizeOfHeapReserve
6A: الحجم الحالي للكومه SizeOfHeapCommit
ملاحظه كل الأربع الأحجام للمكدس والكومه متشابهه في كل البرامج إذا لم يغيرها المبرمج نفسه

6E: أعلام المشغل البرنامج LoaderFlags
72:القيمه الإفتراضيه لعناوين وأحجام الأقسام الفعليه في كل المترجمات يساوي 16 أي 10 بالهيكس NumberOfRvaAndSizes
وهو أن لكل قسم عنوان فعلي واحد وحجم فعلي واحد عدد الأقسام ضرب 2 قد يكون عدد الأقسام
أكبر مافي مشكله إعرف إنها مو كلها فعليه وهذه الاساليب متبعه في برامج التشفير

76: عنوان جدول الدوال المصدره من الملف Export Table address
7A: حجم جدول الدول المصدره Export Table address
7E: عنوان جدول الدوال المستورده للملف Import Table address
82: حجم جدول الدوال المستورده Import Table size
86: عنوان جدول مصادر الملف الأيقونات والنوافذ وغيرها Resource Table address
في مثالنا تجده صفر لأننا لم نستخدم اي ايقونه او نافذه او صوره
8A: حجم جدول مصادر الملف Resource Table size

8E: عنوان جدول الإستثناءات والأخطاء في البرنامج Exception Table address
92: حجم جدول الإستثناءات Exception Table size
96: عنوان جدول شهادة البرنامج Certificate File pointer
9A: حجم جدول شهادة البرنامج Certificate Table size
هذه الجداول ما أدري متى بتكون مستخدمه يمكن في المستقبل
إلى الآن القيمه الإفتراضيه لهذه الجداول 0 واعتقد انها ستستخدم مثل طريقه
شهادة الوثوقيه للمواقع

9E: عنوان جدول الكتل الذاكريه المتنقله Relocation Table address
A2: حجم جدول الكتل Relocation Table size
الكتل المتنقله عباره عن طريقه لتخزين كود تنفيذي في قسم البيانات
ظهر استخدامه اول مره في برامج الضغط والحزم ثم في برامج التشفير والآن في الفايروسات

A6: عنوان بيانات تصحيح البرنامج غير مستخدم في البرنامج النهائي Debug Data address
AA: حجم البيانات Debug Data size
AE: عنوان بيانات تصميم وبنيه البرنامج Architecture Data address
B2: حجم البيانات Architecture Data size
B6: عنوان جدول المؤشرات العامه Global Ptr address
BA: حجم الجدول
BE: محجوز للنظام
C2: عنوان مخزن خيوط او ثريد البرنامج المحليه TLS Table address
C6: حجم الجدول TLS Table size
CA: عنوان جدول تشكيله البرنامج Load Config Table address
CE: حجم الجدول Load Config Table size
D2: عنوان تحديد جدول إستيراد الدوال Bound Import Table address
D6: حجم الجدول Bound Import Table size
DA: جدول العناوين لعناوين الإستيراد Import Address Table address
DE: حجم الجدول Import Address Table size
E2: جدول الإنتظا لإستيراد الدوال Delay Import Descriptor address
E6: حجم الجدول Delay Import Descriptor size
EA: عناون بدايه ملفات التشغيل لتقنيه الكوم COM+ Runtime Header address
EE: حجم جدول الإستيراد Import Address Table size
F2: محجوز للنظام Reserved
F4: محجوز للنظام Reserved

بعد ذلك يبدأ تنسيق الأقسام في البرنامج وكلها نفس القاعده
0-7: إسم القسم وحجمه 8 بايتات SECTION
0B: الحجم الفعلي للقسم VirtualSize
0F: العنوان الفعلي للقسم VirtualAddress
13: الحجم الوهمي للقسم SizeOfRawData
17:العنوان الوهمي للقسم PointerToRawData
القصد من ورى هذا الفصل بين الأقسام لو تفتح أي برنامج
بمحرر هكس من بدايه البرنامج ستلاحظ قسم الكود وبعده فراغ وهي الاصفار
وبعدين القسم الأول من البيانات وبعده فراغ هذه الفراغات للتقسيم
ولهذا فإن الحجم الفعلي للقسم يساوي القسم بدون الفراغ والحجم الوهمي يساوي القسم زائد الفراغ

1B:مؤشر إلى عنوان التحريك للقسم PointerToRelocations
1F:مؤشر إلى رقم السطر PointerToLineNumbers
23:رقم النقل للقسم NumberOfRelocations
25:عدد الأسطر NumberOfLineNumbers
هذه المعلومات خاصه للتبديل بين الأقسام
القيمه الإفتراضيه صفر

27:خصائص القسم Characteristics قسم شفره أو بيانات أو قسم متحرك و للكتابه أو غيره
وهكذا مع كل الأقسام


وبعد الإنتهاء من المقدمه سنبدأ في النوع الأول من التواقيع لإصطياد الفايروسات وهو توقع pe
اسهل برامج antivirus تعتمد على حفظ قيم كل هذه المقدمات ويتم كتابت برنامج لمقارنه هذه
القيم في كل الملفات التنفيذية إذا تم إيجاد قيم متشابه يتم عرضه على انه فايروس

كتابه كود يقارن الثلاث مقدمات بسيط جدا وبالتحديد في لغه السي توجد تعاريف تدل على كل
مقدمه وهي المتغيرات التاليه
مجموعات متغيرات تمثل مقدمه dos
PIMAGE_DOS_HEADER DosHeader;
مجموعة متغيرات تمثل مقدمه pe
PIMAGE_NT_HEADERS PEHeader;
مجموعة متغيرات تمثل مقدمه Section
PIMAGE_SECTION_HEADER Section;

بناخذهم مثال خطوة بخطوة , اولا استخدام PIMAGE_DOS_HEADER DosHeader
ابدأ وانسخ الفايروس الخاص بنا virus.exe إلى الدرايفر C بمعنى C:\virus.exe
وبعد ذلك نريد حفظ توقيع مقدمه dos للفايروس بمعنى حفظ قيم المقدمه بالرمز hex
من خلال olly إنسخ اول 28 بايت وتدل على مقدمه الدوس وبعد ذلك أحفظهم في متغير بلغة السي
بهذا الشكل

BYTE DosHdrSignature[]=”\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xFF\xFF\x00\x00″
“\xB8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00”;

بهذه الطريقة نكون عرفنا توقيع لمقدمه dos للفايروس وطريقه التشييك على الملفات التنفيذية بسيطة
هذا كود لداله scan virus

BYTE DosHdrSignature[]=”\x4D\x5A\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xFF\xFF\x00\x00″
“\xB8\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00”;

BOOL StartScan(void)
{
HANDLE hFile;
void *pMem;
BYTE MemBlock [4096];
pMem = &MemBlock[0];
PIMAGE_DOS_HEADER DosHeader;
DWORD ReadBytes;

// إنشاء مقبض قرائة للملف التنفيذي
hFile=CreateFile(“c:\\virus.exe”, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY, NULL);

if(hFile==(HANDLE)-1){// مقارنه إذا كان الملف موجود او لا
MessageBox (NULL,”## found virus.exe .. ok ##”,”error”,MB_OK);
return 0;
}
// قرائه مقدمه الدوس للملف
ReadFile(hFile, pMem, sizeof(IMAGE_DOS_HEADER),
&ReadBytes, NULL);

DosHeader = (PIMAGE_DOS_HEADER) pMem;
// مقارنه توقيع مقدمه الملف مع التوقيع الذي قمنا بحفظه ويدل على الفايروس
if(memcmp(DosHeader,DosHdrSignature,128)==0)
MessageBox (NULL,”## found virus.exe .. ok ##”,”ok”,MB_OK); // نعم الملف هو الفايروس
else
MessageBox (NULL,”can’t found virus in c:\\”,”error”,MB_OK); // لا الملف ليس الفايروس

CloseHandle(hFile);
return 0;
}

بهذا الكود نكون قد تحققنا من خلال مقدمه الدوس ان الملف virus.exe هو الفايروس الذي نبحث عنه او لا

2- إستخدام مقدمه pe لفحص الفايروس PIMAGE_NT_HEADERS
بنفس الفكره السابقه نحفظ قيمة hex الكامله لمقدمه pe للفايروس ونخزنها في برنامج antivirus بإسم PEHdrSignature
لاحظ في هذا المثال كيف سنقوم بإستخراج بدايه بيانات pe للملف التنفيذي من خلال معلومات مخزنه في مقدمه dos
لو راجعت بدايه الموضوع ستتذكر هذا السطر
18: علامه تدل على بدايه كتله ذاكريه DOS_TablOff وفي مثالنا الكتله الثانيه هي pe
ويرمز لهذا البايت في لغه السي DosHeader->e_lfanew وهو متغير من ضمن متغيرات DosHeader

الكود التالي لفحص مقدمات pe و dos

BOOL StartScan(void)
{
HANDLE hFile;
void *pMem;
BYTE MemBlock [4096];
pMem = &MemBlock[0];
// متغيرات مقدمه dos
PIMAGE_DOS_HEADER DosHeader;
// متغيرات مقدمه PE
PIMAGE_NT_HEADERS PEHeader;

DWORD ReadBytes;
// إنشاء مقبض لقرائه الملف
hFile=CreateFile(“c:\\virus.exe”, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY, NULL);

if(hFile==(HANDLE)-1){// التشييك إذا كان الملف موجود في القرص او لا
MessageBox (NULL,”## found virus.exe .. ok ##”,”error”,MB_OK);
return 0;
}
//اول قرائه لمقدمه الدوس في بدايه الملف
ReadFile(hFile, pMem, sizeof(IMAGE_DOS_HEADER),
&ReadBytes, NULL);

DosHeader = (PIMAGE_DOS_HEADER) pMem;

//
// تحريك مؤشر القرائة إلى مقدمه pe
SetFilePointer (hFile,(LONG)DosHeader->e_lfanew,NULL,FILE_BEGIN);
ZeroMemory(pMem,4096);

// تنفيذ تعليمه قرائه لقرائه مقدمه pe
ReadFile(hFile, pMem, sizeof(IMAGE_NT_HEADERS),
&ReadBytes, NULL);

PEHeader = (PIMAGE_NT_HEADERS) pMem;
// مقارنه مقدمه pe للملف مع مقدمه توقيع الفايروس الذي نبحث عنه
if(memcmp(PEHeader,PEHdrSignature,sizeof(IMAGE_NT_HEADERS))==0)
MessageBox (NULL,”## found virus.exe .. ok ##”,”ok”,MB_OK); // نعم الملف هو الفايروس من خلال مقارنه pe
else
MessageBox (NULL,”can’t found virus in c:\\”,”error”,MB_OK); // لا الملف ليس الفايروس

CloseHandle(hFile);
return 0;
}

وبعد هذي الامثله شو رايك بموضوع كتابه anti virus اكيد بتكون شغله سهله ؟!

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

توجد طرق وأساليب كثيرة وهي ما يميز برنامج مقاومه عن آخر فمثلا توجد طرق البحث العشوائي
وهذا النوع جيد فمثلا يتم إختيار 100 بايت كتوقيع هذه ال 100 بايت موزعه في كل البرنامج
فمثلا بايت في سطر 1 وبايت في سطر 14 وبايت 25 وبايت 5000 وبايت في نهايه الملف
هذه الطريقه فائدتها ان البحث عن الفايروسات يكون اسرع بكثير من بحث المقدمات
شوف هذا المثال

BOOL StartScan(void){
HANDLE hFile;
HANDLE MemFile;
void *pMem;
DWORD size;
// إنشاء مقبض للملف
hFile=CreateFile(“c:\\virus.exe”, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY, NULL);

if(hFile==(HANDLE)-1){// التحقق من وجود الملف
MessageBox (NULL,”## found virus.exe .. ok ##”,”error”,MB_OK);
return 0;
}
// إستخراج حجم الملف
size=GetFileSize(hFile,NULL);
// إنشاء تخطيط للملف في الاذكرة
MemFile=CreateFileMapping(hFile,NULL,PAGE_READONLY,
0,0,NULL);
if(MemFile==NULL)
return 0;

// بداية الفحص العشوائي للفايروس
int i=0;
if(size>200){
// نقل 200 بايت إلى الذاكرة
pMem=MapViewOfFile(MemFile,FILE_MAP_READ,
0,0,200);
//مقارنه البايت 1و156و160و171و181و190و200
if(*((BYTE *)pMem+1) == ‘Z’)
i++;
if(*((BYTE *)pMem+156)==0x21)
i++;
if(*((BYTE *)pMem+160)==0x28)
i++;
if(*((BYTE *)pMem+171)==0xA1)
i++;
if(*((BYTE *)pMem+181)==0x28)
i++;
if(*((BYTE *)pMem+190)==0x85)
i++;
if(*((BYTE *)pMem+200)==0x50)
i++;
}
if(i==7)// إذا كانت التوقيع العشوائي موجود في الملف نستنتج انه الفايروس
MessageBox (NULL,”## found virus.exe .. ok ##”,”ok”,MB_OK);
else
MessageBox (NULL,”can’t found virus in c:\\”,”error”,MB_OK);

// إغلاق المقابض
CloseHandle(MemFile);
CloseHandle(hFile);
return 0;
}

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

وبالتوفيق

الكاتب geek4arab

geek4arab

مواضيع متعلقة

التعليقات مغلقة