وبلاگی برای دوست‌داران کامپیوتر
شل کدینگ
سه‌شنبه ۱٦ آبان ۱۳۸٥ ساعت ٩:٢٧ ‎ب.ظ | نوشته ‌شده به دست علی اسماعیلی | ( نظرات )
تصمیم دارم یه سری مطالب در مورد ShellCoding بنویسم. برای شروع از ویندوز شروع میکنم که در دسترس و مورد استفاده ی همه هست. بعد روی سیستم عامل های Open Source کار میکنیم. البته نمیدونم مطالب من تا چه حدی بتونه مورد استفاده شما قرار بگیره، ولی خوب، برای شروع کارتون میتونه راهنمای خوبی باشه.
اول از همه به تفاوت ویندوز و یونیکس میپردازیم. البته از دیدگاه معماری و ساختاری.
تیم ویندوز NT چند تا تصمیم برای طراحی معماری مورد نظرشون داشتن. پروژه ی NT تقریباً از سال 1989 شروع شد و اولین نتیجه ی اون بنام Windows NT 3.1 سال 1991 وارد بازار شد. خیلی از ساختار های داخلی این سیستم از VMS گرفته شده بود، و با اینکه اختلافات زیادی بین این دو سیستم وجود داشت، ولی در طراحی هسته ی NT زمینه هایی از VMS دیده میشد.

