رابطه Reverse Engineering و Assembly
اکنون که ارتباط بین Reverse Engineering و Cracking را متوجه شدید شاید بپرسید برای یادگیری Reverse Engineering باید از کجا شروع کنیم.
به طور کلی کامپیوتر فقط یک زبان را تشخیص می دهد و آن هم زبان ماشین است. تمامی فایل های اجرایی (مانند برنامه ها) برای اجرا شدن باید به این زبان تبدیل شوند. زبان ماشین فقط از اعداد باینری (۰ و ۱) تشکیل شده و به همین دلیل برنامه نویسی به این زبان بسیار سخت است. به همین خاطر زبان Assembly (اسمبلی) ساخته شد. زبان اسمبلی در واقع همان زبان ماشین هست با این تفاوت که به جای استفاده از اعداد باینری از یک سری دستورات واقعی که بسیار شبیه به کلمات زبان انگلیسی هستند استفاده می شود.
از آنجایی که تمامی فایل های اجرایی برای اجرا شدن و کار کردن باید به زبان ماشین تبدیل شوند به دست آوردن سورس کد آنها به زبان اسمبلی که همان زبان ماشین هست کار بسیار ساده ای است ، بنابر این در صورتی که ما به زبان اسمبلی مسلط باشیم می توانیم به مراحل طراحی یک برنامه پی ببریم. چون سورس آن برنامه را به زبان اسمبلی در اختیار داریم.
در واقع مهندسی معکوس وابسته به اسمبلی است. چون تمامی مراحل پی بردن به مراحل طراحی یک نرم افزار و فهمیدن اصول محاسباتی یک نرم افزار از طریق علم مهندسی معکوس، به واسطه ی زبان اسمبلی انجام می گیرد. بنابراین حالا می توانیم معنای دقیق تری از مهندسی معکوس بیان کنیم :
مراحل پی بردن به طرز محاسبات یک نرم افزار از طریق زبان اسمبلی را مهندسی معکوس می گوییم (توجه داشته باشید که این کار بدون داشتن سورس کد اصلی نرم انجام می شود).
اگر دقت داشته باشید Protection های یک برنامه هم قسمتی از محاسبات آن برنامه هستند و در واقع نرم افزار طبق یک محاسباتی تشخیص می دهد که آیا برنامه توسط کاربر رجیستر شده است یا نه. بنابراین اگر ما بتوانیم تشخیص دهیم که برنامه چگونه این محاسبات را انجام می دهد و روش انجام این محاسبات را به نفع خودمان تغییر دهیم می توانیم یک برنامه را Crack کنیم.
اما ممکن هست بپرسید که چه طور می توان سورس یک فایل اجرایی را به زبان اسمبلی به دست آورد. در بخش آشنایی با Disassembler با چگونگی انجام این کار آشنا خواهیم شد. اما فعلا بهتر است تا کمی بیشتر درباره Assembly بدانیم.
آشنایی بیشتر با Assembly و دیگر زبان های برنامه نویسی
مطالب زیر قسمت هایی از کتاب C++ How To Program است که قسمت هایی از آن را خلاصه کردیم و توضیحاتی مرتبط به بحث خودمان را به آن اضافه کردیم:
برنامه نویسان، دستورالعمل ها را به زبانهای برنامه نویسی گوناگونی می نویسند. برخی از این زبان ها مستقیما برای کامپیوتر قابل فهمند و برخی دیگر نیاز به مراحل میانی ترجمه دارند. امروزه از صدها زبان کامپیوتری استفاده می شود که میتوان آنها را به سه نوع کلی تقسیم کرد:
زبان های ماشین۱
زبان اسمبلی۲
زبان های سطح بالا۳
کامپیوتر ها می توانند زبان ماشین مربوط به خودشان را مستقیما درک کنند. زبان ماشین، «زبان طبیعی» کامپیوتر است و توسط طراحی سخت افزار آن کامپیوتر طراحی می شود.
برنامه هایی که به زبان ماشین طراحی شده اند به طور کلی شامل رشته هایی از اعداد (که نهایتا تبدیل به ۱ و ۰ می شوند) هستند که به کامپیوتر دستور اجرای ابتدایی ترین اعمال را یکی پس از دیگری می دهند. همانطور که در قطعه برنامه زیر دیده می شود کار با زبان ماشین برای انسانها دشوار است. قطعه برنامه زیر اضافه پرداخت را با حقوق پایه جمع می کند و نتیجه را در حقوق کل ذخیره می کند.
+۱۳۰۰۰۴۲۷۷۴ +۱۴۰۰۵۹۳۴۱۹ +۱۲۰۰۲۷۴۰۲۷
با رواج بیشتر کامپیوتر ، برنامه نویسان دریافتند که برنامه نویسی به زبان ماشین بسیار سخت و وقت گیر است . از این رو کار با رشته هایی از اعداد که توسط کامپیوتر قابل فهم بودند را رها کرده و شروع به استفاده از مخففهای انگلیسی گونه ای که بیانگر اعمال ابتدایی کامپیوترند نمودند. این مخفف ها اساس زبان اسمبلی را تشکیل داد. در پی آن برنامه هایی نیز ایجاد شدند تا برنامه های ایجاد شده توسط زبان اسمبلی را به سرعت به زبان ماشین ترجمه کنند که به این برنامه ها اسمبلر می گویند . قطعه برنامه اسمبلی زیر هم اضافه پرداخت را با حقوق پایه جمع می کند و نتیجه را با حقوق کل ذخیره می کند . ولی این کار را واضح تر از زبان معادل ماشین انجام می دهد :
LOAD ADD STORE BASEPAY OVERPAY GROSSPAY
گرچه این کد برای انسان واضح تر است ولی زبان اسمبلی هم حتی برای انجام ساده ترین کارها نیاز به تعداد زیادی دستورالعمل داشت. از این رو برای سرعت بخشیدن به فرایند برنامه نویسی، زبان های سطح بالا ایجاد شدند که در آن ها یک جمله کارهای بزرگی انجام می دهد. برنامه های سطح بالا به برنامه نویسان اجازه می دهند دستورالعمل هایی بنویسند که بسیار شبیه انگلیسی روزمره و شامل نمادهای ریاضی معمول هستند . مانند :GrossPay = BasePay + OverTimePay