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

كتابة اول برنامج ببيئة 32bit

بدأه Xacker في 2 ديسمبر 2005 · 23 رد · 8,131 مشاهدة · في المواضيع المميزة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

ناقشنا في المرة الماضية كيف انه بامكاننا استعمال المقاطعا لكتابة برامج تقوم بتنفيذ اجرائيات معينة وفق دفع قيم معينة الى المكدس وطلب مقاطعة معينة من النظام (DOS).

مثالنا السابق كان عبارة عن برنامج يقوم بالتعامل مع الملفات النصية.. في هذا المقال سنقوم بكتابة نفس المثال السابق لكن ليعمل تحت بيئة 32bit وبالتالي فاننا سنقوم في هذا المقال باستخدام ما يدعى API اختصارا لـ Application Program-ming Interface.

كلنا يسمع بهذا المصطلح API لكن قلة يعرفون مامعناه بشكل صحيح .. اذن دعونا في البداية نتعرف على ما سنقوم باعتماده في بيئة 32bit..

ما هي API؟

API هي عبارة عن مجموعة تعاريف تبين الطرق التي بواسطتها يقوم برنامج ما بالتخاطب مع الاخر. ان احدى الغايات الاساسية من الـ API هو توفير مجموعة من الوظائف المشتركة. بالتالي فان المبرمجين يستطيعون استغلال هذه الوظائف مما يوفر عليهم الوقت للبدء بكتابة كل شئ من البداية.

اذن ناتي الى تلخيص الفكرة العامة للـ API بانها مجموعة القواعد او الوظائف التي من خلالها يستطيع المبرمجون توفير الوقت والجهد اللازم للقيام بعمل ما, كرسم دائرة على الشاشة, عن طريق استخدام احدى هذه الوظائف بتمرير قيم معينة اليها وطلبها من النظام للتنفيذ -- مما يسمح للتطبيقات بالاشتراك بقاعدة وظائف معينة لا تخرج عنها الامر الذي يسهل بالتالي امكانية نقل هذه التطبيقات من جهاز كمبيوتر لاخر نظرا لان هذه القواعد ستكون موجودة بدون شك على الجهاز الاخر.

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

لكن اين توجد هذه الوظائف؟

نظرا لان هذه الوظائف ستكون مشتركة بين جميع البرامج فان المبرمجين قد عكفوا على توفير طريقة تمكنهم من حفظ هذه الوظائف في مكان واحد بحيث تستطيع جميع البرامج استخدام هذه الوظائف في نفس الوقت وبدون اي جهد اضافي يذكر, وهذا ما ادى الى ظهور ما يسمى DLL اختصارا لـ Dynamic Link Library - فمكتبات الربط الديناميكية هي الاصل الذي يحوي على وظائف الـ API المطلوبة لتشغيل برنامجك ان كان مكتوبا لبيئة 32bit - هناك ما يسمى kernel32.dll, user32.dll, comdlg32.dll الخ.. كل هذه المكتبات تم توفيرها وتم تقسيم الوظائف الى مجموعات بحيث اخذت كل مكتبة ربط مجموعة من هذه الوظائف بحيث تكون منسقة مع بعضها البعض.

اذن كانت الغاية الرئيسية من وراء DLL هو توفير بيئة يستطيع من خلالها المبرمجون حفظ اجرائيات هامة من برامجهم, او حفظ وظائف الـ API فيها, اي حفظ كل ما قد يحتاجه المبرمج في اكثر من برنامج (فقد يضطر المبرمج الى استخدام اجرائية معينة في اكثر من برنامج وبالتالي لم يعد مضطرا الى اعادة كتابة هذا الجزء للبرنامج الجديد - يكفي ان يحفظ هذه الاجزاء في مكاتب DLL ويقوم باستدعائها من اي برنامج عند اللزوم عن طريق API).

قد يخطر للقارئ الان السؤال التالي, بما ان DLL ظهرت لتقوم بتجميع وحفظ API حسب الحاجة, هذا يعني ان البرنامج بالاصل لم يعد يحوي على هذه الـ API فكيف له ان يقوم بما يقوم به من وظائف, كيف له بالاصل ان يصل الى وظيفة معينة في الـ DLL, الا يحتاج الى API؟

الجواب هو نعم, فهذا الامر لا يحل من قبل المبرمجين وانما يقوم به المجمع الذي تستخدمه, فانت عندما تريد ان تقوم بكتابة تطبيق 32bit فانك تطلب من المجمع ان يوفر لك امكانية استخدام الوظيفة الفلانية من مكتبة الربط الفلانية ويقوم هو بالتالي باجراء طلب من مكتبة الربط لاستخدام هذه الوظيفة مما يسمح لك باستخدامها متى شئت في البرنامج حتى ولو طلبتها عند نهاية التنفيذ فان المجمع قام بوضع البيانات اللازمة لطلب هذه الوظيفة من مكتبة الربط ضمن بيئة الملف التنفيذي ويبقى على الـ loader الخاص بالويندوز القيام بملئ الفراغات الخاصة بعناوين الوظائف في ما يسمى IT اختصارا لـ Import Table او جدول الوارد. وبالتالي فان برنامجك عندما يطلب هذه الوظيفة فانه سيستخدم هذه العناوين المخزنة فيه.

ارجو ان تكون الفكرة واضحة وساحاول ان اقوم بتزويد شرح شبه مفصل عن الـ loader الخاص بالويندوز وكيف يقوم بعمله لاحقا.

دعونا نبدا بكتابة برنامجنا:

