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

تعلم برمجة الوندوز بالأسمبلر

مغلق
بدأه chik في 11 سبتمبر 2003 · 19 رد · 6,616 مشاهدة · في لغة Assembly لأنظمة 16, 32, 64 بت
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم,

على ما لاحظت في هدا المنتدى أن بعض الإخوان لديهم دراية بلغة الأسمبلر ويتساءلون عن برمجة الوندوز.

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

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

الأدوات المطلوبة MASM32 – VC++6 وشيء من الدماغ والصبر.

إدا قبل الإخوان يمكن أن نبدأ فيما قريب إن شاء الله.

في انتضار آرائكم ومقترحاتكم أقول لكم إلى اللقاء.

#2

جزاك الله كل خير و أعطاك الصبر للبدأ على هذا الموضوع .

جاهز إن شاء الله . أعتقد أنه يمكنك البدأ للأهميه . (خير البر عاجله ) :-)

#3

السلام عليكم,

أولا لاحظت أنه ليس ممكن هنا وضع ملفات للتحميل وهدا يصعب شيئا ما الأمور لأن بعض المرات مشروع ما قد يتطلب عدة ملفات . وهده الملفات قد وضعتها في رابط آخر ويمكنكم تحميا الأمثلة Sample1.zip الدي سنتكلم عليه الآن من هدا الرابط :

http://www.aldroob.com/showthread.php?s=&t...&threadid=22927

سأعطي في هذه البداية مثالا بسيطا يبرز لنا نافذة من نوع MessageBox من س++ والأسمبلر حتى نرى نقط التشابه وكيف نستعمل APIفي هاذين النوعين.

سأبدأ بتحليل س++ :

1 #include <windows.h>

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

2LPSTR Caption=

في هذين السطرين ندرج معطياتنا وهنا نعني عنوان ومحتووى MessageBox

3 int WINAPI WinMain(

هذه تدل أين يبدأ برنامجنا وهي تعادل main هنا لا نحتاج Parametrs وسنرجع إليهم حين نأخذهم بعين الإعتبار ووهنا نقلتها كما هي من MSDN .

4 هنا نبدأ ب MessageBox وإذا أطللنا على MSDN نرى ما يلي

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 );

نرى أنها تحتاج 4 Parametrs

hWwnd وهو هاندل النافذة وووسنعطيها صفر كاعتبار أنه ليس لها نافذة أم

lpText و lpCaption هو العنوان والمحتوى

والأخير هو نوع النافذة التي نريد انظروا MSDN لتروا مختلف الأنواع

5 هنا نغادر البرنامج ب

