PDA

View Full Version : جلوگیری از کپی غیر مجاز برنامه



b_mohammadpoor
سه شنبه 22 مهر 1382, 07:21 صبح
باسلام
من یک برنامه با دلفی 7 نوشتم - میخواهم روی اون قفلی بگذارم که از کپی غیر مجاز اون جلوگیری بشه 8)
ضمنا برنامه دارای بانک SQL است و قراره روی شبکه کار کنه .

با تشکر
محمدپور

(امید)
پنج شنبه 24 مهر 1382, 12:02 عصر
با سلام

اگه بخوای از قفل سخت افزاری استفاده کنی اول یه سرچ تو این فریم می کنی و بعد یک فقره ش رو می خره و مشغول می شی همین.
اگر از قفل نرم افزاری بخواهی استفاده کنی که بهتره تو نت سرچ کنی .
می تونی تابعی بنویسی که براساس شماره سریال مادربورد یا هر چی یه کدی رو برگردونه .
حالا با یه تابع دیگه می تونی در جواب اون کد , کدی رو برای کاربر ارسال کنی که برنامه با مچ کردن کدی که ارسال کردی و شمار سریال اجازه کار کردن کامل برنامه رو بده. یا چیزی تو همین مایه ها.حالا اگه برنامه رو هر سیستمی که نصب شد تو باید کلید کار کردنش رو بفرستی.

آدیوس

SherlookHolms
پنج شنبه 24 مهر 1382, 19:27 عصر
بهترین کاری که میتونی انجام بدی قفل نرم افزاری هست چون میدونم کارمند جماعت پول خرج نمیکنه 8) پس قفل نرم افزاری رو از سایت توری دات نت پیدا کن. البته من یک کامپوننت خوب دارم که قابل کراک نیست و با سافت ایس و دیس اسمبلر و ... هم نمیتونی کاری بکنی که کراک بشه. ولی مجانی نیست. :twisted:

شفیعی
سه شنبه 23 دی 1382, 14:40 عصر
سلام

چگونه می توان روی برنامه قفل گذاشت مثلا بعد از چند روز برنامه از کار بیفتد

یا برنامه فقط با یک سی دی خاص کار کند ویا روشهای دیگر

Delphi-Clinic
سه شنبه 23 دی 1382, 15:31 عصر
با استفاده از ابزار Open Source زیر می توانید قفل زماندار و قفل های License دار را روی نرم افزارتان قرار دهید.

TurboPower OnGuard

مهدی کرامتی
سه شنبه 23 دی 1382, 17:44 عصر
و یک نکته جالب: این TurboPower OnGuard اصلا قابل اعتماد نیست.

Delphi-Clinic
سه شنبه 23 دی 1382, 18:03 عصر
پس از قفل تلفنی DelphiAssistant استفاده کنید.
شرکت مهندسی مشاور لوح و قلم با استفاده از این قفل ماهانه بیش از 5000 نسخه از محصولاتش را به بازار می فرستد.

به نظر من امتحانش را پس داده .
زمان تست بیش از یک سال.

شفیعی
سه شنبه 23 دی 1382, 18:49 عصر
سلام
اخرش تکلیف من چی باید چکار بکنم

مهدی کرامتی
سه شنبه 23 دی 1382, 18:57 عصر
ما یک قفل جدید آماده کرده‌ایم که بزودی مشخصات آن در سایت رسمی نوین رسانه (http://www.novinmedia.com) اعلام خواهد شد.

delphi4all
سه شنبه 23 دی 1382, 21:15 عصر
از Ice License استفاده کن.ولی پولیه.من اون رو خریدم.اگر بخای میتونم بهت بفروشم...
www.ionworx.com

شفیعی
سه شنبه 23 دی 1382, 23:42 عصر
سلام
دوستان خیلی ممنون
من می خواهم تاریخ سیستم را در یک فایل باینری ذخیره کنم و هر بار که برنامه اجرا می شود تاریخ چک کنم اگر 10 روز از تاریخ نگذشته برنامه کار کند واگر 10 گذشته برنامه اجرا نشود تاریخ را به صورت باینری در فایل ذخیره کرده ام فقط نمی دانم تاریخی را که ذخیره کرده ام چگونه از داخل فایل بخوانم .

JavanSoft
چهارشنبه 24 دی 1382, 00:24 صبح
1) روش عهد دقیانوس : می توانید در یک فایل متنی بنویسید و قبل از نوشتن و یا بعد از خواندن انرا با یک عددXORکنید ...بد نیست
2) روش عصر ویندوز : در رجیستری با همان روش فوق در یک جای پرت وپلا بنویسید
3) بی خیال این روشها بشوی و برنامه ای بنویسی که حتی با کپی کردن هم نتوانند از ان استفاده کنند

