کاربر مهمان، خوش آمديد!  ( ورود - عضويت )   امروز 8 مرداد ماه ، 1389
 
ارتباط زنده با مديريت سايت

 مدير اصلي

Ahmad

Hamid

Ali


موضوعات سایت
  عكس
تعداد اخبار : 22 مورد
  آموزش
تعداد اخبار : 40 مورد
  عاشقانه
تعداد اخبار : 1 مورد
  بيوگرافي
تعداد اخبار : 2 مورد
  دانستنيها
تعداد اخبار : 17 مورد
  داستان
تعداد اخبار : 4 مورد
  فيلم
تعداد اخبار : 15 مورد
  مجله
تعداد اخبار : 0 مورد
  موبايل
تعداد اخبار : 6 مورد
  موسيقي
تعداد اخبار : 2 مورد
  خبر
تعداد اخبار : 12 مورد
  پيام كو تاه
تعداد اخبار : 18 مورد
  پزشكي
تعداد اخبار : 2 مورد
  نرم افزار
تعداد اخبار : 198 مورد
  طنز
تعداد اخبار : 8 مورد

مطالب تصادفی

داستان
[ داستان ]

·داستان حضرت سلیمان(ع) و مورچه
·ماجرای دو گرگ
·فقط خانم ها بخوانند !
·داستان پیرمرد و مزرعه

پیغام کوتاه
ارشيو پيغام کوتاه   

 

ديكشنري آنلاين

ساخت قفل های نرم افزاری
آموزش

آشنایی با نحوه ساخت قفل های نرم افزاری

تا وقتی که قانون Copyright نرم افزار در ایران به صورت کامل اجرا نمی شود، لزوم پرداختن به بحث قفل های نرم افزاری بیشتر احساس می شود. در این مقاله سعی بر این است تا علاوه بر آشنایی با انواع قفل های نرم افزاری و بررسی اختلاف آن ها با قفل های سخت افزاری، بتوانیم به عنوان طراح یك قفل نرم افزاری از محصولات نرم افزاری خودمان حمایت كنیم. ضمنا علاوه بر آشنایی با مفاهیم فوق، نوشتن روتین های ضد دیباگ (Debug) و همچنین نحوه كد كردن اطلاعات نیز تا حدی مورد بررسی قرار خواهد گرفت.
كليد


آشنایی با نحوه ساخت قفل های نرم افزاری
تا وقتی که قانون Copyright نرم افزار در ایران به صورت کامل اجرا نمی شود، لزوم پرداختن به بحث قفل های نرم افزاری بیشتر احساس می شود. در این مقاله سعی بر این است تا علاوه بر آشنایی با انواع قفل های نرم افزاری و بررسی اختلاف آن ها با قفل های سخت افزاری، بتوانیم به عنوان طراح یك قفل نرم افزاری از محصولات نرم افزاری خودمان حمایت كنیم. ضمنا علاوه بر آشنایی با مفاهیم فوق، نوشتن روتین های ضد دیباگ (Debug) و همچنین نحوه كد كردن اطلاعات نیز تا حدی مورد بررسی قرار خواهد گرفت.
 

قفل های نرم افزاری و سخت افزاری

قفل های نرم افزاری به برنامه هایی گفته می شود كه كنترل كپی نمودن آنها فقط از طریق نرم افزار و بدون نیاز به سخت افزار اضافی، قابل انجام باشد. قفل های سخت افزاری به برنامه هایی اطلاق می شود كه كنترل كپی نمودن آنها از طریق سخت افزار اضافی (که بر روی سیستم نصب می گردد) صورت می پذیرد.

با توجه به توضیحات فوق می توان به تفاوت قفل های سخت افزاری و نرم افزاری پی برد. قفل های سخت افزاری با اضافه كردن یك سخت افزار جدید به كامپیوتر (اغلب از طریق ارتباط با پورت چاپگر) برنامه خود را كنترل می كنند. برنامه قبل از اجرا، ابتدا با مراجعه به آدرس سخت افزار نصب شده (اضافه شده با استفاده از دستور Port ) به سخت افزار مورد نظر خود مراجعه كرده و در صورت یافتن آن، تست های مختلف اعم از تست رمز، خواندن اطلاعات و ... را انجام داده و در نهایت می تواند تصمیم گیری نماید.