عند البداية في كتابة اي برنامج اسمبلي (واي برنامج بشكل عام) عليك ان تقوم بتحليل الخطوات اللازمة للتنفيذ, ففي برنامجنا الذي سنقوم بكتابته سنقوم بمناقشة كيفية استخدام دوال API اليوم دون الحاجة الى استخدام واجهة للبرنامج, اي ان برنامجنا سيكون برنامج محجم كثيرا حيث سيقوم "تقريبا" بنفس الخطوات التي قام بها برنامجنا الذي كتبناه لـ 32bit (وباء بفشل التنفيذ لتجاوزه الطول المسموح لتطبيقات 16bit :P) -- السبب الذي اقول من اجله "تقريبا" هو اننا لن نستخدم واجهات GUI (Graphical User Interface) لاختيار مثلا ان نقوم بانشاء ملف بدلا من فتحه, سيقوم برنامجنا فورا بما ان العملية ستكون اسهل بالنسبة لتطبيقات 32bit, سيقوم بفحص المسار الحالي للبرنامج ليبحث عن ملف باسم ثابت محدد في احد المتغيرات المعرفة في البرنامج, فان وجده قام بفتحه لقراءة طول معين من البايتات منه, وان لم يجده قام بانشائه وكتابة بعض البايتات الثابتة المحددة ضمن البرنامج فيه -- سنقوم ايضا بالقاء الضوء على بقية الدوال التي تشبه في عملها الخدمات (او الوظائف) التي استخدمناها (طلبناها) من مقاطعة 21h وذلك تمهيدا للمقال القادم الذي سيتناول توسيع عمل البرنامج ليتناول تصميم الواجهات المرئية سواء بلغة الاسمبلي دون الاستعانة باي برنامج خارجي او بعمل resource وربطها مع الملف التنفيذي.

فاذن برنامجنا لليوم سيقوم بـ: 1- البحث في المسار الحالي عن ملف معين وليكن test.txt

2- في حال كان الملف موجودا فتح الملف لقراءة اول 10 بايتات منه مثلا ويعرضها برسالة على الشاشة, وان لم يكن موجودا يقوم بانشائه وكتابة سلسلة نصية ما فيه.

3- اغلاق البرنامج.

الموضوع بسيط, ولن يحتاج الى وقت طويل للفهم.. دعونا اذن نبدا في تعريف بنية الملف التنفيذي الخاص بـ 32bit عندما نريد كتابة مثل هذا البرنامج.

سنقوم باستخدام RadAsm مع Masm32 ويفترض هذا المقال انك تعرف كيف تضيف masm الى قائمة المجمعات التي يدعمها radasm.

ماذا نحتاج لمعرفته عن تطبيقات 32bit؟

(ماخوذ من مقال Iczelion)

تعمل تطبيقات 32بت في ما يسمى النمط المحمي الذي كان متوفرا منذ ظهور i286. لكن i286 اصبح قديما الان. لذا سيكون اهتمامنا مركزا على i386 وما لحقه من معالجات. يقوم نظام ويندوز بتشغيل كل تطبيق 32بت في ذاكرة افتراضية منفصلة. هذا يعني بان كل تطبيق 32bit يملك مقدار عنونة حتى 4GB !. مع ذلك, هذا لا يعني ان كل تطبيق 32بت يملك ذاكرة فيزيائية تصل الى 4GB, فقط ان البرنامج يستطيع العنونة لحدود تصل الى هذا المقدار. فيما يخص شكل الذاكرة المعنونة ففي 32بت لم يعد يهمنا نوع الذاكرة التي سيحتاجها برنامجنا فكل ما نملكه هو شكل واحد من انماط العنونة وهي الـ flat memory. لم يعد هناك مقاطع ملزمة بـ 64k. هذا يعني انك لم تعد بحاجة الى التلاعب بقيم مسجلات المقاطع segment registers.

لننظر الان الى بداية ترويسة اي كود برنامج 32bit لنناقش الامور غير الواضحة فيه, ان كنت تملك اي كود 32بت اطلع عليه وستجد ما يشبه التالي:

.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.386

يعد هذا السطر موجه للمجمع والذي يخبر المجمع بان يقوم باستخدام تعليمات المعالج i386. طبعا بامكانك استخدام .486, .586 لكن الافضل ان تلتزم بهذا المعالج.

.model flat, stdcall

يقوم السطر .model الذي هو عبارة عن توجيه directive للمجمع يخبره فيه بان يقوم باستخدام نمط العنونة flat والذي لا نملك سواه تحت بيئة 32bit.

بالنسبة لـ stdcall فهذا يخبر المجمع ايضا بكيفية تمرير البيانات, من اليمين الى اليسار, او من اليسار الى اليمين, هل تذكر مبدا LIFO؟ الامر "تقريبا" مشابه لهذا المبدا, فالمعطيات في بيئة 16بت تملك نوعين من التحويل, C و PASCAL, بالنسبة لـ C فان تمرير البارامترات يتم من اليمين الى اليسار وبالتالي فان البارامتر الى اقصى اليمين يتم تمريره اولا الى المكدس right most, للتوضيح اكثر افرض انك تريد استدعاء الوظيفة test التي تملك 3 بارامترات (int first_param, int second_param, int third_param) وبالتالي حسب صيغة C فان التمرير والاستدعاء يكون بالشكل:

push third_param
push second_param
push first_param
call test
add  sp, 12           ; adjusts the stack

وبالتالي ترى بانه كما تم تعريف المعطيات في C فان البارامتر الذي يقع الى اقصى اليمين وهو البارامتر الثالث قد تم دفعه اولا الى المكدس, بشكل عام هذا هو الشكل الذي ستصادفه في معظم تطبيقات 32بت.