khafanovich
چهارشنبه 24 دی 1382, 08:49 صبح
سلام...آقا میشه یک قسمت مخصوصه امنیت نرم افزار ایجاد کنید تا بتوانیم راه های جدید رو تست و آزمایش کنیم...همچنین از تجربیات دوستان استفاده کنیم؟!

ramin_rp
چهارشنبه 24 دی 1382, 09:10 صبح
میتونم بهت بفروشم...
قیمت؟

Hidarneh
جمعه 26 دی 1382, 20:01 عصر
ما یک قفل جدید آماده کرده‌ایم که بزودی مشخصات آن در سایت رسمی نوین رسانه (http://www.novinmedia.com) اعلام خواهد شد.
آقای کرامتی بازگشت دوباره اتون مبارک . امیدوارم به سرنوشت 2-3 سال قبل دچار نشه

baabi
جمعه 26 دی 1382, 22:43 عصر
میگم ، حالا اگه از شماره سریال مثلا هارد استفاده کنیم چی ؟ آیا میشه شکوندش؟

Hidarneh
جمعه 26 دی 1382, 23:24 عصر
در کل قدم اولت باید این باشه که برنامه ات رو نتونن تغییر بدن . اگه بشه برنامه ات رو debug کرد و کدهای اسمبلی اونو تغییر داد و برنامه ات هم متوجه نشه هر روشی رو که استفاده کنی .... کاملا قابل شکستن خواهد بود .

امیر-نا
چهارشنبه 06 اسفند 1382, 12:08 عصر
می تونی هر دفه سایز برنامه رو چک کنی اگه زیاد شد بفهمی که بهش دست برد زدن!!


امیر
:shock:

b_mohammadpoor
پنج شنبه 07 اسفند 1382, 12:04 عصر
1- چطوری میتونم سایز برنامه را چک کنم ؟
2 - اگر با برنامه ای مثلا با DEDE بشه سورس برنامه را بدست آورد چطوری میشه جلو این کار را گرفت ؟
3 - ...



خیلی ممنون :wink:

امیر-نا
پنج شنبه 07 اسفند 1382, 14:35 عصر
سلام می تونی از تابع
()GetFileSize
سایز فایل رو بفهمی


امیر

امیر-نا
پنج شنبه 07 اسفند 1382, 14:42 عصر
من دو تا مثال برات نوشام که در زیر آوردم می تونی استفاده کنی
دو تابع را در یک فایل txt.* زخیره کردم


امیر

امیر-نا
پنج شنبه 07 اسفند 1382, 14:43 عصر
البته انازه فایل رو به صورت byte می ده اگه خواستی برحست MB با ید بر 1024 این اندازه رو تقسیم کنی


امیر

ramin_rp
پنج شنبه 07 اسفند 1382, 16:57 عصر
سلام
اگر بایت تقسیم بر 1024 شود کیلو بایت می دهد! ( :wink: )

ramin_rp
پنج شنبه 07 اسفند 1382, 17:01 عصر
سلام
البته این هم بگم که با این کد نمیشه حجم فایلexeرا که باز است (یعنی خود فایل) را بدست آورد
رامین

امیر-نا
پنج شنبه 07 اسفند 1382, 17:05 عصر
آره میدونم
میشه قبل از اجرای برنامه اندازه اونو چک کرد؟؟
نه؟

مهدی کرامتی
پنج شنبه 07 اسفند 1382, 17:15 عصر
کی به شما گفته وقتی برنامه دستکاری شه سایز فایلش تغییر میکنه؟

برای دستکاری کردن یک فایل Exe برای اینکه قفل را چک نکند کافی است موقعیت دستورالعمل های فوق را یافته و آنرا از کار بیاندازید که اینکار به هیچ وجه باعث تغییر در سایز فایل نمیشود!

b_mohammadpoor
جمعه 08 اسفند 1382, 10:36 صبح
اگر با برنامه ای مثلا با DEDE بشه سورس برنامه را بدست آورد چطوری میشه جلو این کار را گرفت ؟

من هنوز جوابمو نگرفتم :?

من میخواهم جلوی کپی غیر مجاز برنامه را بگیرم همچنین کاری کنم که فایل اجرایی را نتونن با برنامه ای مثل DEDE یا ... باز کنن .
لطفا من را راهنمایی کنین :(

مهدی کرامتی
جمعه 08 اسفند 1382, 12:03 عصر
DeDe فقط یک سورس اسمبلی از برنامه شما به طرف میده که بدردش هم نخواهد خود، چرا که در یک نرم‌افزار نوشته شده چیزی که مهم است منطق (Logic) نرم‌افزار است که به هیچ ترتیبی امکان بدست آوردن آن از روی فایل باینری (Exe) وجود ندارد.

b_mohammadpoor
شنبه 09 اسفند 1382, 10:22 صبح
DeDe فقط یک سورس اسمبلی از برنامه شما به طرف میده که بدردش هم نخواهد خود، چرا که در یک نرم‌افزار نوشته شده چیزی که مهم است منطق (Logic) نرم‌افزار است که به هیچ ترتیبی امکان بدست آوردن آن از روی فایل باینری (Exe) وجود ندارد.


یعنی اگر که من یک برنامه با دلفی 7 بنویسم و مثلا روی فرمهای آن نام استفاده کننده را قرار بدهم با برنامه ای مثل DEDE نمیشه اون اسم را عوض کرد ؟ یا اصلا چنین کاری امکان داره ؟ :shock:

مهدی کرامتی
شنبه 09 اسفند 1382, 10:28 صبح
یعنی اگر که من یک برنامه با دلفی 7 بنویسم و مثلا روی فرمهای آن نام استفاده کننده را قرار بدهم با برنامه ای مثل DEDE نمیشه اون اسم را عوض کرد ؟ یا اصلا چنین کاری امکان داره ؟
اگر مقداردهی نام کاربر توسط کد انجام شده باشد خیر، با DeDe‌ امکان نخواهد داشت.

Mashatan
شنبه 09 اسفند 1382, 12:25 عصر
DeDe فقط یک سورس اسمبلی از برنامه شما به طرف میده که بدردش هم نخواهد خود، چرا که در یک نرم‌افزار نوشته شده چیزی که مهم است منطق (Logic) نرم‌افزار است که به هیچ ترتیبی امکان بدست آوردن آن از روی فایل باینری (Exe) وجود ندارد.

اتفاقا بر عکس خیلی هم بدرد کرک میخوره و بسیار راحت میشه فهمید برنامه چه کاری انجام میدهد بسیاری از KeyGen ها و KeyMaker ها رو از همین کدهای باینری بیرون میکشن . و در حقیقت هر KeyGen که شما میبینید قسمتی از کدی هست که داخل برنامه وجود دارد.

البته خیلی سخت و مشکل هست ولی غیر ممکن نیست و بر حسب اهمیت برنامه و موضوع کرکر وقت میزاره حالا اگر کسی قفل برنامه رو کرک نکرده دلیل بر قدرتمند بودن اون قفل نیست شاید چندان اهمیت نداشته.

در ضمن ، برای کسانی که بخاطر کرک کردن Cpu Emulator مینویسن EXE سورس به حساب میاد ! :wink:


یعنی اگر که من یک برنامه با دلفی 7 بنویسم و مثلا روی فرمهای آن نام استفاده کننده را قرار بدهم با برنامه ای مثل DEDE نمیشه اون اسم را عوض کرد ؟ یا اصلا چنین کاری امکان داره ؟

براحتی :wink: البته نه DeDe بلکه یک Resourcer مثل PEExplorer
اگر با کد نوشته باشید چون در String Data Reference برنامه قرار میگیرد باز هم قابل تغییر است.

چی کار میخوای بکنی ؟

ارادتمند
مشاطان

b_mohammadpoor
شنبه 09 اسفند 1382, 13:28 عصر
چی کار میخوای بکنی ؟


من فقط میخواهم راهی برای جلوگیری از کپی غیر مجاز برنامه ام پیدا کنم . لطفا من را راهنمایی کنید که چه کار کنم :(

Mashatan
شنبه 09 اسفند 1382, 15:30 عصر
چی کار میخوای بکنی ؟


من فقط میخواهم راهی برای جلوگیری از کپی غیر مجاز برنامه ام پیدا کنم . لطفا من را راهنمایی کنید که چه کار کنم :(

خوب اینو که میدونم به چه صورت میخوای !!
برنامه روی CD هست ؟
میخوای قفل سخت افزاری باشه یا نرم افزاری ؟
Public هست یا اینکه خودت نصب میکنی ؟

توصیه میکنم روشهای مختلف Crack و Anti Crack (http://charlesappel.home.mindspring.com/crackers.html) رو بخونی
اینم یکی (http://www.inner-smile.com/nocrack.phtml) دیگه اگه اینا رو خوب یاد بگیری دیگه خودت یاد میگیری چطوری لایه درست کنی تا کرکرها رو بپیچونی ولی با همه این موارد برنامه باز هم کرک خواهد شد . چون هر برنامه که اجرا میشود کرک شدنی هست این قانون کرکرهاست :P

من اگر بخوام قفلی بنویسم از روش سریالی استفاده میکنم (همون کاری که در مورد RoYa انجام دادم) به نظر من منطقی ترین و راحت ترین روش برای قفل گذاری است . و Engine ش رو هم خودم نوشتم و سعی کردم هسته اش قوی و قابل اعتماد باشه

چندتا توصیه :

1- هیچ وقت به کاربر پیغامی برای عدم وجود قفل ندهید.
2- از Exception برای ایجاد خطا و گول زدن کاربر استفاده نکنید. سعی کنید از Jumpهای Far بی معنا استفاده کنید البته نه کاری که آقای فراهانی (http://www.farsicomponents.com) در کاموننتشون انجام دادن ا
3- از یک متغییر برای چک کردن قفل استفاده نکنید
4- برنامه را از نظر امنیت به چند دسته تقسیم کنید و سعی کنید اگر کرکر به لایه های نفوذ کرد بهش پیغام ندهید و کار خاصی نکنید و به ظاهر نشان دهید موفق شده و در عوض در نتایج برنامه اخلال ایجاد کنید. ( کاری که من در اغلب برنامه هام انجام میدم)
5- هیچ وقت چک کردن قفل را در Event ها و Procedure های Public یک Class قرار ندهید و حتی المقدور سعی کنید که Procedure معمولی باشه نه در یک Class .
6- هیچ وقت قفل را در یک DLL یا OCX قرار ندهید و سعی کنید قفل در خود EXE چک شود . چون کرک کردن قفلی که در یک DLL چک میشود و یک نتیجه را به عنوان خروجی پس میدهد بسیار راحت تر از خود EXE است.
7- سعی کنید از یک Function و یک الگوریتم برای چک کردن قفل استفاده نکنید و مثلا چک کردم قفل را بین روزهای هفته تقسیم کنید و در هر روز یک Function را صدا بزنید .
8- ...



ارادتمند
مشاطان

b_mohammadpoor
یک شنبه 10 اسفند 1382, 13:02 عصر
برنامه روی CD هست ؟ خیر برنامه را خودم نصب میکنم
میخوای قفل سخت افزاری باشه یا نرم افزاری ؟ اگر نرم افزاری باشه بهتره
Public هست یا اینکه خودت نصب میکنی ؟ برنامه را خودم نصب میکنم و میخواهم به غیر از اون کامپیوتری که نصب کردم دیگه رو هیچ کامپیوتر دیگه ای اجرا نشه

از راهنمایی شما هم خیلی ممنون :)

b_mohammadpoor
چهارشنبه 13 اسفند 1382, 10:39 صبح
من هنوز جوابم را نگرفتم :?

b_mohammadpoor
یک شنبه 17 اسفند 1382, 10:33 صبح
چرا کسی جواب منو نمیده ؟ :shock:

Mashatan
یک شنبه 17 اسفند 1382, 12:15 عصر
خوب من که جواب شما را دادم !! روش سریالی بهترین روش است.
برنامه برروی سیستم یک کد درست میکند و یک Key Gen دارید که License تولید میکنه !
و License رو قرار میدید در برنامه. و برنامه با توجه به فرمولی که شما براش معین میکنید از صحت License مطلع میشه ! البته نباید برنامه KeyGen دست کسی بیفته

ارادتمند
مشاطان

Monaa
یک شنبه 17 اسفند 1382, 12:53 عصر
میبخشید وسط حرفتون میپرم اما ......شما که دلفی کار هستید ....... مگه تمام برنامه های بورلند
از همین روش استفاده نمیکنند ؟ مثلا دلفی 8 و کایلیکس و Java Studio و J Builder ؟
خوب اینها چطوری براحتی Crack میشن و خیلی زود keygen هاشون رو میشه همه جا پیدا
کرد ؟ خود بورلند که پخشش نمیکنه :shock: من حدس میزنم Cracker ها یک نسخه از برنامه ای که
اینطوری محافظت میشود رو میخرند و با ابزارهائی :?: :?: یک رابطه منطقی بین کد و لایسنس پیدا
میکنند که با استفاده از اون keygen رو میسازن .......... خودم تا حالا چنین چیزی رو ندیدم اما فکر نمیکنم
روش دیگری برای حدس زدن نحوه کار اون فرمول وجود داشته باشه ...... درسته ؟

Mashatan
یک شنبه 17 اسفند 1382, 13:48 عصر
میبخشید وسط حرفتون میپرم اما ......شما که دلفی کار هستید ....... مگه تمام برنامه های بورلند
از همین روش استفاده نمیکنند ؟ مثلا دلفی 8 و کایلیکس و Java Studio و J Builder ؟
خوب اینها چطوری براحتی Crack میشن و خیلی زود keygen هاشون رو میشه همه جا پیدا
کرد ؟ خود بورلند که پخشش نمیکنه :shock: من حدس میزنم Cracker ها یک نسخه از برنامه ای که
اینطوری محافظت میشود رو میخرند و با ابزارهائی :?: :?: یک رابطه منطقی بین کد و لایسنس پیدا
میکنند که با استفاده از اون keygen رو میسازن .......... خودم تا حالا چنین چیزی رو ندیدم اما فکر نمیکنم
روش دیگری برای حدس زدن نحوه کار اون فرمول وجود داشته باشه ...... درسته ؟

:)

کرکرها یک شعار دارند که میگه هر برنامه که اجرا میشه قابل کرک شدن هست !
پس این روشی که منم گفتم قابل کرک هست.
در ضمن کرکها (واقعی) آدمهای نابغه هستند مثل tKc که کر هم هست رئیس Core که همه باهاش آشنا هستند و از Crackش استفاده کردن ! یا مثل SAC از گروه UG2001 پس جای تعجب نداره به سرعت KeyGen یک برنامه مثل Borland که جهانی هست رو بدست بیارن !

نه این خبرا نیست پیدا کردن رابطه خیلی خیلی سخت از این اینکه Function Verify یک License رو پیدا کنند و فرمول اون رو بدست بیارن !

وما روش که من گفتم فرقش با روش Borland اینکه این محصولات فقط یک License دارد و با License شون میشه روی هر Computer کار کرد در صورتی که روشی که بیان کردم یک Key که از مشخصات سیستم درست شده مثلا مشخصات CPU وMainboard و ... رو به صورت یک Key در میاره و بعد کاربر این را به کسی که میخواد ازش بخره بفرسته و Licese از روی همین Key درست میشه به این صورت اون License فقط روی اون کامپیوتر کار میکنه ! و نکته بعدی اینکه میشه الگوریتمی که در KeyGen هست با الگوریتم داخل برنامه فرق داشته باشه و داخل برنامه فقط یک Verify باشه .و اینجوری نمیشه KeyGen براش نویشت البته یکم سخته ! البته باید حواستون باشه Function ه Patch نشه ؛ ولی با این وجود بازم قابل کرک هست ولی نه دیگه توسط بچه ها !! :twisted:

برید از اونا بپرسید که شنیده ها رو دیدن :P

التماس دعا

Monaa
یک شنبه 17 اسفند 1382, 13:56 عصر
از توضیحتون ممنونم :)

moradi_am
یک شنبه 17 اسفند 1382, 14:15 عصر
ببخشید اگه بچه ها را هم راه میدید من یک سوال بکنم :?: :)

چطور میشه مشخصات cpu , mb ‌را بدست آورد مثل شماره سریال ؟

Mashatan
یک شنبه 17 اسفند 1382, 17:40 عصر
این یک نمونه هست
و توی اینترنت زیاده !


Author:
-=LTi=- <szabolti@freemail.hu>
...retreive CPU information?


//Sometimes u need to know some information about the CPU
//like: brand id, factory speed, wich instruction set supported etc.
//If so, than u can use this code.
//2002 by -=LTi=-

unit main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

type
Tfrm_main = class(TForm)
img_info: TImage;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure info(s1, s2: string);
end;

var
frm_main: Tfrm_main;
gn_speed_y: Integer;
gn_text_y: Integer;
const
gn_speed_x: Integer = 8;
gn_text_x: Integer = 15;
gl_start: Boolean = True;

implementation

{$R *.DFM}

procedure Tfrm_main.FormShow(Sender: TObject);
var
_eax, _ebx, _ecx, _edx: Longword;
i: Integer;
b: Byte;
b1: Word;
s, s1, s2, s3, s_all: string;
begin
//Set the startup colour of the image
img_info.Canvas.Brush.Color := clblue;
img_info.Canvas.FillRect(rect(0, 0, img_info.Width, img_info.Height));


gn_text_y := 5; //position of the 1st text

asm //asm call to the CPUID inst.
mov eax,0 //sub. func call
db $0F,$A2 //db $0F,$A2 = CPUID instruction
mov _ebx,ebx
mov _ecx,ecx
mov _edx,edx
end;

for i := 0 to 3 do //extract vendor id
begin
b := lo(_ebx);
s := s + chr(b);
b := lo(_ecx);
s1:= s1 + chr(b);
b := lo(_edx);
s2:= s2 + chr(b);
_ebx := _ebx shr 8;
_ecx := _ecx shr 8;
_edx := _edx shr 8;
end;
info('CPU', '');
info(' - ' + 'Vendor ID: ', s + s2 + s1);

asm
mov eax,1
db $0F,$A2
mov _eax,eax
mov _ebx,ebx
mov _ecx,ecx
mov _edx,edx
end;
//06B1
//|0000| |0000 0000| |0000| |00| |00| |0110| |1011| |0001|
b := lo(_eax) and 15;
info(' - ' + 'Stepping ID: ', IntToStr(b));
b := lo(_eax) shr 4;
info(' - ' + 'Model Number: ', IntToHex(b, 1));
b := hi(_eax) and 15;
info(' - ' + 'Family Code: ', IntToStr(b));
b := hi(_eax) shr 4;
info(' - ' + 'Processor Type: ', IntToStr(b));
//31. 28. 27. 24. 23. 20. 19. 16.
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
b := lo((_eax shr 16)) and 15;
info(' - ' + 'Extended Model: ', IntToStr(b));

b := lo((_eax shr 20));
info(' - ' + 'Extended Family: ', IntToStr(b));

b := lo(_ebx);
info(' - ' + 'Brand ID: ', IntToStr(b));
b := hi(_ebx);
info(' - ' + 'Chunks: ', IntToStr(b));
b := lo(_ebx shr 16);
info(' - ' + 'Count: ', IntToStr(b));
b := hi(_ebx shr 16);
info(' - ' + 'APIC ID: ', IntToStr(b));

//Bit 18 =? 1 //is serial number enabled?
if (_edx and $40000) = $40000 then
info(' - ' + 'Serial Number ', 'Enabled')
else
info(' - ' + 'Serial Number ', 'Disabled');

s := IntToHex(_eax, 8);
asm //determine the serial number
mov eax,3
db $0F,$A2
mov _ecx,ecx
mov _edx,edx
end;
s1 := IntToHex(_edx, 8);
s2 := IntToHex(_ecx, 8);
Insert('-', s, 5);
Insert('-', s1, 5);
Insert('-', s2, 5);
info(' - ' + 'Serial Number: ', s + '-' + s1 + '-' + s2);

asm
mov eax,1
db $0F,$A2
mov _edx,edx
end;
info('', '');
//Bit 23 =? 1
if (_edx and $800000) = $800000 then
info('MMX ', 'Supported')
else
info('MMX ', 'Not Supported');

//Bit 24 =? 1
if (_edx and $01000000) = $01000000 then
info('FXSAVE & FXRSTOR Instructions ', 'Supported')
else
info('FXSAVE & FXRSTOR Instructions Not ', 'Supported');

//Bit 25 =? 1
if (_edx and $02000000) = $02000000 then
info('SSE ', 'Supported')
else
info('SSE ', 'Not Supported');

//Bit 26 =? 1
if (_edx and $04000000) = $04000000 then
info('SSE2 ', 'Supported')
else
info('SSE2 ', 'Not Supported');

info('', '');

asm //execute the extended CPUID inst.
mov eax,$80000000 //sub. func call
db $0F,$A2
mov _eax,eax
end;

if _eax > $80000000 then //any other sub. funct avail. ?
begin
info('Extended CPUID: ', 'Supported');
info(' - Largest Function Supported: ', IntToStr(_eax - $80000000));
asm //get brand ID
mov eax,$80000002
db $0F
db $A2
mov _eax,eax
mov _ebx,ebx
mov _ecx,ecx
mov _edx,edx
end;
s := '';
s1 := '';
s2 := '';
s3 := '';
for i := 0 to 3 do
begin
b := lo(_eax);
s3:= s3 + chr(b);
b := lo(_ebx);
s := s + chr(b);
b := lo(_ecx);
s1 := s1 + chr(b);
b := lo(_edx);
s2 := s2 + chr(b);
_eax := _eax shr 8;
_ebx := _ebx shr 8;
_ecx := _ecx shr 8;
_edx := _edx shr 8;
end;

s_all := s3 + s + s1 + s2;

asm
mov eax,$80000003
db $0F
db $A2
mov _eax,eax
mov _ebx,ebx
mov _ecx,ecx
mov _edx,edx
end;
s := '';
s1 := '';
s2 := '';
s3 := '';
for i := 0 to 3 do
begin
b := lo(_eax);
s3 := s3 + chr(b);
b := lo(_ebx);
s := s + chr(b);
b := lo(_ecx);
s1 := s1 + chr(b);
b := lo(_edx);
s2 := s2 + chr(b);
_eax := _eax shr 8;
_ebx := _ebx shr 8;
_ecx := _ecx shr 8;
_edx := _edx shr 8;
end;
s_all := s_all + s3 + s + s1 + s2;

asm
mov eax,$80000004
db $0F
db $A2
mov _eax,eax
mov _ebx,ebx
mov _ecx,ecx
mov _edx,edx
end;
s := '';
s1 := '';
s2 := '';
s3 := '';
for i := 0 to 3 do
begin
b := lo(_eax);
s3 := s3 + chr(b);
b := lo(_ebx);
s := s + chr(b);
b := lo(_ecx);
s1 := s1 + chr(b);
b := lo(_edx);
s2 := s2 + chr(b);
_eax := _eax shr 8;
_ebx := _ebx shr 8;
_ecx := _ecx shr 8;
_edx := _edx shr 8;
end;
info('Brand String: ', '');
if s2[Length(s2)] = #0 then setlength(s2, Length(s2) - 1);
info('', ' - ' + s_all + s3 + s + s1 + s2);
end
else
info(' - Extended CPUID ', 'Not Supported.');
end;

procedure Tfrm_main.info(s1, s2: string);
begin
if s1 <> '' then
begin
img_info.Canvas.Brush.Color := clblue;
img_info.Canvas.Font.Color := clyellow;
img_info.Canvas.TextOut(gn_text_x, gn_text_y, s1);
end;
if s2 <> '' then
begin
img_info.Canvas.Brush.Color := clblue;
img_info.Canvas.Font.Color := clWhite;
img_info.Canvas.TextOut(gn_text_x + img_info.Canvas.TextWidth(s1), gn_text_y, s2);
end;
Inc(gn_text_y, 13);
end;

end.