اما در قفل های نرم افزاری برنامه، بدون نیاز به سخت افزار اضافی و با كنترل رسانه ذخیره سازی، تصمیم گیری می كند. ضمنا لازم به توضیح است كه هدف از طراحی قفل های نرم افزاری/سخت افزاری این نیست كه هیچكس توانایی شكستن (باز كردن ) آن را ندارد بلكه هدف بالا بردن سطح كنترل كپی های غیر مجاز تا حد ممكن می باشد.
 

طریقه استفاده از قفل نرم افزاری

در برنامه مورد نظر با توجه به نوع كاربرد برنامه (كوچك و قابل كپی بر روی یك دیسكت, تحت شبكه و ... ) می توانیم از انواع روش هایی كه جهت حفاظت از نرم افزار در نظر داریم (و متعاقبا توضیح داده خواهد شد) استفاده كنیم. اما مساله قابل بحث این است كه چه قفلی را انتخاب نمائیم؟ جواب این سوال متغییر و وابسته به شرایط زیر می باشد:

الف: اعتقاد طراح نرم افزار به اینكه حتما باید كاربر آن را خریداری نماید تا از امكانات آن مطلع گردد. در این حالت قفل نرم افزاری در ابتدای شروع به كار برنامه كنترل می گردد حتی طراح می تواند در مواقع حساس نیز قفل را مجددا كنترل كند و یا حتی در حالتی كه طراح واقعا سخت گیر باشد، می تواند در زمان های مشخصی نیز از وجود قفل اطمینان حاصل نماید (مثلا هر 4 ثانیه یک بار). البته در این حالت طراح باید روشی را كه جهت كنترل قفل استفاده می كند، نیز در نظر بگیرد.

ب: اعتقاد طراح نرم افزار به این كه كاربر می تواند از نرم افزار به عنوان نسخه نمایشی نیز استفاده كند. طراح در این حالت می بایست در مكان های خاصی از برنامه، قفل را كنترل كند. مثلا در یك برنامه حسابداری می توان تمام بخش های سیستم را آزاد گذاشت (یعنی در بخش های برنامه قفل  وجود نداشته باشد) اما در گزارشگیری ها قفل گذاشت. یعنی در صورتی كه كاربر مایل به استفاده از امكانات گزارشگیری سیستم باشد، قفل نرم افزاری در خواست گردد. مزیت این روش بر روش قبلی این است كه دیگر نیاز به طراحی نسخه نمایشی خاصی جهت مشاهده كاربران وجود ندارد.
 

آشنایی با نحوه قفل گذاری بر روی یك برنامه

الف: طراح به سورس برنامه دسترسی دارد. در این حالت طراح پس از انتخاب روش قفل گذاری، كافی است آن را به زبان مورد نظر خود پیاده سازی نموده و در برنامه خود بگنجاند. (كه مكان های قرار دادن قفل در عنوان قبلی توضیح داده شد.)

ب: طراح (مجری پروژه) به سورس برنامه دسترسی ندارد. گاهی اوقات به یك سری برنامه های ارزشمندی برخورد می كنیم كه فاقد قفل هستند و بنا به دلایلی نیاز به قفل گذاری وجود دارد. (البته این حالت بیشتر در كشور ما و چند كشور دیگر كه در آن ها قانون Copyright اجرا نمی شود، كاربرد دارد.)

جهت تزریق قفل به این گونه برنامه ها، نیاز به آشنایی كامل با ساختار فایل های اجرایی (EXE, COM, SYS, …) وجود دارد چرا كه باید برنامه ای طراحی كنیم تا همانند یك ویروس كامپیوتری به فایل اجرایی مشخصی بچسبد. البته جهت این كار بهترین زبان برنامه نویسی، اسمبلی می باشد. (به دلیل توانایی دخالت در روند اجرای برنامه و برای مطالعه بیشتر در مورد برنامه نویسی اسمبلی به سایر مقالات سایت میکرو رایانه مراجعه نمایید) البته در رابطه با نحوه نوشتن این گونه برنامه ها، روش های زیادی وجود دارد كه خود بحثی مجزا را می طلبد و از حوصله این مقاله خارج است.

ضمنا برای بالا بردن سطح امنیت برنامه، لازم است تا یكسری كد های ضد دیباگ نیز در برنامه گنجانده شوند. كدهای ضد دیباگ، دستوراتی به زبان اسمبلی هستند كه در حالت اجرای عادی برنامه، هیچ تغییری در روند اجرا نمی گذارند بلكه در مواقعی كه برنامه توسط دیباگرها اجرا می گردند، قادر هستند تا از اجرای آن جلوگیری نمایند.