فيما يخص صيغة PASCAL فهي عكس C تماما حيث يتم دفع المعطيات من اليسار الى اليمين وهذا الامر مستخدم في تطبيقات 16بت نظرا لانه يقوم بتوليد احجام اصغر للبرامج. فيما يخص عبارة stdcall الان فهي عبارة ان صيغة هجينة بين C و PASCAL حيث يتم تمرير المعطيات من اليمين الى اليسار بينما يكون امر الاستدعاء مسؤولا عن اعادة موازنة المكدس وهذه الصيغة حصرية الاستخدام على ويندوز.

include / includelib

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

option casemap: none

هذا السطر يدل Masm على ان اسماء الوظائف حساسة لحالة الاحرف اي ان وظيفة exitprocess تختلف عن ExitProcess (لا تنسى ان اسمبلي تشترك مع C في كيفية تقبل حالة الحروف بين كبيرة وصغيرة لكن ASM تملك بعض المرونة في هذا الخصوص).

الان ماذا بقي لدينا للبدء بكتابة التطبيق؟

كما في تطبيقات 16بت, كنا نقوم بتعريف المقاطع التي نريد استخدامها فيه, لكن فيما يخص 32بت فلم يعد هناك حاجة لهذا الامر فتوجيه model اخذ عن عاتقنا مهمة تعريف اسماء المقاطع ولم يبق لدينا الا الاستخدام الصحيح لهذه المقاطع.

.DATA و .CODE

في تطبيقات 32bit كل ما نحتاجه هو مقطعين هما .DATA وقد سبق الحديث عنه في مقالات سابقة, و .CODE والذي سيحوي على التعليمات الخاصة بالبرنامج. في تطبيقات 16بت لو لاحظت كنا نقوم بتعريف البيانات ضمن مقطع .CODE ونقوم باستخدام تعليمة JMP لتخطي هذه البيانات الى بداية التعليمات الصحيحة للتنفيذ, في 32بت هذا الامر مرفوض, لا يمكنك ان تقوم باستخدام بيانات ضمن مقطع الكود لكن طبعا يمكنك ان تطلب من المجمع ان يقوم بتخزينها لاحقا عند القيام بتشكيل الملف التنفيذي في مقطع الكود (احدى اشكال الحماية الغبية :P), ايضا لم تعد هناك حاجة لاستخدام تعليمة JMP في بداية المقطع لان بدايته ستكون اول تعليمة تنفيذية تريد طلبها من البرنامج..

هناك امر نسيت ان اذكره بخصوص inlcude و includelib, فيما يخص هذين التوجين فكما ذكرت فانهما ضروريان لطلب الوظائف من مكاتب الربط لكن ايضا بدون استخدام include ...kernel32.inc مثلا فانك ستبقى قادرا على استخدام الوظيفة المطلوبة لكن لن يعود بامكانك استخدام الشكل invoke لطلب هذه الوظيفة وستضطر لاستخدام الشكل العادي (Push param1, Push param2, Push param3, CALL Func)

دعونا نعود الان للتعرف على الوظائف (دوال API) التي سنحتاجها:

تجدون على الرابط التالي: http://spiff.tripnet.se/~iczelion/files/win32api.zip ملف بسيط يحوي على تقريبا جميع دوال API التي قد تحتاجونها, طبعا هذا الملف قديم وجرى احداث بعض التعديلات على هذه الوظائف فمنها من لم يعد مدعوما من قبل بعض الانظمة والاخر تم تعديل امور بسيطة فيه.. كل هذا يمكن ايجاده ان كنت تملك مكتبة MSDN فان لم تملكها يمكن مراجعة معلومات عن اي وظيفة عن طريق مكتبة MSDN عبر موقع مايكروسوفت: http://msdn.microsoft.com

بالنسبة لما سنقوم باستخدامه من دوال API فهم التالي: دالة (او وظيفة -- يختلف المبرمجون العرب في التعريب -- انا اطلق عليها الاسمين في اوقات غير محددة ويمكنك ان تطلق عليها الاسم الذي تريد لانها معروفة من شكلها) CreateFileA (اسم الدالة ضمن مكتبة MSDN او في win32api.hlp سيكون بدون حرف الـ A في نهايته -- حرف الـ A هذا يدل على ان الدالة ظهرت مع انظمة 32bit -- بعض الدوال تتطلب وجود هذا الحرف للتنفيذ والبعض الاخر لا تحتاجه وسنوضح الامر في وقته) + دالة ReadFile + دالة CloseHandle + دالة MessageBox.. اعتقد ان هذه هي الدوال التي سنحتاجها فقط (نظريا - اي ان هناك دوال نحتاجها لبدء تنفيذ الملف بشكل صحيح واخرى لانهاء البرنامج بشكل صحيح).

دالة CreateFile:

تستخدم هذه الدالة في فتح او انشاء ملف واعادة مقبض الملف لاستخدامات لاحقة.

الشكل العام لها هو التالي:

HANDLE CreateFile(

    LPCTSTR lpFileName,	// pointer to name of the file 
    DWORD dwDesiredAccess,	// access (read-write) mode 
    DWORD dwShareMode,	// share mode 
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,	// pointer to security attributes 
    DWORD dwCreationDistribution,	// how to create 
    DWORD dwFlagsAndAttributes,	// file attributes 
    HANDLE hTemplateFile  // handle to file with attributes to copy  
   );

في الحالات العادية معظم هذه البارامترات تحمل القيمة NULL حيث انها لا تهمنا, ما نحتاج الى اعداده بشكل صحيح هو بارامتر الاسم, بارامتر خصائص الوصول, بارامتر خصائص الملف عند الانشاء...

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

