-
Debugger - Disassembler - Decompiler
سلام؛
در ادبیات مرسوم مباحث مرتبط با امنیت نرم افزار ، دیباگر ، نرم افزاری است که امکان بررسی دقیق روند اجرای یک برنامه اجرائی یا کتابخانه یا درایور را فراهم میکند و در این روند ، کنترل کامل و جزئی حافظه ، متغیرها و توابع ، تراکنشهای پردازنده و حافظه و دیسک و ... و ارتباط با کتابخانه های اشتراکی در اختیار دیباگر میباشد .
دیباگر برنامه اجرائی یا کتابخانه یا درایور را با ترتیباتی قابل پیکره بندی فراخوانی میکند ، به توسعه گر یا آزمایش کننده این امکان را میدهد که در مواقع به خصوصی روند اجرا را متوقف یا منوط به وقوع اتفاق خاصی نماید ، یا حافظه را برای کشف مقدار یا مقادیر به خصوصی جستجو کند یا تراکنشهای برنامه با کتابخانه های همراه ، کتابخانه های سیستم عامل ، سخت افزارهای همراه و ...را کنترل نماید . در واقع وظیفهء اصلی یک دیباگر کنترل کامل فرآیند اجرا شدن یا فراخوانی شدن یک برنامه یا کتابخانه اشتراکی است . اطلاعاتی که میتوان با استفاده از دیباگرها بصورت معمول بدست آورد :
- - هر آنچه بین نرم افزار و حافظه اتفاق می افتد . آدرس دهی متغیرها و توابع ، جایگزینی مقادیر ، تخصیص حافظه و آزاد سازی ، محل دستورات زبان ماشین در حافظه ، داده های در حال ارسال به پردازنده و ...
- وضعیت لحظه به لحظهء پردازنده ؛ محتویات رجیسترها و ...
- هر آنچه بین نرم افزار و کتابخانه هائی که از آن تغذیه میکند واقع میگردد . فراخوانی توابع ، کلاسها یا اشیاء ؛ آدرس کتابخانه ها و توابع مربوطه در حافظه و ...
عموم دیباگرها متداول غیر از موارد فوق اطلاعات متنوع دیگری را نیز فراهم میکنند که بسته به مورد و نوع کاربرد متفاوت هستند .
انواع دیباگر ها :: از دید لایهء کاربرد :
- - Application Mode
- Kernel Mode
دیباگرهای Application Mode فقط به Ring3 و فضای User Mode سیستم عامل دسترسی دارند و امکان Resolve آدرسها فقط در این محدوده برایشان موجود است اما دیباگرهای Kernel Mode یا اصطلاحا" Kernel Debugger ها امکان دسترسی به فضای آدرسی Ring0 یا Kernel Space را نیز دارند و در صورت وجود Symbol file های ، امکان Resolve آدرسها در فضای کرنل نیز برایشان وجود دارد .
از دید نوع عملکرد :
- - Source code Level
- Assembler Level
دیباگرهای Source Code Level با استفاده از سورس کد برنامه ، وظایف مذکور رو کنترل و بررسی میکنند و عموما" هنگام توسعهء یک نرم افزار ، به خطا یابی یا ایجاد روندهای کنترل خطای منطقی کمک بسیاری میکنند اما دیباگرهای Assembler Level بدون استفاده یا نیاز به سورس کد و صرفا" با داشتن نسخهء باینری ، وظایفشون رو انجام میدن . امکان کنترل کد ، در سطح Assembler وجود دارد یعنی فرضا" میتوانید روی دستوری مانند Call یا Test یا Mov برنامه مورد نظر یک BreakPoint بگذارید .
دیباگرها اولین وسیله مورد استفاده نفوذگران نرم افزاری است فلذا روتین های آنتی دیباگ همیشه یکی از عناوین مطرح در روشها و ابزارهای حفاظت از نرم افزار هستند . این روتینها عموما" از این روشها برای شناسائی دیباگر استفاده میکنند :
- - استفاده از مشخصات فردی دیباگر : نام پرسه ، مشخصات ثبت شده در رجیستری ، مولفه های هدر و ...
- بررسی حافظه مجازی اختصاص یافته به برنامه و تست وجود دیباگر ( Hook آدرس یا Hook آدرس ِ آدرس ِ توابع دیباگ ویندوز و بررسی وجود پوینتر به آنها یا عدم وجود آن )
- بررسی پردازنده ( مخصوص روتین های Ring0 )
برای تمامی این Trick ها و روشهائی که از هر کدام منشعب میشود ، نیز ، بالتبع روشهای متقابلی وجود دارد ؛ در مجموع چیزی به عنوان متوقف کردن قطعی همه دیباگر ها منطقا" غیر ممکن است ؛ بهترین روتینهای موجود که هر کدوم با مدتها تحقیق و بررسی ارائه شده اند در کمترین زمان ممکن by Pass شدن . استفاده از روتین های آنتی دیباگ برای حفاظت از نرم افزار روش مناسبی برای کند تر کردن فعالیت نفوذگران تازه کار تر است ، نه چیزی بیشتر .
بجای لیست کردن دیباگرها و توضیحات غیر مفید در مورد هر کدوم ، توصیه های شخصی ام رو مینویسم که صرفا" نشان دهندهء دیدگاه خودم است نه چیز دیگر .
- Windbg : دیباگر مایکروسافت . رابط کاربری نسبتا" خوبی داره و به خوبی با Windows Symbol files متصل میشه . مطمئنا" داشتنش برای کسانی که به هر دلیل به دیباگر نیاز دارند یک ضرورته .
- Ollydbg : قدرتمند ترین دیباگر Assembler Level و Application Mode موجود . اسکریپتهای متعددی برای خودکار سازی بسیاری از وظایف توسط افراد مختلف براش نوشته شده . زندگی بدون Olly برای نفوذگران نرم افزاری قطعا" غیر ممکنه . Olly توسط BCB6 توسعه داده شده/میشه .
- SoftICE : قدرتمند ترین دیباگر Kernel Mode که بصورت همزمان Source Level و Assembler Level نیز هست . بجای تکیه بر رابط کاربری ، دستورات پیچیده ای داره که انعطاف بیشتری به روند دیباگ میده . غیر حرفه ای ها نمیتونن رابطهء خوبی باهاش برقرار کنن . نسخ متعددی داره که هر کدوم رو باید تو یه فضای خاص استفاده کرد . بعدا" ممکنه یه تاپیک مجزا براش ایجاد بشه . Visual SoftICE به عنوان آخرین نسخه ارائه شده ، همراه با DriverStudio ی DevPartnet ارائه میشه و امکانات بصری خوبی به نسخه های سنتی SICE اضافه کرده .
- kd : یا Kernel Debugger ، دیباگر استاندارد DDK ویندوز یا Driver development Kit است . یک Kernel Mode درایور که هم بصورت Assembler Level و هم بصورت Source Level کار میکنه . با SICE قابل مقایسه نیست اما چون سازگاری خوبی با Windows Symbol Files داره ، برای دیباگ درایورها فوق العاده مفیده .
دیباگرهای دیگری هم وجود دارن که هر کدوم ممکنه نسبت به موارد فوق مزایا یا نقائصی داشته باشن ؛ لیکن تجربه نشون میده OllyDBG برای اغلب کاربردها ، SICE برای حرفه ای ها و kd نهایتا" برای توسعه گران Ring0 ، همه نیازها رو برطرف میکنند . این مطلب در ادامه به معرفی ویژگیهای Disassembler ها و Decompiler ها خواهد پرداخت . این مطلب قراره الفبای این حوزه رو به کسانی که باهاش غریبه هستن یاد بده ، نه چیزی بیشتر .
-
Disassembler ابزار برای تبدیل کدهای زبان ماشین ، به معادل اسمبلی آنهاست . زبان اسمبلی به عنوان یک زبان سطح پائین ، به ازای یک دستور یا اصطلاحا" Instruction به یک دستور زبان ماشین تبدیل خواهد شد فلذا بازگردوندن کد باینری به معادل اسمبلی اون کار چنان دشواری نیست .
سوال : یک برنامه اجرائی ( PE ) تحت ویندوز داریم که با MASM ( یا Macro Assembler ) نوشته شده است . با یک Disassembler آن را به کدهای اسمبلی تبدیل میکنیم . آیا خروجی لزوما" با کد اسمبلی اولیه یکسان خواهد بود ؟
جواب : لزوما" خیر . Disassembler های امروزی عموما" به اندازه کافی هوشمند و خوب هستند اما نمیشه انتظار داشت "هوش" داشته باشند . این ابزارها با استفاده از Knowledge Base ای که برای کامپایلرهای مختلف داخلشون تعبیه شده ، کدهای باینری رو به معادل اسمبلی تبدیل میکنند اما تضمینی وجود نداره توسعه گر اصلی برنامه ، نیز دقیقا" همین کدها رو نوشته باشه . میزان خطای Disassembler ها رابطه مستقیمی با میزان پیچیدگی و سطح بالا بودن زبان داره . یعنی Disasembler با دریافت ورودی که با MASM یا GCC تولید شده خطای کمتری خواهد داشت نسبت به زمانی که قراره فایل باینری تولید شده توسط دلفی یا VC رو بررسی کنه ؛ خصوصا " اگر کتابخانه های مفصلی مثل VCL و MFC هم استفاده شده باشه ؛ لیکن در مجموع میشه تا حدود زیادی به خروجی Disassembler های امروزی برای درک منطق و روند فعالیت برنامه اعتماد کرد.
سوال : Disassembler چه کاربردهائی دارد ؟
جواب : فرض کنید قرار روتین مقایسهء سریال نامبر یک Protection کودکانه رو بررسی کنید . دیباگر بهتون کمک خواهد کرد تا بتونید نقل و انتقال مقادیر بین متغیرها و محل انجام مقایسه رو پیدا کنید ؛ و Disassembler کمک خواهد کرد با مشاهدهء دقیق و تک تک دستورات ، انتخابهای خوبی برای عبور از اون حفاظ یا تولید یک Patch و دستکاری نسخهء باینری برنامه داشته باشید . برای یک نفوذگر نرم افزاری حرفه ای ، مطالعهء خروجی Disassembler از یک روال حفاظتی ، معادل مطالعهء سورس کده !
Disassembler های معتبر و قابل اتکاء تحت ویندوز یعنی IDA Pro و WinDasm و PView ، دارای امکانات دیگری هم هستند :
- - آنالیز کد و ایجاد ارتباطات بصری بین اجزاء و روتینهای مختلف برنامه ؛ نمایش توالی اجرا توابع و کاربری از اشیاء و ...
- آنالیز کد باینری و تشخیص توابع داخلی بکار برده شده توسط کامپایلرها و ارائه کامنت های مفید
- ارائه کردن امکانات یک دیباگر در کنار Disassembler
- و ...
در مجموع ، Disassembler به عنوان دومین ابزار مهم در حوزهء امنیت نرم افزار ، یکی از عناصر لا ینفک یک روند حرفه ای آنالیز و بررسی باینری است . IDA Pro توسط یک تیم توسعه گر هماهنگ و قدرتمند قدرتمند ترین Disassembler موجود در محیط ویندوز است . ( یک نسخهء مبتنی بر لینوکس هم داره ، لیکن انتظارات نسخهء ویندوزی رو نمیشه ازش داشت ) این محصول با Borland C توسعه داده میشه و یک دورهء فشردهء آموزشی اون توسط خود شرکت توسعه گر ، به مدت چهار روز ، برای هر نفر ، چیزی حدود هزار و پانصد دلار هزینه در بر خواهد داشت . WinDasm دیگه تحت توسعه نیست و نسخه های جدیدتری نخواهد داشت . آخرین نسخه رسمی 8.9 است که دو نسخه 9 و 10 هم توسط افرادی که براش Patch هائی نوشتن منتشر شدن . WinDasm مدتها به عنوان ابزار شمارهء یک استفاده شده ( خصوصا با توجه به گرون قیمت بودن IDA ) و بسیاری از مقالات و راهنماهای موجود مبتنی بر اون نوشته شده اند . IDA Pro با داشتن آنالایزر قدرتمند و امکان شناسائی کتابخانه های مختلف ، داشتن پلاگینها متعدد و قابلیتهای بی شمار ( که بی اغراق امکان نداره حتی بشه در غالب یک کتاب در مورد همشون حرف زد ) بهترین گزینهء موجوده هر چند تسلط به اون حتی برای کسانیکه دانش بالائی دارند واقعا" دشوار و پر هزینه خواهد بود .
موفق باشید
:)
-
Decompiler به لحاظ "تئوریک" یعنی ابزاری برای تبدیل یک برنامهء باینری اجرائی یا یک کتابخانه یا درایور به سورس کد اصلی ؛ قبل از ورود به بحث لازمه یک طبقه بندی از موجودیتهائی که ممکنه ذیل عنوان Decompiler مطرح بشن داشته باشیم :
- - برنامه های اجرائی باینری : برنامه هائی که عموما" با زبانهای سطح بالائی نظیر VC یا دلفی نوشته میشن و به کدهای "مخصوص" به ویندوز/معماری ماشین ( مثلا" Win32/IA32 یعنی ویندوز 32 بیتی روی اینتل 32 بیتی ) ترجمه میشن .
- کتابخانه های اشتراکی : بسته های نرم افزاری که عموما با زبانهای سطح بالا برای کاربری در سایر برنامه ها تولید میشن و وابسته به سیستم عامل و معماری سخت افزاری هستند .
- برنامه های تفسیری : برنامه هائی که قبل از هر بار اجرا باید توسط یک مفسیر ترجمه بشن . به عنوان مثال برنامه های VB6 که بصورت PCode منتشر میشن و هر بار قبل از اجرا توسط VB runtime تفسیر میشن .
- برنامه های مبتنی بر زمان اجرا : برنامه هائی که برای اجرا نیاز به بستر از پیش فراهم شده ای برای روند اجرا دارند . مانند برنامه های دات نت و جاوا .
- درایور ها : کدهای سطح کرنلی که مختص سیستم عامل و معماری سخت افزاری هستند و عموما با زبانهای سطح پائین تولید میشن .
سوال : آیا معنای تئوریک Decompiler برای همه این گروهها محقق شده ؟ میشه ؟ خواهد شد ؟
جواب : خیر .
هیچ Decompiler ای برای گروهای اول و دوم و پنجم ارائه نشده ، نمیشه ، نخواهد شد . یعنی دریافت سورس کد کامل نرم افزارهای اجرائی از نسخه باینری اونها مطلقا" غیر ممکنه . این عدم امکان فنی نیست که در آینده با پیشرفت دانش امکان پذیر بشه ؛ یک نفی منطقی است . یعنی منطقا" امکان باز-تولید سورس کد کامل یک برنامه تولید شده با محیطهائی مثل Delphi یا VC وجود نداشته ، نداره ، نخواهد داشت .
سوال : پس نرم افزارهای متعددی که تحت عنوان Decompiler منتشر میشن چی ؟
جواب : با توجه به تعریف Decompiler ، جواب داده شد .
سوال : در مورد گروه های سوم و چهارم چی ؟
جواب : برای این دو گروه Decompiler وجود داشته و داره ؛ با یک توضیح کوچک . برنامه هائی هستند که میتونن از برنامهء اجرائی VB ( به عنوان نماینده گروه سوم ) یک سورس کامل قابل کامپایل تولید کنند ، اما ، این سورس ، لزوما" قرار نیست همان سورسی باشد که توسعه گران نرم افزار تولید کرده اند ؛ برای دات نت ( نمایندهء گروه چهارم ) نیز Decompiler های متعددی وجود داره ؛ اما هیچکدام قول نمیدهند خروجی آنها لزوما" همان سورس کدی باشد که برنامه از آن تولید شده .
سوال : آیا اصولا" وجود Decompiler لازمه ؟
جواب : برای اهداف مثبت و خیرخواهانه خیر . حتی برای اهداف غیر خیرخواهانه نیز وجود Decompiler یک لازمه نیست . هیچ کسی از وجود ابزاری که بتونه برنامهء او رو به سورس قابل قبولی مبدل کنه خوشحال نخواهد شد ؛ این ابزار کمکی به توسعه نرم افزار نمیکنه و سود اقتصادی ، پیشرفت علمی و افزایش قابلیتهای صنعت نرم افزار رو بیشتر نخواهد کرد . حتی برای اهداف مخرب هم ، وجود چنین ابزاری لازم نیست چون بسیاری از کسانی که در این مسیر فعالیت میکنند برای تخریب امنیت یک نرم افزار نیازی به دست رسی به سورس اون ندارند . کشف نقاط ضعف امنیتی یا عبور از حفاظهای نرم افزار عموما" در محیطهائی اتفاق می افته که سورس وجود نداره و تمام فرآیند تخریب از طریق مهندسی معکوس یا Reverse Engineering انجام میگیرد .
سوال : برنامه هائی که با جاوا و دات نت نوشته میشن چقدر امن هستند ؟
جواب : چون نقطهء صفری وجود نداره ، میزانی قابل ارائه نیست ؛ اما در مقام مقایسه :
- - بررسی و Trace و بازبینی روند اجرا ی برنامه هائی که با محیطهائی نظیر دات نت و جاوا تولید میشوند ، به مراتب دشوار تر از برنامه هائی است که با محیطهائی نظیر دلفی و VC تولید میشوند؛ چرا که وجود Runtime های بزرگی مانند JRE یا CLR باعث میشه پیچیدگی فراخوانی ها ، مدیریت حافظه ، مدیریت ریسمان ها و پردازه ها و غیرهم به مراتب از برنامه های اصطلاحا" Native ( مانند خروجی های VC ) بیشتر باشه . پس فی المثل درک جزئیات فنی یک الگوریتم ، وقتی با دات نت نوشته شده باشه و به خوبی با Framework مخلوط باشه واقعا" دشوار تر از درک جزئیات فنی الگوریتمی که با Delphi کامپایل شده .
- عبور یا تخریب حفاظهای نرم افزارهائی که با زبانهای نظیر جاوا و دات نت نوشته میشن به مراتب آسون تر از برنامه هائی است که با امثال دلفی و VC تولید میشن . چرا که اگر از درک جزئیات یک الگوریتم بگذریم ، وابستگی کامل این برنامه ها به یک لایهء میانی به نام زمان اجرا و عدم وابستگی به عناصر زیر ساختی سستم عامل و پردازنده و سخت افزار و همچنین امکانات بیشتر نفوذگران نرم افزار در تغییر محتویات این برنامه ها باعث میشن از این دیدگاه ، برنامه های Native وضع بهتری داشته باشند .
- ( میگذریم از این حقیقت که برای یک حرفه ای ، اهمیت خاصی نداره که یک برنامه با دلفی کامپایل شده یا Managed CPP )
سوال : روشهای حفاظتی که برای مقابله با Decompiler ها مورد استفاده قرار میگیره چقدر قابل اعتمادند ؟
جواب : برای امثال دات نت و جاوا ، تقریبا" هیچ . برای سایر محیطها ، Decompiler دشمن خطرناکی به حساب نمیاد . فی المثل برنامه ای با عنوان DeDe با Delphi Decompiler مدعی است که یک Decompiler برای دلفی است ؛ اما در واقع تو فقط میتونی یک سری اطلاعات دریافت کنی ؛ و نه سورس کد کامل . ممکنه در برخی موارد این اطلاعات بتونه به یک نفوذگر نرم افزاری کمک خاصی بکنه ؛ اما من حیث مجموع ، اینگونه برنامه ها تهدید خطرناکی به حساب نمیان . بگذریم از این واقعیت که یک نفوذگر نرم افزاری برای حذف روتین حفاظتی نرم افزار یا جستجوی یک سرویس برای نقاط ضعف متداول ، نیازی به یک Decompiler نداره . تمام وقایع تلخی که سالهاست شاهدش هستیم داره تحت شرایطی می افته که هیچ Decompiler ضعیفی هم وجود نداره !
موفق و سر بلند باشید
مجوز های ارسال و ویرایش
- شما نمی توانید موضوع جدید ارسال کنید
- شما نمی توانید به پست ها پاسخ دهید
- شما strong>نمی توانید فایل پیوست ضمیمه کنید
- شما نمی توانید پست های خود را ویرایش کنید
-
قوانین انجمن