با اضافه كردن كد های ضد دیباگ به ابتدای برنامه (یا قبل از كنترل قفل) می توان احتمال دست كاری در برنامه را پائین آورد. (نحوه نوشتن كد های ضد دیباگ در زیر آورده شده است.)
 

آشنایی با روش های قفل گذاری و نحوه طراحی آن ها

1- قفل گذاری با استفاده از شماره سریال اصلی دیسكت
همانطور كه می دانید، سیستم عامل جهت هر دیسكت یك شماره سریال واحد (UNIQUE) اختصاص می دهد، بطوریكه شماره سریال هر دو دیسكت با هم یكی نیستند. بنابراین همین خود یك راه تشخیص دیسكت كلید (قفل) می باشد. جهت استفاده از این قفل می بایست شماره سریال دیسكت را خوانده و سپس در داخل برنامه آنرا كنترل نمائیم. یك راه ساده جهت خواندن شماره سریال، اجرای دستور VOL بصورت شكل زیر است:

VOL >>C:DOSLCK.TMP

بعد با باز كردن فایل LCK.TMP می توانیم به محتویات آن دسترسی پیدا كنیم. راه دیگر مراجعه به Boot Sector جهت كنترل قفل می باشد.

ضریب اطمینان این قفل در مورد دیسكت ها 5%-2% بوده و در رابطه با هارد دیسك 60%-50% می باشد. دلیل این اختلاف این است كه در حالت قفل دیسكتی، با عمل كپی Boot Sector، قفل بر روی دیسكت دیگر قرار خواهد گرفت اما در رابطه با هارد دیسك اینكار به سادگی انجام پذیر نیست.

2- قفل گذاری با استفاده از مشخصات سیستم
در این نوع قفل نرم افزاری، برنامه قبل از اجرا ابتدا مشخصات سیستم را خوانده (كه اینكار از طریق مراجعه به بخش های خاصی از حافظه و یا مراجعه به اطلاعات BIOS انجام می شود.) سپس آن را با فایلی كه قبلا توسط نویسنده نرم افزار بر روی كامپیوتر كپی گردیده، مقایسه می كند و در صورت عدم برابری، اجرای برنامه پایان می پذیرد.

این نوع قفل هنوز هم در بسیاری از برنامه ها استفاده می گردد، اما نكته قابل ذكر این است كه جهت اطمینان بیشتر به قفل، لازم است فایل حاوی مشخصات بصورت كد شده نوشته شده باشد تا امكان دستكاری آن توسط قفل شكنان به حداقل ممكن برسد. درصد اطمینان این نوع قفل 75%-65% می باشد.
 

3- قفل با استفاده از موقعیت فایل روی هارد دیسك
این نوع قفل فقط بر روی هارد دیسك قابل استفاده بوده و به این صورت است كه فایل اجرایی به موقعیت خود بر روی هارد حساس می باشد چرا كه قبل از اجرا ابتدا موقعیت خود را از روی سكتورهای ROOT خوانده و سپس شماره كلاستر اشاره گر به خودش را بدست می آورد، سپس آن را با شماره كلاستری كه قبلا توسط برنامه نویس بر روی یكی از فایل های برنامه (ممكن است به صورت كد شده باشد) قرار داده شده، مقایسه كرده و در صورت برابر بودن اجرا می شود.

این نوع قفل نسبت به قفل قبلی (شماره 2)  استفاده كمتری دارد، چون در صورتی كه برنامه از روی بخشی از هارد به ناحیه دیگری انتقال یابد، اجرا نخواهد شد و این از نظر كاربر بسیار ناپسند می باشد. (ضمنا امكان Defra, Scandisk, و ... نیز وجود ندارد چرا كه شماره كلاستر اشاره گر به فایل تغییر خواهد كرد.) ضریب اطمینان این نوع قفل نیز 80%-70% می باشد.
 

4- قفل با استفاده از فرمت غیر استاندارد
این شیوه یكی از رایج ترین قفل های نرم افزاری است كه هنوز هم بصورت جدی مورد استفاده قرار می گیرد. برخی از دلایل اهمیت آن عبارتند از:
- امكان استفاده از روش های متفاوت در این روش
- راحتی و سرعت زیاد به هنگام استفاده از آن
- وجود ضریب اطمینان بالا و انعطاف پذیری زیاد آن
- عدم وجود نرم افزار خاصی جهت باز كردن این نوع از قفل ها