invoke CreateFile, addr lpFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL

ما يتغير من هذه البارامترات هو البارامتر lpFileName والذي يشير الى اسم الملف المراد الوصول اليه.

البارامتر dwDesiredAccess والذي يحمل احدى قيمتين: GENERIC_READ/WRITE

البارامتر dwShareMode ويحمل احدى اربع قيم لكننا في معظم الاوقات كما يظهر الكود السابق نحتاج الى الوصول الى الملف بغرض القراءة والكتابة في نفس الوقت لذا فاننا نقوم بتحديد اكثر من خيار بفصلهم بالمحرف "|".. في radasm سنقوم باستخدام المعامل "and" بدلا من هذا المحرف حيث لا يمكن استخدام "|".

البارامتر dwCreationDistribution تملك اكثر من خيار اكثر ما نستخدمه هو CREATE_NEW او OPEN_EXISTING

البارامتر dwFlagsAndAttributes يحدد خصائص الملف المراد انشاؤه كما ورد في مثالنا الخاص بـ 16بت.

فيما يخص البارامترات الاخرى فيذكر الملف win32api.hlp انها تستخدم في حالات خاصة وبالتالي في غير هذه الحالات فانها تحمل القيمة NULL.

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

اذن كما راينا فان استخدام هذه الدالة ليس بالامر الصعب, لكن كيف نقوم بالعادة باستدعاء اي دالة في MASM32 ؟

هذا السؤل يحمل اجابتين, في masm32 الاصلي فانك ملزم بالشكل (push param3 - push param2 - push param1 - call FunctionName) بينما في masm32 المعدل من قبل _Huntch فقد تم كتابة ماكروات تسمح باستخدام الشكل (Invoke FunctionName, param1, param2, param3) -- هل تذكر صيغة C و باسكال؟

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

اذن بفرض انك قمت باجراء التعديلات الصحيحة ليعمل masm مع radasm نقوم بفتح ملف جديد في radasm عن طريق Ctrl+N او File -> New File.. لن اعرض الان البنية الكاملة للملف التنفيذي لان هناك بعض الدوال التي سنتعرف عليها بعد قليل والتي سنحتاجها في البداية.

لاحظ كيف ان RadAsm يوفر امكانية التحديد التلقائي للدالة التي تقوم بكتابة اسمها وكيف انه يقوم بعرض ايضا الشكل العام لاستدعاء هذه الدالة او اي دالة اخرى.. مثلا, FindFirstFile.

01_12_05_07_10_30_1133493030ex1.gif

01_12_05_07_12_35_1133493155ex_.gif

لاحظ كيف اننا نقوم بالاشارة الى اسماء label البيانات التي قمنا بحجزها في .DATA عن طريق استخدام ADDR والتي تشير الى عنوان الـ RVA (Relative Virtual Address) الخاص بهذه البيانات.

هذا هو الشكل العام الذي سنقوم باستخدامه لتعريف واستدعاء وظائف API, ولا تختلف اي دالة عن الاخرى في الاستدعاء بل في كيفية تعريف بعض البارامترات وخصوصا ما يتعلق بدوال الشبكات وخلافه.

الان ننتقل الى الوظيفة الثانية..

دالة ReadFile:

غالبا ما تستخدم هذه الدالة مع CreateFile حيث تنفذ في حال تم اعادة مقبض للملف ان وجد, تستخدم هذه الدالة لقراءة كمية من البيانات من الملف المحدد بمقبضه. تملك هذه الدالة الشكل العام التالي:

BOOL ReadFile(

    HANDLE hFile,	// handle of file to read 
    LPVOID lpBuffer,	// address of buffer that receives data  
    DWORD nNumberOfBytesToRead,	// number of bytes to read 
    LPDWORD lpNumberOfBytesRead,	// address of number of bytes read 
    LPOVERLAPPED lpOverlapped  // address of structure for data 
   );

يحدد البارامتر hFile مقبض الملف الذي قمنا بفتحه بواسطة CreateFile, يحدد البارامتر lpBuffer المخزن الذي سيتم تخزين البايتات المقروءة فيه, يحدد البارامتر nNumberOfBytesToRead عدد البايتات المراد قراءتها من الملف والتي يتم قراءتها ابتداء من العنوان المحدد بمؤشر الملف الذي يدل على بدايته, يحدد البارامتر lpNumberOfBytesRead عدد البايتات المقروءة فعليا من الملف, واخيرا, البارامتر الاخير يمكن ان يحمل القيمة NULL في حال لم يكن الملف قد تم الوصول الى مقبضه من خيار FILE_FLAG_OVERLAPPED فان كان الاخير هو المستخدم وجب تحديد buffer ليتم تخزين بيانات بنية التراكب فيها.

نستخدم الدالة السابقة في برنامجنا بالشكل التالي:

invoke ReadFile, addr hfile, addr fbuffer, 10, addr bnum, NULL

اود الاشارة هنا الى البارامتر الثالث, كما نرى فاننا نقوم بتحديد عدد البايتات التي نريد قراءتها اما بشكل مباشر بقيمة عشرية مثلا, او يمكننا طبعا استخدام متحول يحمل هذه القيمة ونشير اليه بواسطة addr bytes_2_read مثلا, ايضا فيما يخص البارامتر الرابع, يجب ان نحدد بارامتر يتم فيه تخزين عدد البايتات التي تم قراءتها من قبل ReadFile.

دالة CloseHandle:

نستخدم هذه الدالة في اغلاق مقبض الملف الذي قمنا بانشاءه في البداية (او فتحه) للوصول اليه.. لا نستخدم هذه الدالة الا بعد الانتهاء من التعامل مع الملف.

الشكل العام لها بسيط جدا:

BOOL CloseHandle(

    HANDLE hObject  // handle to object to close  
   );

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

invoke CloseHandle,addr hfile

دالة MessageBox:

هذه الدالة من اكثر الدوال شيوعا في الاستخدام في البرمجة, اعتقد ان استخدامها واضح من الاسم وهو اظهار رسالة ما على الشاشة, سنستخدمها في برنامجنا لنقوم باظهار عدد من المحارف التي قمنا بقراءتها من الملف على الشاشة, استخدامها العام هو التالي:

int MessageBox(

    HWND hWnd,	// handle of owner window
    LPCTSTR lpText,	// address of text in message box
    LPCTSTR lpCaption,	// address of title of message box  
    UINT uType  // style of message box
   );

يحدد في البارامتر الاول مقبض النافذة الاب التي تعود الرسالة اليها, في حال تحديد القيمة NULL لهذا البارامتر فان الرسالة تعود الى النافذة النشطة حاليا, البارامتر الثاني يشير الى النص المراد اظهاره على الشاشة, البارامتر الثالث يشير الى عنوان لهذه الرسالة, اخيرا, البارامتر الاخير يشير الى شكل هذه الرسالة اي ما سيظهر فيها من ازرار, OK فقط, YES / NO, Retry / Ignore / Abort .. الخ, بشكل شائع يستخدم الشكل OK فقط لهذه الرسائل..

invoke MessageBox, NULL, addr lpText, addr lpCaption, MB_OK

لربما قد ترتبك فيما يخص اسماء المتحولات التي قمت باستخدامها وبين الشكل العام للاستخدام.. ان اسم المتحول lpText مثلا لا يشير الى انك ملزم بهذا الاسم, يمكنك استخدام ما شئت من اسماء للاشارة الى النص الذي قمت بوضعه في .DATA لكني فضلت استخدام هذا الشكل فقط لتوضيح كيفية الاستخدام لا اكثر.

ماذا نحتاج للقيام به كبداية لانشاء ملف EXE؟

ان فتح ملف EXE بشكل صحيح واغلاقه يختلف عما كنا نقوم به فيما يخص تطبيقات 16بت حيث ان تطبيقات 32بت لها شكل معين في الاستدعاء.. عندما نقوم بانشاء ملف EXE وفتحه فان اول دالة يتم تنفيذها هي دالة GetModuleHandleA -- هذه الدالة غير ضرورية دوما, قد لا تريد استخدامها ويمكنك ذلك لكن الغاية منها توفير بعض المعلومات الضرورية من اجل استدعاء وظائف اخرى في البرنامج. بعد ان يتم تنفيذ هذه الدالة يتم الانتقال في التنفيذ الى الدالة التي تليها وهي تكون الدالة التي تريد منها اظهار رسالة او قراءة ملف او عمل اخر تحدده انت.. وفي اخر البرنامج يتم الانهاء بواسطة دالة تسمى ExitProcess -- لناخذ الان نظرة اقرب على هاتين الدالتين..

دالة GetModuleHandle:

تستخدم هذه الوظيفة في ارجاع مقبض ملف تم تخطيطه في الذاكرة -- الاستخدام العام لهذه الدالة هو:

HMODULE GetModuleHandle(

    LPCTSTR lpModuleName  // address of module name to return handle for  
   );

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

invoke GetModuleHandle, NULL

دالة ExitProcess:

تستخدم هذه الوظيفة في انهاء واغلاق البرنامج وازالته من الذاكرة - تملك هذه الدالة بارامتر واحد وستلاحظ ان اغلب التطبيقات ان لم تكن جميعها تقوم باستخدام القيمة "0" لهذا البارامتر والذي يقوم باستخدام القيمة الافتراضية لانهاء التطبيق - بينما كان من المفترض (وليس شرطا) ان يتم استخدام الدالة GetExitCodeProcess والتي تعيد القيمة اللازمة لانهاء التطبيق.

تنظيم البرنامج وكتابته:

سنقوم كما ذكرت في بداية المقال باستخدام Masm32 v8.2 مع RadAsm لذا قم بفتح مشروع جديد في radasm (او ملف asm جديد فقط ان اردت) وستكون الخيارات هي التالية:

1- بعد ان نختار File -> New Project نقوم بتحديد المجمع المطلوب وهو masm ونحدد خيار Win32 App (no res)

2- نقوم بتحديد اسم للمشروع المطلوب واسم لمجلد المشروع المطلوب وليكن "MyFirst_Win32Asm_Project"

3- لن نقوم باختيار اي بنية خاصة اوتوماتيكية للملف المطلوب لذا يمكن تجاوز نافذة Template باختيار none وباي حال فان (no res) تلغي وجود اي template للبرنامج :P

4- فيما يخص الملفات التي نريد انشاءها للمشروع سنبقي فقط على الخيارات Asm و Inc

5- في النافذة الاخيرة Make سنبقي على الخيارات كما هي ونختار Finish لانشاء الملفات المطلوبة.

ستلاحظ ظهور ملفات باسماء MyFirst_Win32Asm وبلاحقتي .asm و .inc في نافذة المشروع project الى اليمين.

فيما يخص برنامجنا فاننا نقوم بكتابته في الملف الذي يحمل اللاحقة .asm (طبعا [:) اما ملف .inc فنستخدمه لكتابة اسماء المكتبات التي نطلب منها وظائف فيه وللبيانات المستخدمة في البرنامج.. فقط للتنظيم :)