Win32 API و PE-COFF
OllyDbg، یه برنامه دیباگر هست که امکانات کاملی برای این کار داره و در سطح اسمبلر هست. این برنامه ابزار خوبی برای تجزیه و تحیلی دودویی ویندوزه. اگه با چنین برنامه ای کار کنید و مفاهیم اونو درک کنید، حتماً نوشته های من براتون روشن تر خواهد بود. این برنامه رو میتونید از آدرس http://home.t-online.de/home/Ollydbg/ دانلود کنید.
API اولیه برای برنامه های ویندوز API ویندوز 32 بیته که یه برنامه نویس لینوکس میتونه اونو بعنوان مجموعه ای از کتابخانه های مشترک موجود در /usr/lib در نظر بگیره.
اگه با API ویندوز آشنایی کمی دارید و یا اصلا در مورد اون اطلاعاتی ندارید، میتونید از آدرس www.winprog.org/tutorial/ یه مقاله ی آموزشی خوب در این مورد ببینید.
یک برنامه نویس لینوکس ماهر، میتونه برنامه ای بنویسه که بطور مستقیم با کرنل ارتباط برقرار کنه. مثلاً با فراخوانی های سیستم مثل Open() یا Write(). این کار رو روی ویندوز نمیشه انجام داد. هر سرویس پک جدیدی که ارائه میشه، رابط کرنل ویندوز رو بکلی عوض میکنه و در کنار اون مجموعه کتابخانه های مربوطه هم عوض میشن (همون DLL های خودمون). DLL ها این امکان رو ایجاد میکنن که یه برنامه یا پردازه بتونه توابعی رو فراخوانی کنه که جزو کد اجرایی خودش نیستن. کد اجرایی تابعی توی یه DLL قرار داره، که شامل یک یا چند تابع کامپایل شده، لینک شده و جدا از پردازه ی فراخواننده هست. API ویندوز بعنوان مجموعه ای از DLL های قدیمی توی ویندوز قرار داده شده و بنابراین هر پردازه ای که از Win32 API استفاده میکنه، به ناچار از اتصال پویا هم استفاده میکنه. اینطوری تیم کرنل ویندوز میتونن API های داخلی رو عوض کنن و توابع پیچیده ی جدید رو به مجموعه خودشون اضافه کنن و در ضمن هنوز API های پایداری برای برنامه نویسان داشته باشن.
مثل هر سیستم عامل پیشرفته ی دیگه ای، ویندوز هم از سیستم فایل قابل تغییر استفاده میکنه که موقع اجرا بارگذاری میشه و عملکرد کتابخانه های مشترک رو تضمین میکنه. در یونیکس، این قسمت میتونه فایل .so باشه، ولی در ویندوز DLL ها این نقش رو بر عهده دارن. درست مثل فایلهای .so که فایل ELF هستن، یک DLL فایل PE-COFF (PE : اجرایی قابل حمل) هست. PE-COFF از فرمت COFF در یونیکس گرفته شده. فایلهای PE قابل حمل هستند چون میشه اونا رو روی هر پلتفرم ویندوز 32 بیت اجرا کرد که PE-Loader این فرمت ها رو قبول میکنه.
خیلی از فایلهای PE قابل جایگزینی هستن. مثل فایلهای ELF، یه فایل PE از بخش های مختلفی تشکیل شده. بخش .reloc رو میتونیم برای جایگزینی DLL توی حافظه استفاده کنیم. هدف بخش .reloc اینه که یه برنامه بتونه از طریق اون دو تا DLL که برای استفاده از یه فضای حافظه طراحی شدن رو بارگذاری کنه.
برخلاف Unix، عادت پیش فرض ویندوز اینه که دنبال فایلهای DLL توی دایرکتوری فعلی بگرده. از دیدگاه یه هکر، این یعنی توانایی فرار از Citrix یا محدودیت های ترمینال سرور، ولی از دیدگاه یه برنامه نویس از این طریق میشه یه DLL که متفاوت از DLL اصلی موجود تو ریشه است رو جابجا کرد. این کار رو DLL-Hell میگن. یه کاربر باید متغیر محیطی PATH رو برای جابجایی DLL ها تنظیم کنه تا تداخلی موقع بارگذاری برنامه ها پیش نیاد.
نکته ی مهمی که باید در مورد PE-COFF یاد بگیریم، RVA یا آدرس مجازی وابسته هستش. RVA ها برای کم کردن کار PE-Loader بکار میرن. توابع میتونن هر جایی از فضای آدرس مجازی ذخیره بشن. اگه PE-Loader بخواد هر آیتم رو دقیقاٌ سر جای خودش قرار بده، نتیجه ی کار خیلی سنگین میشه. با پیشرفت تو یادگیری Win32 خواهید دید که مایکروسافت علاقه ی شدیدی به استفاده از اختصار ها داره، درست بر عکس یونیکس که از خود واژه استفاده میکنه. هر سندی که توسط مایکروسافت منتشر میشه، پر از این اختصارات و عبارات مربوط به اوناست.
RVA در واقع تعریف این جمله است : هر DLL در حافظه وارد یک آدرس پایه میشود، و سپس RVA به آدرس پایه افزوده میشود تا آیتم مربوطه پیدا شود.
پس، برای مثال، تابع malloc() توی DLL ی بنام msvcrt.dll هست. سرآیند msvcrt.dll شامل جدولیه که نشانگر توابع موجود توی فایلDLL هست که Export Rable نامیده میشه. Export Table شامل رشته ایه که malloc و RVA ( برای مثال در 2000) توش خودش داره. بعد از اینکه DLL تو حافظه بارگذاری میشه، مثلاً توی 0x80000000، میتونید تابع malloc رو با رفتن به آدرس 0x80002000 پیدا کنید. آدرس پیش فرض ویندوز NT برای بارگذاری یه فایل EXE از 0x40000000 شروع میشه. البته این مورد با توجه به بسته های زبان و گزینه های کامپایلر میتونه عوض بشه. سمبل های مربوط به فایلهای PE-COFF که توسط مایکروسافت توزیع شدن، معمولاً بیرون از خود سیستم عامل توزیع میشن. میتونید پک های مربوط به هر نسخه از سیستم عامل رو از سایت MSDN پیدا کنید و یا از طریق WinDbg از راه دور به سرور هاشون متصل بشید. OllyDbg هنوز قادر به انجام این کار نیست.
برای مطالعه ی بیشتر روی PE-COFF، توی سایت مایکروسافت عبارت PE-COFF رو تو قسمت جستجو وارد کنید. این نکته رو هم به خاطر داشته باشید که مثل بعضی از یونیکس های قدیمی، توی ویندوز NT نمیتونید فایلی رو که باز هست، پاک کنید.

برچسب‌ها: شل‌ کدینگ

 
لینک دوستان
دیگر موارد