همان طور كه می دانید سیستم عامل جهت دسترسی به اطلاعات یك دیسكت از فرمت خاصی (18 سكتور در هر تراك) استفاده می كند، اما اگر یه تراك به صورت غیر استاندارد فرمت شود، (مثلا 19 سكتور در تراك) سیستم عامل دیگر توانایی استفاده از سكتورهای غیرمجاز را نخواهد داشت (برای مطالعه بیشتر دراین مورد به سایر مقالات سایت میکرو رایانه مراجعه نمایید) و بنابراین تمام نرم افزارهای تحت سیستم عامل مزبور نیز از سكتورهای مخفی استفاده نكرده، در نتیجه امكان كپی برداری از آنها بسیار ضعیف است.

پیشنهاد ما استفاده از همین روش جهت طراحی قفل است. به طوری که تراك آخر دیسك را مثلا بهصورت یك سكتوری و با شماره 20 فرمت کنید. سپس جهت كنترل دیسكت به سكتور فوق مراجعه كرده و در صورت وجود آن كنترل و اجرای برنامه را پی بگیرد.

البته غیر از تغییر شماره سكتور می توان از اندازه غیر مجاز نیز استفاده كرد، یعنی بجای اینكه سكتورها را بصورت 512 بایتی فرمت كنیم، از اندازه 1024, 2048 و ... استفاده كنیم. ( قفل نرم افزاری Copy Control كه معروفترین در نوع خود می باشد، از همین روش استفاده می كند.)
این قفل فقط جهت فلاپی دیسك قابل استفاده می باشد و در صد اطمینان در این روش حدود 95%-85% می باشد.
 

5- قفل با استفاده از شماره سریال ساختگی
این روش قفل گذاری كه قویترین قفل می باشد، بصورت مخلوطی از روش های 1 و 4 می باشد. یعنی ابتدا تراك خاصی را بصورت غیر استاندرد فرمت كرده و سپس اطلاعات خاصی را درون آن قرار می دهند (شماره سریال فرضی). این قفل فقط جهت فلاپی دیسك قابل استفاده بوده و ضریب اطمینان آن حدود 98%-90% می باشد.

 

آشنایی با روتین های ضد دیباگ Anti Debug Procedures

همان طوری كه توضیح داده شد، روتین های ضد دیباگ جهت جلوگیری از اجرای برنامه های دیباگر و یا حداقل جهت مشكل تر كردن كار دستكاری قفل توسط قفل شكنان، استفاده می شود. در زیر چند روش به عنوان مثال آورده شده است:

 

الف: غیر فعال كردن وقفه ها جهت جلوگیری از اجرای مرحله به مرحله ( Trace كردن ) برنامه:

می توان وقفه های كنترلر 8359 را غیر فعال ساخت. (در مورد وقفه ها بحث های نسبتا مفصل و کاملی در سایت میکرو رایانه انجام شده برای مطالعه بیشتر دراین مورد به سایر مقالات سایت میکرو رایانه مراجعه نمایید) آدرس این كنترلر 21h بوده و IRQ های 7-0 را كنترل می كند IRQ1 همان وقفه مربوط به صفحه كلید می باشد. پس با غیر فعال كردن این وقفه می توان صفحه كلید را غیر فعال نمود. طریقه استفاده:

CS:0100 E421   IN   AL,21
CS:0102 0C02  OR   AL,02
CS:0104 E621  OUT 21,AL

ب: تغییر بردار وقفه ها

یكی از روش های ساده و راحت جهت ضد دیباگ كردن برنامه ها تغییر برداری است كه دیباگر از آن استفاده می كند. (03 ) حتما بخاطر بسپارید كه در پایان برنامه دوباره آدرس بردار وقفه تغییر داده شده را بازیابی كنید. طریقه استفاده:

 

CS:0100 EB04 JMP 0106
CS:0102 0000 ADD [BX+SI],AL
CS:0104 0000 ADD [BX+SI],AL
CS:0106 31C0 XOR AX,AX
CS:0108 8EC0 MOV ES,AX
CS:010A 268B1E0C00 MOV BX,ES:[000C]
CS:010F 891E0201 MOV [0102],BX
CS:0113 268B1E0E00 MOV BX,ES:[000E]
CS:0118 891E0401 MOV [0104],BX
CS:011C 26C7064C000000 MOV Word Ptr ES:[000C],0000
CS:0123 26C7064E000000 MOV Word Ptr ES:[000E],0000

 

ج:گیج كردن دیباگر

 این راه یكی از قویترین تكنیك های ضد دیباگ بوده كه در آن به وسط یك دستور، پرش می شود و اینكار باعث قفل كردن (Hang) دیباگر خواهد شد. طریقه استفاده:

CS:0100 E421 IN AL,21
CS:0102 B0FF MOV AL,FF
CS:0104 EB02 JMP 0108
CS:0106 C606E62100 MOV Byte Ptr [21E6],00
CS:010B CD20 INT 20

 

د: كنترل پرچم های CPU

این روش در برابر دیباگرها بسیار مفید می باشد و به این صورت است كه ابتدا پرچم Trace از CPU را خاموش كرده و در بین برنامه آنرا كنترل كنیم. در صورتی كه این پرچم روشن شده باشد، مشخص است كه دیباگر در پشت صحنه در حال اجراست. طریقه استفاده:

CS:0100 9C PUSHF
CS:0101 58 POP AX
CS:0102 25FFFE AND AX,FEFF
CS:0105 50 PUSH AX
CS:0106 9D POPF

و در بین برنامه از دستورات ذیل استفاده كنید:

CS:1523 9C PUSHF
CS:1524 58 POP AX
CS:1525 250001 AND AX,0100
CS:1528 7402 JZ 152C
CS:152A CD20 INT 20

 

ه: متوقف ساختن دیباگر

این روش باعث متوقف شدن دیباگر می شود كه با اجرای دستور ساده INT 03 می توان این كار را انجام داد. طریقه استفاده:

CS:0100 B96402 MOV CX,0264
CS:0103 BE1001 MOV SI,0110
CS:0106 AC LODSB CS:0107 CC INT 3
CS:0108 98 CBW
CS:0109 01C3 ADD BX,AX
CS:010B E2F9 LOOP 0106

 

روش های كد كردن اطلاعات Data Coding Procedures


الف: افزودن یك عدد به كد های یك فایل

در این روش جهت كد كردن یك فایل، ابتدا آن را خوانده و سپس یك مقدار خاص، مثلا 20 را به مقدار هر بایت فایل اضافه می كنیم. این یكی از ساده ترین روش ها بوده و نسبتا كارایی خوبی نیز دارد. جهت خارج كردن فایل از حالت كد شده (Decode) نیز، كافیست مقدار فوق را از تمام بایت های فایل كم كنیم.
 

ب: XOR كردن كل فایل

در این روش نیز پس از خواندن كل فایل، تمام بایت های آن را با رشته كاراكتری یا عدد ثابت خاصی XOR كرده و سپس مقدار جدید را در فایل حاصل ضبط می نمائیم. جهت خارج كردن فایل از حالت كد شده، دقیقا عکس آن را انجام می دهیم.

 

 مثالی از یک برنامه قفل گذار Pascal Source To Learn

در زیر لیست دو برنامه نمونه، كه شماره (1) جهت درست كردن دیسكت قفل و شماره (2) جهت تست آن طراحی شده، آورده شده است: در این برنامه ها از تراك 81 و سكتور 20 (در حالت عادی هر دیسكت فقط 18 سكتور دارد) جهت قفل برنامه استفاده شده و به این صورت عمل می كند كه یك رشته را از كاربر دریافت كرده و در مكان فوق قرار می دهد و سپس جهت تست رشته دریافتی در برنامه دوم آن را با اطلاعات موجود در دیسكت مقایسه می كند و با دادن پیغام مناسبی آن را چاپ می نماید. این برنامه توسط Turbo Pascal 7.0 كامپایل و اجرا شده اند.

برنامه شماره (1)

این برنامه جهت ساختن دیسكت قفل استفاده می شود


program PROGRAM-1;
Uses Dos;
TYPE DAT = String[40];
VAR
      C : Registers;
      FP : String[15];
      PU : Array[1..512] of char;
      Data: Dat;
      I : Byte;
      Key : Dat;
{******************************************}
Procedure ZUW;
      Begin
           Fp:=#81+#0+#20+#2;
           c.d1 :=0;
           c.dh :=0;
           c.ch:=81;
           c.c1:=20;
           c.a1:=1;
      end;
 Procedure Write-Key(data:Dat);
      Begin
           c.ah:=5;
           ZUW;
           c.es:=Seg(fp[1]);
           c.bx:=Ofs(fp[1]);
           Intr(19,c);
           c.ah:=5; ZUW;
           c.es:=Seg(fp[1]);
           c.bx:=Ofs(fp[1]);
           Intr(19,c);
           For i:=1 to Length(data) do
                                Pu:=data;
           Pu[i+1]:=#0;
           c.ah:=3; ZUW;
           c.es:=Seg(Pu);
           C.bx:=Ofs(Pu);
           Intr(19.c);
       end;
 {******************************************}