فيكون برنامجنا بالشكل التالي:

.386
.model flat, stdcall
option casemap: none

include MyFirst_Win32Asm.inc

.code
main proc	far

	invoke GetModuleHandle, NULL; return the program handle
	mov	handle, eax    ; store the handle in 'handle'
; try to open an existing file, if it fails we'll simple show an error message that the file doesn't exist.. for the time being :)
	invoke CreateFileA, addr file_name, GENERIC_READ and GENERIC_WRITE, FILE_SHARE_READ and FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
	cmp eax, -1   	 ; see if the file exists, '-1' = 'FFFFFFFFh' so we are checking if the file doesn't exist
	je	@no_file
; if the JE instruction was ignored then the file exists and EAX holds the handle
	mov	file_handle, eax  ; so we store the handle in 'file_handle'
	invoke ReadFile, file_handle, addr input_buffer, 25, addr bnum, NULL
	test eax, eax    ; see if failed to read the contents
	je	@no_read
	invoke CloseHandle, file_handle; close the file we just opened to read
	invoke MessageBox, NULL, addr input_buffer, addr asm_is_gr8, MB_OK
	jmp	_@

@no_file:
	invoke MessageBox, NULL, addr no_file, addr error, MB_OK
	jmp	_@
@no_read:
	invoke MessageBox, NULL, addr no_read, addr error, MB_OK
_@:
	invoke	ExitProcess, 0

main endp

end main

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

ماذا لو اردنا تنقيح البرنامج؟

لنفرض اني واجهت خطا ما عند تشغيل برنامجي, ولم ادر اين او ما السبب, فاردت تنقيحه بواسطة برنامج مثل olly.. في برنامجنا سيظهر التنقيح بالشكل التالي:

01_12_05_07_14_03_1133493243debug.gif

ما يميز تطبيقات الاسمبلي عن غيرها انها تعمل على مبدا what-you-write-is-what-you-get, دون زيادة او نقصان, لاحظ في الصورة السابقة كيف ان الكود الذي قمنا بكتابته تم عرضه كما هو الامر الذي يسهل على المبرمج تدارك اخطائه وفهم البرنامج بدون اي تعقيد..

01_12_05_07_17_17_1133493437win3_asmgr8.gif

01_12_05_07_14_54_1133493294size.gif

اخبرني الان "Isn't assembly just gr8؟" :)

اسئلة؟

MyFirst_Win32Asm.rar

1

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#2

السلام عليكم

كيف الحال .. صارلي زمان مقطوع عن مواضيعك يا أخي (بسبب الدروس في الكلية )

جزاك الله خيرا يا أخي ، جاري التحميل ، واذا في شي راح ارجعلك اكيد

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#3

هلا اخي الاخير زمانه والله اشتقنا لتعليقاتك وتفاعلك معنا.. اعتقد من عدد المتفاعلين يمكنك ان تحزر ما اعني :D

تحياتي لك ولكل محبي الاسمبلي ;)

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#4

السلام عليكم

صبرا يا أخي

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

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

1

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#5

الله الله يا أستاذي ، بصراحة روووووووعة

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

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

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

في بادئ الامر تكلمت عن ال API بصورة عامة ، اخي العزيز هل ال API واحدة ، يعني هي هي مع الفيجوال سي او بقية اللغات ؟، يعني هل استطيع القول ان ال API تابعة لـ OS وجميع اللغات تعمل عليها (طبعا تختلف من نظام الى اخر كما ذكرتَ)

وبخصوص ال DLL ، يعني ممكن القول بأنها مجموعة من دوال ال API ؟ طيب كيف ممكن ان اعرف كل DLL ما تحوي من API ؟

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

طبعا انا بأنتظار شرحك عن ال loader كما وعدتنا ، بارك الله فيك .

ندخل الى البرنامج ،

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

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

بالتأكيد سأقوم بقراءة البرنامج مرتين وثلاث حتى أُلِم بكل جوانبه !

اخي الكريم اول ما اطلبه منك هو وصلة لتحميل masm ، انت افترضت .. وانا للأسف لا املكه ..

طيب هل من طلب اخر (بس لاتزعل وضوج (هاي بلهجتنا )) يعني لا تغضب ، هل من الممكن ان تقوم بأعداد درس خاص عن masm كيفية اعداده واساسيات التعامل معه ( مع الصور ) ، حتى تكون الشغلة كاملة من مجاميعوا .

بس سؤال على دوال ال API بصورة عامة :

الشكل العام للدالة هل هو ثابت ، يعني هل من الممكن تغير اسماء الباراميترات ام هي ثابتة ، وكذلك الامر بالنسبة لأستدعاء الدالة .

وهنالك امر ذكرته لم افهم ما تقصد به

""" هناك امر نسيت ان اذكره بخصوص inlcude و includelib, فيما يخص هذين التوجين فكما ذكرت فانهما ضروريان لطلب الوظائف من مكاتب الربط لكن ايضا بدون استخدام include ...kernel32.inc مثلا فانك ستبقى قادرا على استخدام الوظيفة المطلوبة لكن لن يعود بامكانك استخدام الشكل invoke لطلب هذه الوظيفة وستضطر لاستخدام الشكل العادي (Push param1, Push param2, Push param3, CALL Func) """

بارك الله فيك .. وانا بأنتظار المزيد

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#6

أيه الجمال ده موضوع أكثر من رائع

جزاك الله خير

Nothing to mention except that I am Muslim

Using your brain is not bad as you think

My Blog

logo.jpg

#7