VOID ExitProcess( UINT uExitCode // exit code for all threads );

أما فيما يخص الأسمبلر في الأول نعطي نوع Processor Instructions هنا نعطي نوع 386 ونعطي أيضا نوع الذاكرة Flat وهنا يمكن أن نأخذ كل هذا كموديل لبرامجنا ويمكن أن نقرأ عنها في ملف المساعدة ل MASM

1 مثل ما سبق ملفات Include نزيد windows.inc الذي يحوي عدة معطيات مثل MB_OK وهنا نزيد أيضا user32.inc و kernel32.inc لأن MessageBox توجد في user32 أما ExitProcess فتوجد في kernel32 كما نزيد ملفات .lib المرافقتان لهما في س++ لم نكتب كل هذا لأن الكل كان مذكور في windows.h .

2 .data هنا تبدأ منطقة المعطيات وسنعطي كالسابق العنوان والمتوى

3 .code هنا تبدأ منطقة الكود ووهي بمثابة main

4 بعد هذا عندنا

invoke MessageBox, 0,Offset Text, Offset Caption, MB_OK + MB_ICONEXCLAMATION

هنا نرى التشابه الكبير نكتب المكرو invoke وو المسج بوكس يكتب في نفس الشكل مثل س++ ونلاحض نفس الشيء فيما يخص ExitProcess . لكي نلخص إذا كانت عندنا Api باسم Func نكتبها في س++ كما يلي :

Func(a,b,c,d,e) ففي الأسمبلر نكتبها

Invoke Func,a,b,c,d,e

وفي الحقيقة فإن هذه الماكرو تفعل العمل التالي:

push e

push d

push c

push b

push a

call Func

نرى أن parameters تضع في الستاك على العكس يعني الأخير يطرح الأول وهنا ارجعو إلى مثالنا وغيروا invoke MessageBox

ب :

push MB_OK

push Offset Caption

push Offset Text

push 0

call MessageBox

وتلاحظون أنه يعطينا نفس النتيجة.

وللتجميع يمكنكم استعماا الملف make.bat وسنرجع للحديث عنه في مرة أخرى وإذا غيرنا اسم ملف chik1 يجب التغيير أيضا chik1 داخل هذا الملف.

أما int 3 هي الآن غير شغالة وسنرجع إليها حين نستعمل Debugger

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

في انتظار آرائكم أقول لكم إلى اللقاء.

#4

جميل جدا اخي CHIK والفرق واضح من خلا الحجم حيث ان حجم الملف بالاسمبلي اصغر عشر مرات من السي بلس بلس

شكرا جزيلا وجميل جدا و نتمني اكثر حيث ان الاسمبلي عباره عن كهف مظلم بالنسبة لى

#5

السلام عليكم,

هنا سأقترح مثالا لإستعمال نافدة من نوع DialogBox .

هنا سأعطي المثال ب س++ وفي المرة القادمة سأعطي نفس الشيء بالأسمبلر. ويمكنكم من الآن التفكير في هدا.

يمكنكم تحميل المشروع كاملا من هدا الرابط.

http://www.aldroob.com/showthread.php?s=&p...95472#post95472

نشغل Visual C++ نختار File New Win32 Application نعطي الإسم والمسار ثم OK . نعطي الإسم مثلا ExpApi . بعد هذا نختار Empty Project و OK .

بعد أن نتم من المشروع نختار Project Add To Project New C++ Source File نعطي الإسم مثلا ExpApi .

بعد هدا سنضيف النافذة , نختار Insert Resource Dialog New بعد هذا تظهر لنا نافذة فيها 2 باتن نختار كل واحد منهما ونزيلهما بالضغط على Delete . بعد هذا نضيف EditBox و 2 Button . بعد هذا نسجل هذه النافذة في نفس المسار تحت اسم script1.rc . بعد هذا نختار View Id=resource symbol هذا يعطينا الأرقام التي أعطيت للنافذة ولكل ما فيها نرى مثلا IDD_DIALOG=101 هذا بالنسبة للنافذة . IDD_EDIT1=1000 ل EditBox و IDC_BUTTON= 1000 و 1001 للبقية . يمكن أن تكون عندكم أرقاما مختلفة يجب فقط أن نعرف رقم كل أداة عندنا.

بعد هذا نرجع إلى ملفنا ExpApi.cpp فهو الآن صفحة بيضاء ونبدأ البرمجة.

#include <windows.h> نضيف ملف header .

LPSTR text="a text … " نعطي ما سنكتب .

نضيف السطر الآتي وسنتحدث عنه من بعد

BOOL CALLBACK DialogProc(

HWND hwndDlg, // handle to dialog box

UINT uMsg, // message

WPARAM wParam, // first message parameter

LPARAM lParam // second message parameter

); هنا أخذتها كما هي من MSDN

هنا سنعطي نقطة بدء البرنامج WinMain هذه الدالة هي التي سيبدء بها برنامجنا :

int WINAPI WinMain(

HINSTANCE hInstance, // handle to current instance

HINSTANCE hPrevInstance, // handle to previous instance

LPSTR lpCmdLine, // pointer to command line

int nCmdShow // show state of window

)

لها 4 Parameters الأول هو الوحيد الذي سنحتاجه في برنامجنا هذا وهو في الحقيقة يعطينا موقع البرنامج في الذاكرة . الثاني هو كالأول لكن بالنسبة إذا كان البرنامج شغالا من قبل. الثالث هم Parameters التي يمكن أن نعطيها مع بدء البرنامج . والأخير هو يحدد كيف ستظهر النافذة كبيرة مصغرة … وإذا لم نفهم كل معنى هذا ليس مشكلا فسوف نتطرق لكل واحد حين نحتاجه في البرامج القادمة إن شاء الله.

لبرامج من النوع DialogBox سوف نحتاج الدالة DialogBoxParam .إذا أطللنا على MSDN تعطينا:

int DialogBoxParam( HINSTANCE hInstance, // handle to application instance LPCTSTR lpTemplateName, // identifies dialog box template HWND hWndParent, // handle to owner window DLGPROC lpDialogFunc, // pointer to dialog box procedure LPARAM dwInitParam // initialization value );

ونحن سنكتبها كالتالي

DialogBoxParam(hInstance,MAKEINTRESOURCE(101),NUL

L,DialogProc,NULL);

البارمتر الأول هو hInstance الذي تعطيه لنا WinMain

الثاني هو رقم النافذة 101 ونستعمل الماكرو MAKEINTRESOURCE لتحول لنا الرقم إلى بارامتر مفهوم.

الثالث أعطيناه NULL لأن نافذتنا ليس لها أب أو أنها تعتبر هي الأب أو الأساسية.

الرابع وهو من نوع CALLBACK وهو عنوان الدالة التي تتكلف بتحليل ودراسة Events . مثلا حين نقوم بشيء على نافذتنا كالكليك مثلا فإن الوندوز سيبعث بإنذار إلى النافذة ليخبرها بأن شيئ حصل ويعطيها رقم Event وكل هذا سيقدم إلى هذه الدالة. ونحن قد أعطينا مفهومها في الأول لأننا نذكرها هنا ولكن سنتعامل معها من بعد. نعلم الكومبايلر بوجودها .

هذا كل ما سنضع في WinMain أما البرمجة الحقيقية فستكون في DialogProc .

BOOL CALLBACK DialogProc(

HWND hwndDlg, // handle to dialog box

UINT uMsg, // message

WPARAM wParam, // first message parameter

LPARAM lParam // second message parameter

)

إذن هذه هي الدالة التي ستقوم بتحليل النافذة . وهي لها 4 بارامتر :

الأول وهو hwndDlg أو ما يسمى ب هاندل النافذة والآن يمكن أن نعتبر هذا كبارامتر يمكن أن يعرف نافذة ما.

الثاني وهو رقم Event الذي وقع للنافذة وهي كثيرة ويمكن التعرف عنها في MSDN وهي تبدأ ب WM_ .

الثالث والرابع هما بارامتر إضافيان وهما يتغيران حسب Event .

هنا سنكتب if(uMsg==WM_CLOSE)

{

ExitProcess(0);

return 1;

}

حين يصل إلى دالتنا الإنذار WM_CLOSE وهذا يحصل حين نريد إقفال النافذة ننهي البرنامج ب ExitProcess .

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

سنضيف الآن ما يتعلق بنقر Button 1 2.

if(uMsg==WM_COMMAND)

{

if(LOWORD(wParam)==1001)

{

SetDlgItemText(hwndDlg,1000,"An Example From - Chik - مثال من عند");

return 1;

}

if(LOWORD(wParam)==1002)

{

ExitProcess(0);

return 1;

}

} حين ننقر Button فإن الوندوز ترسل إنذار من نوع WM_COMMAND . وحين يتم هذا فإن البرامتر wParam يحمل في Word المنخفض (LOWORD) رقم Button الذي حصل عليه النقر

if(LOWORD(wParam)==1001) هنا نحاول أن نعرف إذا كان button1 الذي يحمل رقم 1001 وإذا كان ذلك سنرسل كتابة ما إلى EditBox والحامل للرقم 1000 .سنستعمل

SetDlgItemText(hwndDlg,1000, text);

هذه الدالة ترسل كتابة ما في text إلى الأداة رقم 1000 والكل في النافذة التي تحمل الهاندل hwndDlg وهذه ليست إلا نافذتنا.

نعمل نفس الشئ مع Button2 وهنا نخرج من البرنامج.

هذا البرنامج مكتوب على هذا النحو ليس بالأنيق ولكن فضلته هكذا ظانا أنه ربما يسهل الفهم أكثر . فيمكن مثلا أن نضيف تلملف resource.h إلى مشروعنا وبدلا من أن نكتب الأرقام نكتب IDD_DIALOG إلى غير ذلك.

وكمثال يمكنكم أن تزيدوا EditBox آخر , نكتب في هذا وحين نقوم بالنقر تنقل الكتابة في EditBox الآخر باستعمال الدالة GetDlgItemText التي تقرأ الكتابة من نافذة ما داخل DialogBox .

أتمنى أن تجدوا إفادة في هذا وفي انتظار آرائكم واقتراحاتكم أقول لكم إلى اللقاء.

#6

رائع جدا اخي chik

بس اذا ممكن يكون الدرس على ملف وورد مرفق مع المثال او استعمال خاصيه الكود بالمنتدي عشان تسهل قراءة الكود

تحياتي والمعذره على على الاقتراح

#7

السلام عليكم,

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

يمكنكم تحميل هذا المثال كاملا من الرابط التالي :

http://www.aldroob.com/showthread.php?s=&t...&threadid=22927

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

نشغل فيجوال س++ ونقوم ب insert resource ثم نختار dialog new تظهر لنا نافذة فيها 2 button نزيلهما ونضيف EditBox و 2 Button . بعد هذا ننقر فوق النافذة باليمين ونغتار Propreties وحين تفتح هذه الأخيرة نبدل خانة ID حيث غالبا ما نجد فيها IDD_DIALOG… نغيرها باسم في هذا المثال سميتها CHIK " " نكتب الإسم بين الشرطتين. مثل السابق نرى الأرقام المعطية لكل أداة وذلك باختيار view id=resource symbol في حالتي هذه IDC_EDIT=1000 و IDC_BUTTON=1001 والآخر 1002 نسجل هذا في المسار الذي سنشتغل فيه ونختار تسجيله تحت ملف .res ونعطيه اسم مثلا هنا script1.res .

هنا نكون انتهينا بما يتعلق بالنافذة فلنذهب إلى البرمجة.

.386

.model flat, stdcall

option casemap :none ; case sensitive

include c:\masm32\include\windows.inc

include c:\masm32\include\user32.inc

include c:\masm32\include\kernel32.inc

includelib c:\masm32\lib\user32.lib

includelib c:\masm32\lib\kernel32.lib

هذه كالسابق ونتأكد أن مسار masm32 هو صحيح عندنا أو نغيره .

WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

هنا ندرج الدالة المكلفة بدراسة events نفس الشيء مثل س++ .

WndProc اسم الدالة يمكن أن نعطيها أي اسم نريد.

PROTO تعني prototype.

:DWORD نوع parameter ونلاحظ أنه عندنا أربعة . رغم أنه في س++ أذنا هذه parameters من أنواع مختلفة hwnd,wparam.. وغيرها إلا أنها كلها من نوع 32 بايت أو double word.

.data

dlgname db "CHIK",0 ; إذا كنتم قد أعطيتم اسم آخر للديالوغ غيروه هنا

text db "An Example From - Chik - مثال من عند",0

hInstance dd 0

هنا نعطي المعطيات . الأول سيكون الإسم الذي أعطيناه للنافذة الثاني الكتابة التي سنبرزها والثالث هو سنحتاجه في البرنامج تذكروا hInstance في س++.

invoke GetModuleHandle, NULL

mov hInstance, eax

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

invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR WndProc,0

لا شيء يذكر فهذا مثل س++.

WndProc proc hWin :DWORD,

uMsg :DWORD,

wParam :DWORD,

lParam :DWORD

هنا الدلة WndProc وسنعطي اسماء لكل parameter .

أما البقية فهي مثل س++ .

ونلاحظ أن كثير من الماكرو قد سهلت الأمور مثل .if وغيرها.

في السطر الأخير عندنا xor eax,eax و return.

نريد أن نرجع صفر لذا قمنا ب xor eax,eax فهذه العملية ستقوم بوضع 0 في eax.

لبناء البرنامج يمكنكم استعمال الملف make.bat وأنا هنا لم أضع فيه إلا اللازم حتى نتمكن من فهمه فهو يحتوي على 3 اسطر الآتية وتأكدوا من مسار mas32 :

C:\MASM32\BIN\Cvtres.exe /machine:ix86 script1.res

C:\MASM32\BIN\Ml.exe /c /coff chik2.asm

C:\MASM32\BIN\Link.exe /SUBSYSTEM:WINDOWS chik2.obj script1.obj

السطر الأول سيمكن من إعطاء ملف .obj ل resource أو النافذة.

الثاني سيجمع الملف .asm ويعطينا الملف .obj للبرنامج.

والأخير سيجمع ويلاقي جميع الملفات .obj ليعطينا الملف .exe الأخير.

أتمنى أن يفيدكم هذا المثال وتكونوا قد لاحظتم التشابه الكبير.

إلى مثال آخر سأبقى أنتظر آراءكم واقتراحاتكم.

إلى اللقاء.

#8

السلام عليكم

لقد قرات المعلومات التي اعطيتني اياها اخي chik و لكن التطبيق عليها صعب لهذا

اريد driver printer مكتوب بلغة التجميع اين استطيع الحصول عليه ؟؟؟

تم تعديل هذه المشاركة بواسطة abood في 19 سبتمبر 2003 في 17:46

#9

السلام عليكم,

إلى الأخ abood هل تريد استعمال هدا على الدوس أو الوندوز.

سأرى ما يمكنني عمله.

إلى اللقاء.

#10

للرفع

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

لاادري اخي CHIK كيف اساعدك ولكن عدد زوار الموضوع احبطني حقيقه واخاف ان قله عدد الزوار يقلل من حماسك للموضوع وبالتالي نفقد الشي الكثير

#11

السلام عليكم

اخي chik شكرا لك على الاهتمام

لا يهم على دوس او على وندوز المهم ان يكون على الاسمبلي

و شكرا

#12

السلام عليكم,

في الرابط التالي ستجدون المشاريع كاملة للسيرفر والكلاينت بلغة س++ و الأسمبلر.

وأتمنى أن تروقكم الأمثلة .

http://www.aldroob.com/showthread.php?s=&t...&threadid=22927

كنت أود أن أذهب تدريجيا مع هذه الدروس إلا أني لاحظت اهتمام الإخوة ببرمجة Server & Client وها أنا سأعطي مثالا لهذا كالعادة ب س++ وبالأسمبلر ورغم أن الكثير يتخوف من هذا الأخير إلا أنكم سوف تلاحظون أن هناك تشابه كبير.

أولا يجب أن نعرف أننا سنستعمل بروتوكول TCP/IP لبرنامجينا.

دعنا الآن نتكلم بعجالة ماذا يحدث حين يكون عندنا سيرفر وكلاينت.

نعرف أن في ميدان هذا النوع من الإتصالات هناك ما يسمى ب port أو البوابات وعددها إذا لم تخدعني ذاكرتي حوالي 65000 منها ما هو مسجل مثل الباب 80 يستعمل ل http المعروف أو 21 ل FTP وغير ذلك والبقية يمكن استعماله لأغراض أخرى.

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

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

حين يتم هذا الإتصال يمكن أن يبديا الحديث بتبادل المعلومات مثل ما يحدث في التشات أو الميسنجر. وهنا أضيف أنه يمكن برمجة السيرفر لبعض COMMANDS ليعمل أشياءا أخرى كحذف ملف ما أو غير ذلك وهذه هي طريقة التروجينات. نقول مثلا لو أن الكلاينت يرسل كلمة del path\file فإن السيرفر سيمسح الملف المذكور أو نقول مثلا send path\file ليرسل إلى الكلاينت الملف المذكور إلخ…

والإتصال يكون بواسطة ما يسمى ب السوكيت SOCKETS وهذه بمثابة قناة التواصل بينهما أو الخيط الذي يكون مسؤولا عن هذا الإتصال.

ومثالنا يمكن أن نجربه على كمبيوتر واحد أو على الشبكة وأظن ان التجربة الأولى غالبا ما تكون على كمبيوتر واحد. نشغل السيرفر بعد ذلك نشغل الكلاينت هنا يجب أن نعطيه الإيبي لكمبيوترنا وإذا لم يكن عندنا أي إيبي مثلي يمكنكم الذهاب إلى الكنترول بانل ثم الشبكة واختيار TCP وهنا يمكنم إدخال أي إيبي فمثلا أنا أدخلت الرقو 1.2.3.4 إيبي عجيب أليس كذلك. ووإذا تمت الأمور كما يرام فستتم الإتصال ويمكنكم إيذاع واستقبال الكتابة بين الكلاينت والسيرفر.

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

هنا سنقوم بتحليل برنامج س++ للسيرفر.

مثل المثال السابق نقوم بإنشاء نافذة DialogBox اسمها "DLGSERVER" وإيقون اسمه "MYICON".لقد زدنا ملف <winsock2.h> وهو كافي إذ فيه جميع ما نحتاج وكما يجب أن نضيف ملف ws2_32.lib حتى تكون لدينا كل الأدوات لبناء برنامجنا. وكما نرى أننا زدنا 2 events خاصين WS_ACCEPT = WM_USER و

WS_REC= WM_USER + 1 وسوف نرى صلاحيتهما من بعد.

فيما يخص WinMain فلا شيئ جديد على المثال السابق وسنرى الآن الدالة المكلفة ب Events .

حين يبدأ تهيئ الديالوغ WM_INITDIALOG سنرسم الإيقون

HICON ico;

ico=LoadIcon(hins,"MYICON");

SendMessage(hwnd,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)ico);

نأخذ الإيقون أولا بإعطائه الهاندل للبرنامج ثم الإسم الذي اخترناه للإيقون. بعد ذلك نستعمل SendMessage لتخبر النافذة أننا سنقوم برسم الإيقون بإعطائها الرسالة WM_SETICON.

WSAStartup(0x101,&wsaData);

هذه تمكننا من إخبار وندوز أننا سنستعمل السوكيت لتهيء لنا المناخ المناسب.

soc=socket(AF_INET,SOCK_STREAM,0);

هنا نقوم بخلق السوكيت التي سنسميها soc وهي التي ستبقى في الإستماع. ولها ثلاث متطلبات ويمكن في غالب الأحيان استعمال نفس الشيء. الأول هو ما يسمى بالعائلة الثاني هو النووع والأخير هو البروتوكول.

socin.sin_family=AF_INET;

socin.sin_port=htons((u_short)11111);

soccin هي من نوع struct sockaddr_in ويجب ملؤها بخاصيات السوكيت التي نريدها. نعطيها مثلا النوع البوابة والإيبي إلا أن الإيبي لن نعطيها هنا في السيرفر لكنها أساسية في الكلاينت. و htons هي دالة مرادها أن تترجم لنا رقم البوابة المعروف عندنا إلى رقم تفهمه sockaddr_in .

bind(soc,(SOCKADDR*)&socin,sizeof(socin));

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

listen(soc,10) ;

وأخيرا ستبدأ السوكيت في الإستماع وتنتظر أي اتصال.

WSAAsyncSelect(soc,hwnd,WS_ACCEPT,FD_ACCEPT);

هذه تقوم بربط message خاص ب event خاص. وهذا ما ذكرت في البداية.

نعلم مثلا أننا حين ننقر button فإن وندوز ترسل message إلى النافذة المسؤولة هذا message هو WM_COMMAND حين تريد الكتابة ترسل WM_SETTEXT وغيرها. لكن هنا من سيدلنا مثلا أنه قد تم اتصال فيجب أن يكون عندنا event في هذا الحال هو FD_ACCEPT أو أن السيرفر قد قبل مكالمة وبين message في حالنا سميناه WS_ACCEPT وهذا إرسال خاص اخترناه نحن وللعلم هناك إرسالات خاصة بالوندوز تبتدأ من الصفر حتى 3FF بالهيكس والخاصة تبتدأ من WM_USER = 400. بخلاصة يمكن أن نقول أنه كلما قبل السيرفر أي مكالمة فإن الوندوز ترسل لنا إرسالا رقمه 400 هيكس. ونحن حين نتصل بهذا نعرف أنه قد تم قبول. وإذن فهذه الدالة تقوم بالربط بين كل هذا وهناك كما تتوقعون عدة Event قبول الإتصال استقبال معطيات إقفال مكالمة أو غير ذلك ويمكن أخذ ما نحتاجه في البرنامج.

shutdown(soc2,SD_SEND);

closesocket(soc2);

shutdown(soc,SD_SEND);

closesocket(soc);

WSACleanup();

EndDialog(hwnd,0);

حين ننهي البرنامج نعمل التنظيف بمحي وإزالة كل ما كنا قد خلقناه.

case WM_COMMAND:

if(LOWORD(wpa)==1002)

{

char ch[100];

int ll;

GetDlgItemText(hwnd,1001,ch,100);

ll=strlen(ch)+1;

send(soc2,ch,ll,0);

return 1;

}

حين ننقر زر send لإرسال الكتابة نقوم بأخذ ما كتبناه ونضعه في بافر ch نتعرف على طوله ونرسله على متن السوكيت 2 التي سنتكلم عنها لاحقا باستعمال الدالة send .

case WS_ACCEPT:

if (LOWORD(lpa)==FD_ACCEPT)

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

int sz;

sz=sizeof(socin2);

soc2=accept(soc,(SOCKADDR*)&socin2,(int *)&sz);

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

EnableWindow(GetDlgItem(hwnd,1002),1);

SetDlgItemText(hwnd,1003,"!!! CONNEXION ESTABLISHED !!!");

send(soc2,"!!! CONNEXION ESTABLISHED !!!",30,0);

WSAAsyncSelect(soc2,hwnd,WS_REC,FD_READ|FD_CLOSE);

حين يتم القبول نكتب رسالة تنبهنا بذلك ونرسل رسالة إلى الكلاينت .

وفي السطر الأخير سنختار أرسالا خاصا مرة أخرى وفي هذه الحالة سيخبرنا بوصول كتابة ما FD_READ أو أن الإتصال قد أغلق FD_CLOSE وكل هذا يرسل لنا ارسالا خاصا اسمه WS_REC.

case WS_REC:

if(LOWORD(lpa) == FD_READ)

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

cc=ioctlsocket(soc2,FIONREAD,&cmd);

if(cmd)

{

char ch[100];

cc=recv(soc2,ch,100,0);

SetDlgItemText(hwnd,1000,ch);

}cc=ioctlsocket(soc2,FIONREAD,&cmd);

if(cmd)

{

char ch[100];

cc=recv(soc2,ch,100,0);

SetDlgItemText(hwnd,1000,ch);

}

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

if(LOWORD(lpa) == FD_CLOSE)

{

EnableWindow(GetDlgItem(hwnd,1002),0);

SetDlgItemText(hwnd,1003,"!!! I AM WAITING !!!");

closesocket(soc2);

وفي الأخير إذا ما كسر الإتصال كمثل أننا أقفلنا السيرفر نقوم بإخبار الكلاينت بذلك.

هذا من جانب السيرفر أما من جانب الكلاينت فالأمور تقريبا متشابهة إلا في حالة accept فبالطبع الكلاينت لن يبقى في الإستماع وإنما يحاول الربط لذى فهو سيستعمل connect.

case 1001:

GetDlgItemText(hwnd,1000,ip,16);

soc=socket(AF_INET,SOCK_STREAM,0);

socin.sin_family=AF_INET;

socin.sin_port=htons((u_short)11111);

socin.sin_addr.S_un.S_addr=inet_addr(ip);

connect(soc,(sockaddr*)&socin,sizeof(socin));

WSAAsyncSelect(soc,hwnd,WS_CONNECT,FD_CONNECT);

حين ننقر connect سنأخذ IP للسيرفر نخلق السوكيت ونعطيها الخصائص وهنا نزيد الإيبي باستعمال الدالة inet_addr التي تحول إيبي معروف على النحو 1.2.3.4 إلى إيبي ل struct.بعد هذا نستعمل connect.

والبقية تلاحظون أنها متشابهة.

أما فيما يخص الأسمبلر فأظن أنه بدون تعليق كل ما قيل مسبقا يطبق على هذا الأخير ولقد حاولت أن آخذ اسماء المتغيرات نفسها حتى يبدأ الشبه كما هو.

وهنا أريد أن أعطي أو أعيد بعض المعطيات وهي أنه حين نستدعي دالة API فإذا كانت هذه الأخيرة ترجع شيئا ما فهذا يكون في eax . فعلى سبيل المثال حين نكتب في س++ :

soc=socket(AF_INET,SOCK_STREAM,0)

بما |أن الدالة socket في الرجوع تعطينا soc الذي نستخدمه فيما بعد ففي الأسمبلر نكتب كالتالي :

invoke socket,AF_INET,SOCK_STREAM,0

وبما أن الدالة ترجع في eax فإن هذا الأخير يحتوي إذن على علامة soc لذى نكتب mov soc,eax نكتب قيمة eax الناتج المرجع في soc .

وكذلك حين نستعمل الماكرو LOWORD في س++ فهذه الأخيرة تعطينا 16 بت الأولى لعدد يحتوي على 32 بت. فمثلا eax هو رجستر من 32 بت و LOWORD ل eax ليس هو إلا ax .

وفي الأخير أريد أن أظيف أنه في الأسمبلر يجب إضافة الملف ws2_32.inc وملف ws2_32.lib وهذان فيهما كل الدوال الخاصة بالسوكيت وإظافة أيضا masm32.inc و .lib لأننا استعملنا StrLen الدالة التي تعطينا طول كتابة ما.

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

وإلى اللقاء.

#13

السلام عليكم,

بعد برامج الكلاينت والسيرفر أقترح عليكم برنامج يعطينا بعض المعلومات عن كمبيوتر متصل بالنت. فيمكن أن نعطي IP للكمبيوتر الدي تريد أن نتعرف عليه والبرنامج يعطينا الأسم أو نعطيه ليبحث عن مجموعة من IP مثلا نريد أن نبحث الإيبيات ما بين 127.0.0.1 - 100 هنا سيبحث كل الإيبيات ما بين 127.0.0.1 و 127.0.0.100 كمثال كما يمكن أن نعطيه اسم الهوست والبرنامج يعطينا IP لهدا الهوست , مثلا نعطيه اسم www.microsoft.com أو microsoft.com والبرنامج يعطينا IP لهدا.

اليكم الكود كاملا ولكن يجب إضافة Resource للنافدة تضم على:

DialogBox

3 textbox

1 chekbox button

2 button

1 list box

1 static text على الأقل

كما يجب إعطاء الأرقام لكل هده الأدوات كما في البرنامج أو تغيير أرقام البرنامج بأرقامكم.

وكل من يريد الملفات كاملة يمكن أن يترك إيميله هنا.

وهدا الكود كاملا ب Masm32 وكل من يريد أي استفسار أو أي اقتراح سأكون رهن الإشارة إن شاء الله .

      .386
      .model flat, stdcall
      option casemap :none   


      include c:\masm32\include\windows.inc
      include c:\masm32\include\user32.inc
      include c:\masm32\include\kernel32.inc
      include c:\masm32\include\ws2_32.inc
      include c:\masm32\include\masm32.inc

      includelib c:\masm32\lib\user32.lib
      includelib c:\masm32\lib\kernel32.lib
      includelib c:\masm32\lib\ws2_32.lib
      includelib c:\masm32\lib\masm32.lib



        WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
        TreatResult PROTO :DWORD
        Chik    PROTO :DWORD
        
        
    .data
        dlgname       db "DLGHOST",0 
        hInstance     dd 0 
        theicon       db "MYICON",0 ;The Icon
        MIP           db 100 DUP(0) ;Buffer for the input IP
        MRange        db 5   DUP(0) ;Buffer for the range IP
        MRangeD       db 0          ;Value of the range   
        MResult       db 200 DUP(0) ;buffer for output result for the list
        MSearching    db "!!!!  Åääí ÇáÂä ÃÞæã ÈÇáÈÍË - ÔíÁ ãä ÇáÕÈÑ     !!!!",0
        MFinish       db "!!!!    áÞÏ ÇäÊåì ÇáÈÍË ÇáÂä    !!!!",0 
        Erro          db "!!!!    ÎØÃ Ýí ÇáÅíÈí Ãæ ÇÓã ÇáåæÓÊ    !!!!",0
        Caption       db " **  ÎØÃ ãÇ  **",0  
        StatMess      db "%d :  ãÚÇáÌÉ ÇáÑÞã ",0 ; Message for multi search
        MDef          db "0",0       ;default value of the range
        Espace        db " ",0  
        hst           hostent <>      ;structure hostent for the result of gethost
        wsaData       WSADATA  <>      ;;struct for the starting of winsock
        MChek         db 0             ;value of the chek button 0 not cheked
        Handle        dd 0             ;handle of the thread
        hw            dd 0             ;;value of hwnd
        ThreadID      dd 0             ;ID of the thread
        uu            db 4 DUP(0)      ;value of the inet address
        forme         db "== NAME : %s ==== IP : %d.%d.%d.%d ==",0   ;the forme of the output string
;***********************************************************                      
        IDC_SEARCH      EQU 1003 ;ID OF THE SEARCH BUTTON
        IDC_IP          EQU 1000   ;ID of IP textbox
        IDC_RANGE       EQU 1001   ;ID of the range text box
        IDC_CHEK        EQU 1002   ;ID of the check box button
        IDC_LIST        EQU 1004   ;ID of the list box
        IDC_MESSAGE     EQU 1006   ;ID of the message text box
        IDC_QUIT        EQU 1005   ;ID of the quit button
        IDC_STA         EQU 1007
        
    .code

start:



        invoke GetModuleHandle, NULL
        mov hInstance, eax
        
        invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR WndProc,0
        invoke ExitProcess,0


WndProc proc hwnd   :DWORD,
             msg    :DWORD,
             wpa    :DWORD,
             lpa    :DWORD
;***********  InitDialog  **********************      
      .if msg == WM_INITDIALOG
      
            invoke LoadIcon,hInstance,addr theicon
            invoke SendMessage,hwnd,WM_SETICON,ICON_BIG,eax
            invoke SetDlgItemText,hwnd,IDC_RANGE,addr MDef
            invoke WSAStartup,101h,addr wsaData
            mov eax,1
            ret
      .endif 
;***********  WM_CLOSE  ************************
      .if msg == WM_CLOSE
            invoke CloseHandle,Handle
            invoke WSACleanup
  invoke EndDialog,hwnd,0
      .endif


;**********  COMMAND  *****************************
        .if msg == WM_COMMAND
            mov eax,wpa
;**********  Click on the chek button **************
            .if ax == IDC_CHEK
                NOT MChek
                .if MChek==0
                    invoke GetDlgItem,hwnd,IDC_RANGE
                    invoke EnableWindow,eax,0
                .else
                    invoke GetDlgItem,hwnd,IDC_RANGE
                    invoke EnableWindow,eax,1
                .endif
                
                mov eax,1
                ret
            .endif
;***************  Click on ÎÑæÌ  button ****************            
            .if ax == IDC_QUIT
                invoke CloseHandle,Handle
                invoke WSACleanup
                invoke EndDialog,hwnd,0
                mov eax,1
                ret
            .endif
;*************** click on ÇÈÏÅ ÇáÈÍË  Button ***********            
            .if ax == IDC_SEARCH
                
                invoke SetDlgItemText,hwnd,IDC_MESSAGE,addr MSearching
                invoke SendDlgItemMessage,hwnd,IDC_LIST,LB_RESETCONTENT,0,0
                invoke GetDlgItemText,hwnd,IDC_IP,addr MIP,100
                invoke CreateThread,0,0,addr Chik,hwnd,0,addr ThreadID
            .endif

        .endif 
        
                          
                  

    xor eax, eax
    ret

WndProc endp
;****************************************************************
;*****  Chik Thread  ********************************************
; äÓÊÚãá ÇáËÑíÏ åäÇ ÍÊì íÚãá ÇáÈÍË Ýí ÇáãÃÎÑÉ æÍÊì áÇ äÔÚÑ Ãä ÇáÈÑäÇãÌ ãÊÌãÏ
Chik proc hwn   :DWORD
    mov al,Byte Ptr MIP
    .if al < '0'
        invoke MessageBox,hInstance,addr Erro,addr Caption,0
        ret
    .elseif al <= '9'
        invoke inet_addr,addr MIP
        mov DWORD Ptr uu,eax
        .if MChek == 0
            invoke gethostbyaddr,addr uu,4,2
            .if eax !=0
                invoke TreatResult,hwn
            .endif
            jmp TheEnd
        .endif
;********TREAT RANGE ADRESSES***************************************
        invoke GetDlgItemText,hwn,IDC_RANGE,addr MRange,5
        invoke a2dw,addr MRange
        mov MRangeD,al
ReDo:
        xor eax,eax
        mov al,byte ptr [uu+3]
        .if al > MRangeD
            jmp TreatEnd
        .endif
        push eax
        push offset StatMess
        push offset MResult
        call wsprintf
        invoke SetDlgItemText,hwn,IDC_STA,addr MResult
        invoke gethostbyaddr,addr uu,4,2
        .if eax !=0
            invoke TreatResult,hwn
        .endif
        inc byte ptr[uu+3]
        jmp ReDo
 TreatEnd: 
         invoke SetDlgItemText,hwn,IDC_STA,addr Espace
    .else
        invoke gethostbyname,addr MIP
        .if eax != 0
            invoke TreatResult,hwn
        .endif   
    .endif
 TheEnd:
    invoke SetDlgItemText,hwn,IDC_MESSAGE,addr MFinish
    xor eax,eax
    ret
Chik endp
;*****************************************************************
;*********** Treat the result
;Ííä äÚËÑ Úáì ÔíÁ åäÇ ÊÊã ãÚÇáÌÊå áíÙåÑ Ýí áÇÆÍÉ ÇáäÊíÌÉ
TreatResult proc hhwn  :DWORD
     mov dword ptr hst,eax
     mov esi,dword ptr hst
     assume esi:ptr hostent
     mov ebx,[esi].h_name
     mov esi,[esi].h_list
     mov esi,dword ptr [esi]
     xor eax,eax
     mov cx,word ptr [esi+2]
     mov al,ch
     push eax
     mov al,cl
     push eax
     mov cx,word ptr [esi]
     mov al,ch
     push eax
     mov al,cl
     push eax

     push ebx
     push offset forme
     push offset MResult
     call wsprintf
     invoke SendDlgItemMessage,hhwn,IDC_LIST,LB_ADDSTRING,0,addr MResult
     ret   
TreatResult endp
    
end start

وإلى اللقاء

#14

عمل رائع جدا ومميزما ادري وشلون نشكرك عليه

الجميل فى الموضوع انه جديد تماما ولايوجد اي كتب مطبوععه تتناول هالموضوع

#15

السلام عليكم,

لاحظت أن هدا المكان من المنتدى بدات تقل نقاشاته هده الأيام وسأعطي مثالا آخر هنا عن استعمال DLL ربما يبعث شيئا من الحيوية في منتدى الأسمبلي.

لقد قامت بعض النقاشات حول DLL في منتدى C-C++ انضر الرابط :

http://www.arabteam2000.com/ib/index.php?s...showtopic=34783

وأريد هنا أن أنقل هدا الموضوع إلى الأسمبلي .

أن Dll في برمجتها لا تختلف عن EXE مضمونا وهي تختلف ببساطة في الشكل.

إن DLL هي كدلك لها نقطة الدخول وهي تختلف عن مثيلتها في EXE وفي DLL فهي تستعمل ل Initialisation .

وهدا هو الهيكل لبناء مكتبة باستعمال Masm32

**** هده دائما كما هي

.386

.model flat, stdcall

option casemap :none

*** هنا نزيد الملفات الرأسية التي قد نحتاجها

include c:\masm32\include\windows.inc

;include c:\masm32\include\user32.inc

include c:\masm32\include\kernel32.inc

;includelib c:\masm32\lib\user32.lib

includelib c:\masm32\lib\kernel32.lib

** بداية الكود

.code

** تعريف نقطة بداية المكتبة وللمزيد من المعلومات يمكن أن نقرأها في MSDN

MainDll proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD

mov eax,TRUE

ret

MainDll Endp

** نكتب هنا ما نريده من الكود والدوال التي نريد تصديرها وننهي بالسطر التالي

End MainDll

بعد هدا نضيف ملف من نوع def. نكتب فيه الدوال التي نريد تصديرها وفي غالب الأحيان يكون كالتالي :

LIBRARY NameOfTheDll

EXPORTS Func1

Func2

Func3

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

هنا سنقول أنه عندنا مكتبة اسمها MyDll.dll وهي تصدر دالة اسمها Somme تستقبل رقمين وترجع المجموع فكيف سيمكن أن نستعمل هده الدالة من طرف برنامج آخر . في الأسمبلر يمكن أن نستعملها كاتالي:

invoke LoadLibrary addr filename

** filename اسم ومسار المكتبة التي سنستخدمها وهي ترجع الهاندل في eax إدا لم يكن أي خطء

.بعد هدا نستدعي ما يلي للتعرف على عنوان الدالة التي تهمنا :

invoke GetProcAddress ,eax,addr nameoffunc

eax هو الهاندل للمكتبة وقد أخد مما سبق و nameoffunc هو اسم الدالة. وإدا تم كل شيء على ما يرام فإن عنوان الدالة سيكون عندنا في eax .

وبعد هدا سنرسل الرقمين num1 و num2 إلى الدالة كالتالي:

push num1

push num2

call eax

وسيكون عندنا المجموع في eax .

في الملف المرافق تجدون مجلد Dll_Asm يحتوي على مثال بسيط ل DLL فيها دالتين Somme و Minus كل منهما يستقبلان عددين الأولى ترجع المجموع والثانية الفرق.

يمكن تجربتها باستعمال Visual Basic مثلا وسيكون كالتالي في الباسيك:

Private Declare Fuction Somme Lib "Path\Asm_Dll.dll" (Byval x as long,byval y as long)as long

علما أن Path هو مسار المكتبة

بعد هدا يمكن أن نستعملها كالتالي:

ss=Somme(15,4) مثلا ونفس الشيء بالنسبة للدالة الأخرى.

وفي المجلد الآخر تجدون مثالا لاستعمال DLL في برامج Hook والبرنامج هو كالتالي:

نضع الملف EXE و DLL في نفس المجلد وحين نشغل البرنامج ننقر على HOOK ليبدأ هدا الأخير في الإشتغال وبعد هدا وحين ننقر باليمين على أي نافدة مفتوحة ينقل اسم النافدة على برنامجنا. وهدا أيضا مثال بسيط للهوك يمكن تطويره.

إلى اللقاء في انتضار الإقتراحات.

DllWithAsm.zip

#16

رائع

#17

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

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

أخى chik

لا نستطيع ان نشكرك على هذا المجهود الرائع . جزاك الله خير

لدى اقتراح أرجو ان يحوز على اعجابك

انا مبتدئ اسمبلى ولا استطيع تشغيل برنامج masm32v8

فأرجوا ان تقوم بشرح وافى لتشغيل هذا البرنامج وجزاك الله خيرا

مع قبول فائق الاحترام

محمد من مصر

#18

السلام عليكم,

إن masm32 في نسخه المختلفة قد نعتبره مجموعة من الملفات والمكتبات لبناء البرنامج. وهده لا تحتاج إلى تعليق أو أية معلومات إضافية فكل من سبق وأن برمج بلغة أخرى كان يزيد الملفات الرأسية header files أو المكتبات Lib files التي يحتاجها برنامجه و masm يحتوي هو أيضا على مثل هدا فالملفات الرأسية تكون في المجلد include والمكتبات تكون في lib وطبعا حسب متطلبات البرنامج نضيف ما نحتاجه وهنا لا أرى ما يمكن أن أضيفه.

وكما أن في masm ملف qeditor.exe هدا البرنامج واجهة يمكن أن نكتب فيها برنامجنا ولكن هدا ليس ضروريا فيمكن أن نكتب برنامجنا أين نشاء وحتى على برنامج notepad للوندوز.

بعد هدا يجب بناء البرنامج وعندنا الملفات اللازمة لدالك في مجلد bin وهده العملية إما أن نقوم بها يدويا سطرا بسطر أو نجمعها في ملف من نوع bat .وأضن أنه في البداية لا يجب الإهتمام بهدا كثيرا فيمكن مثلا أخد ملف bat في مثال من الأمثلة السابقة وسوف يصلح لمعضم برامجنا فقط نغير داخل الملف bat الإسم الدي سنعطيه لبرنامجنا.وإدا كنا نريد المزيد من التوضيحات لهدا مثلا التوضيحات الخاصة ب Link نكتب في نافدة دوس Link /? وستعطينا مختلف الأشكال التي يمكن استعمالها. ولكن أدرر مرة أخرى أنه يمكن في الكثير من البرامج أن نكتفي كما في الأمثلة.

وإدا كنا نعرف برمجة الوندوز ب API فأضن أن برمجة الوندوز بالأسمبلر 32 لن تكون صعبة.

هدا ما يمكن أن أقوله هكدا ولكن إدا كانت لك أسئلة مدققة فإن شاء الله نلقى لها الحل.

أتمنى لك التوفيق وإلى اللقاء.

#19

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

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

أخى CHIK

الف الف شكر على اهتمامك والرد السريع بارك الله فيك وارجو من الله ان يوفقك ويسددخطاك والى مزيد من التقدم

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

#20

والله موضوع رائع وهو كما يبدو ليس مجرد دروس لتعلم برمجة نظام تشغيل وانما مشروع مفتوح ...

أتمنى من أعضاء قسم الأسمبلي والسي المشاركة في الموضوع ... ورسالتي موجهة بشكل خاص الى مشرفي الأقسام المعنية أيضاً كالأخ JAAS والأخ Xacker

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

سلامي

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

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