begin
           Writeln;
           Writeln( Program Number1 );
           Writeln( This Program Used For Create The Key );
           Write( Please Type Key Word : );
           Readln(Key);
           Writeln;
           Write( Writing Key …);
           Write-Key(Key);
           Writeln( OK .);
           Writeln;
end.

 

برنامه شماره (2)

این برنامه جهت كنترل دیسكت قفل استفاده می شود

program PROGRAM-2;
Uses Dos;
Type DAT = String[40];
Var
     C : Registers;
     FP : String[15];
     PU : Array[1 ..512] of char;
     Data: Dat;
     I : Byte;
     Key : Dat;
{******************************************}
Procedure ZUW;
Begin
    Fp:=#81+#0+#20+#2;
    c.d1:=0;
    c.dh:=0;
    c.ch:=81;
    c.c1:=20;
    c.a1:=1;
 end;

{******************************************}
 Function Read-Key(Key:Dat):Boolean;
 Begin
    c.ah:=2;
    ZUW;
    c.es:=Seg(pu);
    c.bx:=Ofs(pu);
    Intr(19.c);
    c.ah:=2;
    ZUW;
    c.es:=Seg(pu);
    c.bx:=Ofs(pu);
    Intr(19,c); I:=1;
    data:=; While pu#0 do
          begin
                 Data :=data+pu[];
                 Inc(I);
          end;
    If data=Key then
                 Read-Key:=True
    Else
                 Read-Key:=False;
end;

{******************************************}
 begin
        Writeln;
        Writeln( Program Number2 );
        Writeln( This Program Used For Check The Key );
        Write( Please Type Key Word : );
        Readln(Key);
        Writeln;
        If Read-Key(Key)=False then
                    Writeln( I am Sorry , Not Found .);
        Else
                    Writeln( Very Good , That Found .);
        Writeln;
 end.



کلمات کليدي :

ارسال شده در مورخه : سه شنبه، 1 ارديبهشت ماه ، 1388 توسط ahmad  چاپ مطلب

 

مرتبط با موضوع :

 تماشای مسابقات جام جهاني از طریق اینترنت  [جمعه، 4 تير ماه ، 1389]
 مشاهده نتایج بازی‏های جام‏جهانی به وسیل  [جمعه، 4 تير ماه ، 1389]
 مستقیم كردن لینک‏های Megaupload ،Rapidshare و ... با س  [جمعه، 4 تير ماه ، 1389]
 با موبایل خود آتش روشن کنید  [سه شنبه، 1 تير ماه ، 1389]
 آموزش نرم افزار فتوشاپ  [يكشنبه، 8 فروردين ماه ، 1389]
 پاک کردن ID خودتان از Add List افراد دیگر در یاهو  [دوشنبه، 31 فروردين ماه ، 1388]
 آموزش نصب ویندوز به صورت عکس  [سه شنبه، 25 فروردين ماه ، 1388]
 آموزش پارتيشين بندي با Partition Magic  [سه شنبه، 25 فروردين ماه ، 1388]
 NTFS چیست؟  [سه شنبه، 25 فروردين ماه ، 1388]
 Blu-ray چیست ؟  [يكشنبه، 23 فروردين ماه ، 1388]

 
نام شما: [ کاربر جدید ]

عنوان:
 
نظر:


:) ;) |) :- :( :0 :# *) ^) +)) :} |(( @: (:) :? :**

کد امنيتي : caw87qat
تايپ کد امنيتي : [ بازگشت ]

 
بازدیدکنندگان غیر عضو حق ارسال نظر و پیشنهاد در مورد مطالب این سایت ندارند .
برای استفاده از سرویسهای مخصوص کاربران عضو فرم عضویت را تکمیل نمائید .
امتیاز دهی به مطلب
امتیاز متوسط : 5
تعداد آراء: 1


لطفا رای مورد نظرتان را در مورد این مطلب ارائه نمائید :

عالی
خیلی خوب
خوب
متوسط
بد


اشتراک گذاري مطلب


انتخاب ها

 گرفتن پرينت از اين مطلب گرفتن پرينت از اين مطلب


 
موضوعات مرتبط

آموزش


صفحه اصلي |  جستجو |  دريافت فايل |  آرشيو اخبار |  تماس با ما



  

PHPNuke Farsi [MT Edition] Project By PHPNuke.ir

www.mashhadteam.ir