اخي العزيز شكرا على الدرس الرائع

نسخت الكود في RadASM

(كود البرنامج في .asm وكود الملفات الاخرى نسخته في .inc )

قمت بعمل assembling بنجاح لكن عند عمل linking ظهرت المشكلة التالية

LINK : fatal error LNK1181: cannot open input file "MyFirst_Win32Asm.res"

فما السبب؟

#8

ساجيب عن الاسئلة بما يتوفر لي من الوقت (بعد الكم اللي اكلناه اليوم بالامتحان :( )

اقتباس
اخي العزيز هل ال API واحدة ، يعني هي هي مع الفيجوال سي او بقية اللغات ؟، يعني هل استطيع القول ان ال API تابعة لـ OS وجميع اللغات تعمل عليها (طبعا تختلف من نظام الى اخر كما ذكرتَ)

الـ API ثابتة لانها بالاصل مستوردة من ملفات الـ dll الخاصة بالنظام, بالتالي اي لغة تستخدم الدوال ذاتها مع اختلاف شكل الاستدعاء فقط.. في اسمبلي استخدم invoke او الـ push/call التقليدية.. في C اقوم بالتصريح عنها ونستدعيها بشكل اخر.. وهكذا

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

ليس بالشكل الدقيق.. ملفات الـ DLL هي مكاتب مشتركة تحوي الدوال فيها ليتم استخدامها من اي تطبيق يحتاجها دون الحاجة الى اعادة اختراع العجلة كما يقال.

اقتباس
طيب كيف ممكن ان اعرف كل DLL ما تحوي من API

راجع MSDN / استخدم LordPE مثلا

اقتباس
هل من الممكن توضيح ولو بصورة مختصرة عن ال Handle

فقط اعتبر ان للنافذة مقبض, للزر مقبض, لشريط التحريك مثلا مقبض.. يتم الوصول الى كل هذه الامور عن طريقه ... ساقوم بالتوضيح بشكل اوسع لاحقا باذن الله.

تحميل masm من هنا: http://win32asm.cjb.net - بالنسبة لـ masm قم بتحميله واختبر قوائمه واخبرني ان وجدت اي شئ معقد فيه, masm ليس كـ radasm على سبيل المثال يحوي الكثير من القوائم والخيارات متعددة الاستخدام, استخدامه بسيط جدا لكن باذن الله ساذكر استخدامات اهم العناصر فيه (تكرم عينك (بلهجتنا :D))

بالنسبة للبارامترات انت تزود المجمع بالقيمة الخاصة بالبارامتر وليس بالاسم بالتالي, ما تقراه في MSDN او اي مرجع عن lpFilePointer على سبيل المثال ليس الا دليل عن نوع البارامتر ويمكنك ان تقوم باسناد القيمة المتوافقة مع هذا البارامتر سواء بقيمة نصية او عددية او خيار ما او سماحية ما..

بالنسبة للاستفسار عن include و includelib .. استخدامهم في برنامجك يجعل المجمع يطلب من البرنامج ان يقوم باستيراد العناوين الخاصة بكل وظيفة مستخدمة فيه ويخزنها فيما يسمى الـ FirstThunk و الـ OriginalFirstThunk ليتم طلب هذا العنوان بدل طلب الوظيفة مباشرة وبالتالي يجعل البرنامج يعمل على كل نظام تشغيل... يمكنك كتابة وتجميع البرنامج السابق بدون ادراج ملف kernel32 لكن في هذه الحالة ستكون مضطرا لاستخدام الشكل التقليدي للاستدعاء Push param1, push param2, call function_name .. في هذه الحالة العنوان تكون مطلقة وقد يؤدي هذا الى حدوث مشاكل مع بعض الانظمة فقد لا يعمل البرنامج او بعض وظائفه.. راجع مقال كتبته تجده في قسم المواضيع المتقدمة الخاصة بالقرصنة عن قرصنة ملف كتبه CuTedEviL لمجموعة CODE اقوم فيه بعمل reverse للتطبيق لاضافة زر والتعديل على الكود باضافة شفرات اخرى وادراج وظائف جديدة غير مدرجة واعادة اصلاح الملف ليحوي زرين يعملان بوظيفة معينة.. ستفهم ما اعنيه بالكلام السابق بشكل افضل عندها..

اقتباس
LINK : fatal error LNK1181: cannot open input file "MyFirst_Win32Asm.res"

راجع الخيارات يا علي.. انت اخترت خيار يحوي على resource.. نحن هنا نريد تطبيق win32(no res)

بالتوفيق للجميع واعذروني عن عدم التواجد والتقصير..

تحياتي

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#9
اقتباس
بعد ان نختار File -> New Project نقوم بتحديد المجمع المطلوب وهو masm ونحدد خيار Win32 App (no res)

هنا المشكلة...لا يوجد لدي خيار no res

#10

لا اذكر الخيارات بالضبط صرلي حوالي 3 اسابيع ما لمست اي كود اسمبلي.. باي حال, تحتاج الى خيار win32 .. لا اعتقد ان radasm كان يحوي على خيار اخر لتطبيقات الـ 32.. لم اعد اذكر بالضبط, باي حال قم بالغاء تفعيل الخيار الخاص بالـ res عندما تختار صيغة المشروع وحاول. اعتقد ان الحل هو ذلك.

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#11

شكرا على الرد اخي الكريم ..

لنا عودة ما أن تنتهي الامتحانات

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#12

بارك الله بيك اخي درس ممتاز جدا

اقتباس
الاخير زمانه:

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

#13

السلام عليكم ...

طالت الغيبة !!!!

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

اخي Xacker ،

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

بدأت من ها هنا ..

انا بس حابب اسأل على البرنامج ،

انا نفذت هذا الدرس في برنامج يدعى ..

Assembly Studio

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

وبعدين نفذت البرنامج بأستخدام MASM32 و RadASM و الحمد لله ،

يعني ماكو فرق ؟؟

طبعا وجدت خيارات RadASM اكثر من Assembly Studio

،،،

انا فقط اريد ان اعرف ما هي علاقة ال MASM32 مع ال RadASM ،

يييعني انا قمت بكتابة وتنفيذ البرنامج في ال RadASM ،

لماذا في بعض دروسك تذكر كتابة البرنامج في MASM32 ؟

يعني مثلا جملة كهذه ..

اقتباس
بعد ان يتم كتابة البرنامج بواسطة Masm32 (منفردا دون RadAsm)

ارجو توضيح هذه النقطة ،

لكي ابدأ بداية صحيحة

،

لدي سؤال واحد على الكود ،

ما معنى far في

Main proc far

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#14

مهمة RadASM وغيره مجرد واجهات لتضيف بعض ميزات اخرى على masm كاضافات خارجية وواجهات اوسع لاستخدامات اخرى غير متوفرة في masm .. يمكنك الاستغناء عنه دون مشاكل لو اردت

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

اما بخصوص near و far,

near تسمح لك بالانتقال ضمن اجزاء وظيفة او اجرائية ما بين اللافتات بواسطة jmp مثلا لكنها لن تسمح لك بالانتقال الى وظيفة خارجية من ضمن اجرائية رئيسية للبرنامج على سبيل المثال

لذا ان لم تكن تريد ان تتعب نفسك في مسالة مفروغ منها استخدم far دوما

ويمكنك مراجعة الصفحة التالية لمزيد من المعلومات التفصيلية:

http://www.arl.wustl.edu/~lockwood/class/c...ml#HEADING1-133

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#15

السلام عليكم ،

جزاك الله خير اخي الكريم على المرور والاجابة ،،

راح اتعبك وياي :rolleyes:

بالنسبة للعبارة المقتبسة ،

على ما اذكر كانت في درس التعامل مع ال resource

/index.php/topic/264448-%D8%A7%D9%84%D8%A8%D8%AF%D8%A7%D9%8A%D8%A9-%D9%85%D8%B9-%D8%A7%D9%84%D8%A7%D9%86%D8%AF%D8%B1%D9%88%D9%8A%D8%AF/

 

اني وان كنت الاخير زمانه ---- لأتِ بما لم تستطعه الاوائلُ

#16

اها, ما قصدته ان RadASM يوفر لك امكانية تشكيل resource بدلا من استخدام msvc لذا لست بحاجة الى الخوض في غمار التصريحات هنا وهناك في ملف الـ rc بينه وبين masm وغيره..

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#17

جميل جدا أخوي xacker....

وفقك الله $$$

;أخوك خالد

#18

أخى Xacker

تبعاً لما تفضلت بشرحه نفذت البرنامج التجريبى الذى تفضلت وأرفقته ولكن كما اننى جديد لا أعرف كيفة تشغيل البرنامج وتحويله إلى ملف تنفيذى فكلما حاولت عمل Compile Rc أو Assemble من قائمة Make يظهر لى خطأ كما فى الصورة

أرجوا التوضيح ولك ألف شكر

post-101744-1204234585_thumb.jpg

كل من فى الوجود يطلب صيداً :::: غير ان الشباك مختلفات

#19

هل قمت بتنصيب masm32 ؟

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

#20

يلزمك ضبط الاعدادات للـRadASM

اختر Option->Set Paths ثم اضبط مسار المربع الأحمر كما بالصورة الى مجلد الـMasm32 لديك واضبط الباقي كما بالصورة بالضبط

768293-1416.png

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#21
GamingMasteR كتب:
يلزمك ضبط الاعدادات للـRadASM

اختر Option->Set Paths ثم اضبط مسار المربع الأحمر كما بالصورة الى مجلد الـMasm32 لديك واضبط الباقي كما بالصورة بالضبط

768310-1396.png

اشكرك أخى GamingMasteR على الرد ولكن لم أجد كل من الملفات الأتية ML.exe , RC.exe, Link.exe

بالرغم انى حملت ال باكج كامل ... فهل اتثاقل عليك لطلب العون وأكون شاكر جداَ

كل من فى الوجود يطلب صيداً :::: غير ان الشباك مختلفات

#22

إذن كما قال الأستاذ Xacker :

اقتباس
هل قمت بتنصيب masm32 ؟

او حمله مرة اخرى ربما يكون ناقص لديك فهو خفيف ...

راجع هذا الدرس يشرح كيفية تنصيب WinASM+RadASM مع MASM32 بالتفصيل لـzool@nder من الفريق العربي للهندسة العكسية :

http://www.at4re.com/Tutz/Masm32_RadAsm_WinASM.Howto_install.and.config.rar

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#23

اشكرك أخى GamingMasteR

تمت عملية التحميل بنجاح المشكلة كانت عندى فى ال Windows

شكراً جزيلاً

كل من فى الوجود يطلب صيداً :::: غير ان الشباك مختلفات

#24

مجموعة مقلات مفيده هو ده الشرح انا كان نفسى افهم يعنى ايه model flat, stdcall من اول ماابتديت اشتغل اسمبلى

ايه النشاط ده كله (كلام كنت هقوله لو شفت المقلات دى فى 2005 )

With method and logic one can accomplish anything.

— Agatha Christie, Poirot Investigates, 1924

مدونتى

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