
نکته مهم: من مسیر را برایت شرح میدهم، اما عمیق شدن در این مسیر و یادگیری بر عهده خودت است. من وظیفهام فقط نشان دادن سرنخها و هشدارِ موقعیتهای فریبنده است؛ تو هستی که باید با دستوپنجه نرم کردن با بایتها، مسیر را مال خود کنی.
B8 78 56 34 12 C3 55 48 8B EC
حالا
سؤال این است: اینها چه عددهایی هستند؟ شاید بگی «B8» یعنی «۱۸۴» در
دنیای ما. اما اشتباه میکنی. بایتها هیچ عدد ذاتیای ندارند. هر بایت را
بسته به جایگاهش میتوانی جور دیگری بخوانی.
کامپیوتر فقط صفر و یک میفهمد. عدد ۵ برای خودش یعنی ۰۰۰۰۰۱۰۱. این زبان اصلی سختافزار است.
وقتی
بدافزار میخواهد چک کند که آیا یک پرچم فعال است، آن پرچم یک بیت خاص در
یک بایت مشخص است. مثلاً بیت شماره ۳ از سمت راست. اگر آن بیت ۱ باشد، یعنی
«فعال». این یعنی دیدن اعداد به عنوان «مجموعهای از انتخابهای روشن و
خاموش». هر بیت یک تصمیم است.
نکته
فلسفی پنهان: تو داری به یک عدد نگاه میکنی و از آن چندین جواب «بله/خیر»
استخراج میکنی. یعنی یک عدد میتواند همزمان چند خبر داشته باشد. این
شبیه این است که یک جمله واحد، چند معنا داشته باشد بسته به اینکه کجای آن
را نگاه کنی.
هیچ کامپیوتری ذاتی «هگز» نمیفهمد. هگز یک قرارداد انسانی است. چون خواندن
بیست بایت صفر و یک برای انسان سخت است، آمدیم هر چهار بیت را با یک نماد
(۰-۹ و A-F) نشان دادیم.
حالا به همان دوازده بایت اول برگردیم. در هگز میبینیم B8 78 56 34 12. در معماری x86، B8 یعنی «عدد بعدی را در ثبات EAX بارگذاری کن». چهار بایت بعدی (78 56 34 12)
خودشان یک عدد ۳۲ بیتی هستند. اما اینجا یک پیچیدگی وجود دارد: پردازنده
این بایتها را به صورت «little-endian» میخواند، یعنی از راست به چپ.
بنابراین آن چهار بایت در واقع عدد 0x12345678 را تشکیل میدهند.
همین عدد 0x12345678
را اگر در جای دیگری از بدافزار ببینی، ممکن است یک آدرس حافظه باشد، نه
یک مقدار ساده. پس یک رشته یکسان از بایتها میتواند در دو جای مختلف دو
معنی کاملاً متفاوت داشته باشد.
این شبیه کلمه «شیر» در زبان فارسی است: هم حیوان، هم نوشیدنی. بافت حکم میکند.
عدد ۰xFF در هگز یعنی ۲۵۵ در دهدهی. اما خود کامپیوتر به «دویست و پنجاه و پنج» فکر نمیکند. آن را به عنوان هشت بیت با مقدار ۱۱۱۱۱۱۱۱ میبیند. ما انسانها هستیم که برای راحتی میگوییم ۲۵۵.
نکته ظریف: وقتی در دیباگر اندازه یک بافر را میبینی ۱۰۲۴ بایت، این عدد دهدهی
است. اما در حافظه آن ۱۰۲۴ بایت به صورت هگز و باینری ذخیره شدهاند. تو
داری سه لایه تفسیر همزمان را تجربه میکنی: دهدهی برای درک تو، هگز برای
نمایش ابزار، باینری برای اجرای ماشین.
بعضی وقتها به عددی مثل ۰۷۷۷
برمیخوری. این یعنی هشتایی. در لینوکس، مجوز فایل را اینطوری نشان
میدهند. اما خود فایل همچنان بایتها را به صورت باینری نگه داشته. این
فقط یک قرارداد نمایشی دیگر است.
برای
تحلیلگر بدافزار تازهکار، اگر این را دیدی، بدان همین کافی است که بدانی
«این عدد بر پایه ۸ است و هر رقم بین ۰ تا ۷». زیاد گیر نده.
چرا این موضوع برای تحلیل بدافزار مهم است؟
هر بدافزاری یک «تفسیر» از بایتهاست. خود بدافزار هنگام اجرا، بایتهایش را
به عنوان دستورات CPU تفسیر میکند. ابزارهای آنالیز، همان بایتها را به
عنوان داده، رشته، آدرس، یا ساختارهای سطح بالا (مثل جدول import) تفسیر
میکنند.
اگر تو این نکته را درک کنی که «هیچ عددی بدون زمینه معنی ندارد»، دیگر آسان فریب
بدافزارهایی که از تکنیکهای «antidisassembly» استفاده میکنند را
نمیخوری. مثلاً بدافزار عمداً بایتها را طوری میچیند که دیساسمبلر یک
جور بخواند، اما CPU جور دیگر. این یعنی «دعوا بر سر تفسیر».
در یکی از بدافزارهای معروف، تکه کدی را دیدم که وقتی در هگز نگاهش میکردی به نظر میرسید یک دستور CALL است. اما وقتی همان بایتها را با یک آفست متفاوت شروع به خواندن میکردی، تبدیل به دستور XOR
میشدند. فقط کسی میتواند این حقه را بفهمد که میداند یک عدد میتواند
دو دستور متفاوت باشد، فقط بسته به اینکه از کجا شروع به دیدنش کنی.
تمرین مهم :
یک فایل notepad.exe را با یک Hex Editor باز کن. ستون وسط که هگز است. یک جایی را پیدا کن که چند بایت پشت سر هم ببین مثل 54 68 69 73. کنار آن در ستون راست متنی میبینی «This». حالا این سؤال را از خودت بپرس: بایت 54 اگر به حروف تبدیل شود یعنی حرف T. اما اگر به عنوان عدد در نظر گرفته شود یعنی 84 در دهدهی. کدام درست است؟ هر دو درست است. فقط بافت فرق میکند. مثل همون کلمه شیر چند معنا داره معنای اصلی رو خودت باید پیدا کنی
وقتی این را بپذیری، نیمی از رمز و راز بدافزارها برایت روشن میشود.