۰۳-آبان-۱۳۸۷, ۲۰:۲۹:۱۴
توضيح كلي: ديباگر IDA يكي از حرفه اي ترين انواع ديباگر مي باشد كه درنوع خود بي نظير است . ما قصد داريم در اين مقاله چگونگي آنپك كردن برنامه اي را شرح دهيم كه در برابر اين ديباگر قدرتمند ايستادگي مي كند! هر چند در نهايت تسليم نبوغ ما خواهد شد.
سطح : پيشرفته
-----------------------------------------------------------------------------------------
چند روز قبل يك برنامه كوچك بي خطر از طرف يك كاربر حرفه اي IDA دريافت كرديم ( Test )كه نمي شد اون رو توسط IDA ديباگ كرد. بريكپوينت ها عمل نمي كردند و اجراي برنامه از كنترل ما خارج مي شد ،و البته ديباگر اون رو خيلي كند لود و اجرا مي كرد.
وقتي براي اولين بار برنامه رو داخل IDA لود كرديم، متوجه شديم كه حتي نمي تونه ايمپورت تيبل رو هم پيدا كنه. اين وضعيت معمولا هنگام كار با برنامه هاي محافظت شده،كرم هاي پك شده و ... به وجود مياد.
دومين چيز جالب در مورد اين برنامه پرش كردن اينتري پوينت هست ..... به اينجا. آدرس با رنگ قرمز مارك گرفته شده كه معمولا زماني رخ ميده كه IDA نمي تونه مكان اون رو تشخيص بده.
وظيفه اين كد جلوگيري از ديسمبل شدن هست، به همين خاطر پارامترهايي كه به طور پيش فرض لود مي شدند مناسب نخواهند بود.اين نوع كدگذاري اشتباه نشان مي دهد كه مشكلات ذاتي براي دسترسي به موفقيت اوليه وجود دارد.
اما چه خواهد شد اگه مثلا به وسيله لود كردن فايل در حالت كنترل دستي يك بيت پائين تر رو بررسي مي كرديم ؟ در اين حالت كاربر مي تونه تعيين كنه كه كداميك از سكشن ها بايد لود شوند. براي اينكه اشتباهي رخ نده، اجازه دهيد همه سكشن ها رو لود كنيم. فقط اجازه بديد تيك "Make Imports Section" رو برداريم تا پيغام "Missing Imports" ظاهر نشه. خوب چيزي شبيه به اين خواهيم داشت :
يك بار ديگه بايد به سوالاتي در مورد سكشن هايي از فايل كه مي خواهيم ليستشون رو داشته باشيم پاسخ بديم. اينجوري بهتره!!
خوب حالا ما آدرسي كه نمي خواستيم رو انداخيتم دور و مي تونيم برنامه رو آناليز كنيم. اولين دستور فايل اجرايي ما يك دستور پرش هست كه به هدر برنامه پرش مي كنه:
هوووم! هدر برنامه معمولا نبايد شامل هيچ كدي باشه اما برنامه داره از اين روال سو استفاده و به اونجا پرش مي كنه. نكته ظريفي كه در اين كار وجود داره اينه كه هدر برنامه ها فقط_ خواندني هستند. به همين دليل بود كه نمي تونستيم هيچ بريك پوينتي اونجا قرار بديم.
در هر صورت اجازه بديد ببينينم برنامه چطور كار مي كنه.مي بينيم كه برنامه يك پوينتر داخل ESI لود مي كنه كه اون هم به سرعت داخل EBX كپي مي شه:
( كليدهاي تركيبي Ctrl-O اعداد هگزادسيمال رو به اولين دستور داخل ليبل اكسپريژن تبديل مي كنه )
سپس مقدار EBXبراي فراخواني ساب روتين زير استفاده مي شه:
فراخواني هايي زيادي شبيه به اين داخل ليست وجود دارند، پس اجازه بديد تابع رو پيدا كرده و طرز كار اون رو بررسي كنيم. ظاهرا يك پوينتر تابع در اينجا قرار داره:
اگر ما بر روي __ImageBase كليك كنيم، چيزي كه خواهيم ديد آرايه اي از DWords است. IDA ، هدر برنامه رو به صورت يك آرايه ترسيم كرده كه در اين مورد اشتباه است. ما آرايه تعريف شده رو لغو مي كنيم ( كليد سريع U ) ، بر مي گرديم به پوينتر ( كليد سريع Esc) و دوباره پوينتر رو دنبال مي كنيم. اين بار ما به انتهاي اون در آدرس : 0x400130 خواهيم رفت كه بايد شامل يك تابع باشد. ما اطمينان داريم كه همينطور است چراكه دستوري در آدرس : 0x400169 به طور غير مستقيم 0x400130 فراخواني كرده است. كليد P را فشار مي دهيم ( براي ساخت پروسيجر يا تابع) تا به IDA بگيم كه اينجا بايد يك تابع باشد دقيقا در همين آدرس. ماداميكه تابع روي صفحه نمايش ماست، مافقط مي تونيم نيمي از اون رو ببينيم! انگار كسي كه اين برنامه رو نوشته خواسته با تقسيم كردن تابع به چندين قسمت فهم اون رو براي ما دشوار كنه. حالا IDA به خوبي مي دونه چطور اين توابع پراكنده رو تحليل كنه و اطلاعاتي در مورد ديگر بخش هاي تابع رو به ما نشون بده.
اما اين فقط توضيحي در مورد ديگر بخش ها {ي مر بوط به تابع} است. چه خوب بود اگه مي شد تمام تابع رو روي يك صفحه ببينيم. اينجا يك دستور مخصوص براي كمك به ما وجود داره: دستوري كه باعث توليد فلوچارت هاي توابع در IDA مي شود، كليد سريع اون F12 هست.
اين دستور مخصوصا براي توابع چند بخشي نظير تابع ما مفيد خواهد بود چرا كه تمام تكه هاي تابع را روي صفحه نمايش خواهد آورد.
خيلي باحال مي شه اگه تابع اصلي رو به صورت فلوچارت روي صفحه داشته باشيم :
يك نگاه سريع به فلوچارت نشون مي ده كه تابع تنها به يك نقطه ختم مي شود و آن دستور "Ret" هست(0x4001FA). مي تونيم يك بريكپوينت روي اون قرار بديم و اجازه بديم برنامه اجرا بشه. قبل از اينكه اين كار رو انجام بديم، بگذاريد دوباره اين مطلب رو تكرار كنم كه اجراي كدهايي كه به صحت { غير مخرب بودن} اونها اطمينان نداريد كار درستي نيست . خيلي خوبه كه چندين " جعبه ماسه بازي" براي اين جور تست ها داشته باشيد { منظور همون ويرچوال ماشين وديپ فيريز و .... اينهاست!} براي مثال مي تونيد از اين استفاده كنيد : remote debugging facilities IDA Pro offers
در هر صورت، زماني كه مي خواهيد يك فايل جديد را باIDA اجرا و ديباگ كنيد، به شما هشدار خواهد داد، اون رو ايگنورش كنيد.
از آنجائي كه بريكپوينت در قسمت هدر برنامه قرار داره، و هدر برنامه نيز توسط سيستم محافظت مي شود، ما نمي تونيم از يك بريك پوينت نرم افزاري ساده استفاده كنيم. حتما بايد از يك بريكپوينت سخت افزاري استفاده كنيم : ابتدا با استفاده از F2 يك بريكپوينت بسازيد، سپس بر روي آن راست كليك كرده و گزينه " Edit Breakpoint " را براي تغيير دادن آن به يك بريكپوينت سخت افزاري انتخاب نمائيد.
بعد از قرار دادن بريكپوينت،ديباگرمون رو با فشردن F9 استارت مي كنيم. زماني كه به بريكپوينت مي رسيم، برنامه در سگمنت MEW آنپك خواهد شد. ما به اونجا مي پريم و همه چيز رو به كد تبديل مي كنيم ( سريع ترين راه براي انجام اين كار فشردن كليد F7 بر روي بريك پوينت مي باشد )
خوب حالا ما يك ليست خيلي خوب داريم اما با يك مشكل بزرگ: اين ليست سريع از بين مي ره – به محض اينكه سيشن مورد ديباگ رو متوقف كنيم، ليست ناپديد خواهد شد.
دليلش اينه كه اين ليست محتويات حافظه رو به ما نشون مي ده و اين محتويات به محض اينكه پروسه رو ببنديم از بين خواهند رفت.خيلي خوب بود اگه مي شد محتويات حافظه رو داخل ديتابيس ذخيره كنيم و به كار آناليز بدون ديباگر ادامه مي داديم. ما تو اين فكر هستيم كه اين قابليت رو به ورژن هاي آينده IDA اضافه كنيم ، اما الان بايد اين كار رو به صورت دستي انجام بديم. البته منظور ما از روش دستي اين نيست كه بايت به بايت حافظه رو داخل يك صفحه كپي كنيد! ما مي تونيم از بولتين IDC {زبان برنامه نويسي توكار IDC} براي نيل به اين هدف استفاده كنيم.
اينجا دوتا چيز هست كه بايد ذخيره كنيم چرا كه در هنگام متوقف كردن ديباگر ناپديد خواهند شد : محتويات حافظه و نام توابع وارد شده ( Imported Function Names). محتويات حافظه را مي توان با اين اسكريپت چهار خطي ذخيره نمود :
زماني كه اسكريپت رو اجرا كنيم، يك فايل به نام "Bin" بر روي ديسك به وجود مي آيد. اون محتوي بايت هاي سگمت MEW خواهد بود. همانطور كه مي بينيد، من آدرس هاي هگزادسيمال رو داخل اون قرار دادم: بعد از انجام همه اين كارها، كد اسكريپت يكبار مصرفي به دست آمده كه تنها يك بار مي توان آن را اجرا نمود.{ به خاطر اينكه آدرس ها ممكن است در هر باراجراي برنامه تغيير يابند}
همچنين ما بايد نام توابع وارد شده را هم ذخيره نمائيم. به فراخواني كه در آدرس 0x401002 قرار داد نگاه كنيد، براي مثال :
اگر بخواهيم نام تابع فراخواني شده را بدانيم، بايد چندين بار Enter را فشار دهيم تا لينك ها را دنبال نموده و در نهايت نام آن را بدست آوريم :
هر وقت از ديباگر خارج شويم، سگمنت Kernel32.dll از ليست نامها، دستورات، توابع و هر چيزي كه داخل آن وجود دارد تهي خواهد شد. ما بايد ليست نام توابع را قبل از اينكه اين اتفاق رخ دهد كپي نمائيم:
حالا بايد اين دو اسكريپت رو اجرا كنيم، مي تونيم ديباگر رو متوقف كنيم ( Ctrl + F2 ) و از محتويات حافظه كپي تهيه كنيم. دستور "Load Addititional Binary File" در داخل فايل، منويي به شكل زير نمايش داده خواهد شد :
لطفا توجه داشته باشيد كه هيچ احتياجي به ساخت سگمنت نيست، اون از قبل موجود هست ( تيك "Create Segments" رو بر داريد) همچنين احتياجي به تعيين آدرس در پاراگراف نيست ( خود برنامه تعيين مي كند )
فايل رو لود كنيد، كليد Pرا در آدرس0x401000 فشار دهيد و....... اينجا رو ببينيد! شما يه ليست خوب داريد:
مابقي اين آناليز فرايندي خوشايند و دلپذير است كه به عهده خواننده گذارده مي شود ....شما حدس بزنيد.
منبع : http://www.hex-rays.com/idapro/unpack_pe/manual.htm
مترجم :
-------------------------------------------------------------------------------
براي دانلود برنامه IDA به بخش ابزار كرك مراجعه نمائيد.
همچنين مي تونيد نسخه Html آموزش رو همراه با تصاوير به طور كامل از اينجا دانلود نمائيد.
[attachment=1618]
سطح : پيشرفته
-----------------------------------------------------------------------------------------
چند روز قبل يك برنامه كوچك بي خطر از طرف يك كاربر حرفه اي IDA دريافت كرديم ( Test )كه نمي شد اون رو توسط IDA ديباگ كرد. بريكپوينت ها عمل نمي كردند و اجراي برنامه از كنترل ما خارج مي شد ،و البته ديباگر اون رو خيلي كند لود و اجرا مي كرد.
وقتي براي اولين بار برنامه رو داخل IDA لود كرديم، متوجه شديم كه حتي نمي تونه ايمپورت تيبل رو هم پيدا كنه. اين وضعيت معمولا هنگام كار با برنامه هاي محافظت شده،كرم هاي پك شده و ... به وجود مياد.
دومين چيز جالب در مورد اين برنامه پرش كردن اينتري پوينت هست ..... به اينجا. آدرس با رنگ قرمز مارك گرفته شده كه معمولا زماني رخ ميده كه IDA نمي تونه مكان اون رو تشخيص بده.
وظيفه اين كد جلوگيري از ديسمبل شدن هست، به همين خاطر پارامترهايي كه به طور پيش فرض لود مي شدند مناسب نخواهند بود.اين نوع كدگذاري اشتباه نشان مي دهد كه مشكلات ذاتي براي دسترسي به موفقيت اوليه وجود دارد.
اما چه خواهد شد اگه مثلا به وسيله لود كردن فايل در حالت كنترل دستي يك بيت پائين تر رو بررسي مي كرديم ؟ در اين حالت كاربر مي تونه تعيين كنه كه كداميك از سكشن ها بايد لود شوند. براي اينكه اشتباهي رخ نده، اجازه دهيد همه سكشن ها رو لود كنيم. فقط اجازه بديد تيك "Make Imports Section" رو برداريم تا پيغام "Missing Imports" ظاهر نشه. خوب چيزي شبيه به اين خواهيم داشت :
يك بار ديگه بايد به سوالاتي در مورد سكشن هايي از فايل كه مي خواهيم ليستشون رو داشته باشيم پاسخ بديم. اينجوري بهتره!!
خوب حالا ما آدرسي كه نمي خواستيم رو انداخيتم دور و مي تونيم برنامه رو آناليز كنيم. اولين دستور فايل اجرايي ما يك دستور پرش هست كه به هدر برنامه پرش مي كنه:
کد:
loc_400158
هوووم! هدر برنامه معمولا نبايد شامل هيچ كدي باشه اما برنامه داره از اين روال سو استفاده و به اونجا پرش مي كنه. نكته ظريفي كه در اين كار وجود داره اينه كه هدر برنامه ها فقط_ خواندني هستند. به همين دليل بود كه نمي تونستيم هيچ بريك پوينتي اونجا قرار بديم.
در هر صورت اجازه بديد ببينينم برنامه چطور كار مي كنه.مي بينيم كه برنامه يك پوينتر داخل ESI لود مي كنه كه اون هم به سرعت داخل EBX كپي مي شه:
کد:
HEADER:00400158 mov esi, offset off_40601C
HEADER:0040015D mov ebx, esi
( كليدهاي تركيبي Ctrl-O اعداد هگزادسيمال رو به اولين دستور داخل ليبل اكسپريژن تبديل مي كنه )
سپس مقدار EBXبراي فراخواني ساب روتين زير استفاده مي شه:
کد:
HEADER:00400169 call dword ptr [ebx]
فراخواني هايي زيادي شبيه به اين داخل ليست وجود دارند، پس اجازه بديد تابع رو پيدا كرده و طرز كار اون رو بررسي كنيم. ظاهرا يك پوينتر تابع در اينجا قرار داره:
کد:
__u_____:0040601C off_40601C dd offset __ImageBase+130h
اگر ما بر روي __ImageBase كليك كنيم، چيزي كه خواهيم ديد آرايه اي از DWords است. IDA ، هدر برنامه رو به صورت يك آرايه ترسيم كرده كه در اين مورد اشتباه است. ما آرايه تعريف شده رو لغو مي كنيم ( كليد سريع U ) ، بر مي گرديم به پوينتر ( كليد سريع Esc) و دوباره پوينتر رو دنبال مي كنيم. اين بار ما به انتهاي اون در آدرس : 0x400130 خواهيم رفت كه بايد شامل يك تابع باشد. ما اطمينان داريم كه همينطور است چراكه دستوري در آدرس : 0x400169 به طور غير مستقيم 0x400130 فراخواني كرده است. كليد P را فشار مي دهيم ( براي ساخت پروسيجر يا تابع) تا به IDA بگيم كه اينجا بايد يك تابع باشد دقيقا در همين آدرس. ماداميكه تابع روي صفحه نمايش ماست، مافقط مي تونيم نيمي از اون رو ببينيم! انگار كسي كه اين برنامه رو نوشته خواسته با تقسيم كردن تابع به چندين قسمت فهم اون رو براي ما دشوار كنه. حالا IDA به خوبي مي دونه چطور اين توابع پراكنده رو تحليل كنه و اطلاعاتي در مورد ديگر بخش هاي تابع رو به ما نشون بده.
اما اين فقط توضيحي در مورد ديگر بخش ها {ي مر بوط به تابع} است. چه خوب بود اگه مي شد تمام تابع رو روي يك صفحه ببينيم. اينجا يك دستور مخصوص براي كمك به ما وجود داره: دستوري كه باعث توليد فلوچارت هاي توابع در IDA مي شود، كليد سريع اون F12 هست.
اين دستور مخصوصا براي توابع چند بخشي نظير تابع ما مفيد خواهد بود چرا كه تمام تكه هاي تابع را روي صفحه نمايش خواهد آورد.
خيلي باحال مي شه اگه تابع اصلي رو به صورت فلوچارت روي صفحه داشته باشيم :
يك نگاه سريع به فلوچارت نشون مي ده كه تابع تنها به يك نقطه ختم مي شود و آن دستور "Ret" هست(0x4001FA). مي تونيم يك بريكپوينت روي اون قرار بديم و اجازه بديم برنامه اجرا بشه. قبل از اينكه اين كار رو انجام بديم، بگذاريد دوباره اين مطلب رو تكرار كنم كه اجراي كدهايي كه به صحت { غير مخرب بودن} اونها اطمينان نداريد كار درستي نيست . خيلي خوبه كه چندين " جعبه ماسه بازي" براي اين جور تست ها داشته باشيد { منظور همون ويرچوال ماشين وديپ فيريز و .... اينهاست!} براي مثال مي تونيد از اين استفاده كنيد : remote debugging facilities IDA Pro offers
در هر صورت، زماني كه مي خواهيد يك فايل جديد را باIDA اجرا و ديباگ كنيد، به شما هشدار خواهد داد، اون رو ايگنورش كنيد.
از آنجائي كه بريكپوينت در قسمت هدر برنامه قرار داره، و هدر برنامه نيز توسط سيستم محافظت مي شود، ما نمي تونيم از يك بريك پوينت نرم افزاري ساده استفاده كنيم. حتما بايد از يك بريكپوينت سخت افزاري استفاده كنيم : ابتدا با استفاده از F2 يك بريكپوينت بسازيد، سپس بر روي آن راست كليك كرده و گزينه " Edit Breakpoint " را براي تغيير دادن آن به يك بريكپوينت سخت افزاري انتخاب نمائيد.
بعد از قرار دادن بريكپوينت،ديباگرمون رو با فشردن F9 استارت مي كنيم. زماني كه به بريكپوينت مي رسيم، برنامه در سگمنت MEW آنپك خواهد شد. ما به اونجا مي پريم و همه چيز رو به كد تبديل مي كنيم ( سريع ترين راه براي انجام اين كار فشردن كليد F7 بر روي بريك پوينت مي باشد )
خوب حالا ما يك ليست خيلي خوب داريم اما با يك مشكل بزرگ: اين ليست سريع از بين مي ره – به محض اينكه سيشن مورد ديباگ رو متوقف كنيم، ليست ناپديد خواهد شد.
دليلش اينه كه اين ليست محتويات حافظه رو به ما نشون مي ده و اين محتويات به محض اينكه پروسه رو ببنديم از بين خواهند رفت.خيلي خوب بود اگه مي شد محتويات حافظه رو داخل ديتابيس ذخيره كنيم و به كار آناليز بدون ديباگر ادامه مي داديم. ما تو اين فكر هستيم كه اين قابليت رو به ورژن هاي آينده IDA اضافه كنيم ، اما الان بايد اين كار رو به صورت دستي انجام بديم. البته منظور ما از روش دستي اين نيست كه بايت به بايت حافظه رو داخل يك صفحه كپي كنيد! ما مي تونيم از بولتين IDC {زبان برنامه نويسي توكار IDC} براي نيل به اين هدف استفاده كنيم.
اينجا دوتا چيز هست كه بايد ذخيره كنيم چرا كه در هنگام متوقف كردن ديباگر ناپديد خواهند شد : محتويات حافظه و نام توابع وارد شده ( Imported Function Names). محتويات حافظه را مي توان با اين اسكريپت چهار خطي ذخيره نمود :
کد:
auto fp, ea;
fp = fopen("bin", "wb");
for ( ea=0x401000; ea < 0x406000; ea++ )
fputc(Byte(ea), fp);
زماني كه اسكريپت رو اجرا كنيم، يك فايل به نام "Bin" بر روي ديسك به وجود مي آيد. اون محتوي بايت هاي سگمت MEW خواهد بود. همانطور كه مي بينيد، من آدرس هاي هگزادسيمال رو داخل اون قرار دادم: بعد از انجام همه اين كارها، كد اسكريپت يكبار مصرفي به دست آمده كه تنها يك بار مي توان آن را اجرا نمود.{ به خاطر اينكه آدرس ها ممكن است در هر باراجراي برنامه تغيير يابند}
همچنين ما بايد نام توابع وارد شده را هم ذخيره نمائيم. به فراخواني كه در آدرس 0x401002 قرار داد نگاه كنيد، براي مثال :
کد:
MEW:00401002 call sub_4012DC
اگر بخواهيم نام تابع فراخواني شده را بدانيم، بايد چندين بار Enter را فشار دهيم تا لينك ها را دنبال نموده و در نهايت نام آن را بدست آوريم :
کد:
kernel32.dll:77E7AD86
kernel32.dll:77E7AD86 kernel32_GetModuleHandleA: ; CODE XREF: sub_4012DCj
kernel32.dll:77E7AD86 ; DATA XREF: MEW:off_402000o
kernel32.dll:77E7AD86 cmp dword ptr [esp+4], 0
هر وقت از ديباگر خارج شويم، سگمنت Kernel32.dll از ليست نامها، دستورات، توابع و هر چيزي كه داخل آن وجود دارد تهي خواهد شد. ما بايد ليست نام توابع را قبل از اينكه اين اتفاق رخ دهد كپي نمائيم:
کد:
auto ea, name;
for (ea = 0x401270; ea<0x4012e2; ea =ea+6 )
{
name = Name(Dword(Dfirst(ea))); /* به دست آوردن نام*/
name = substr(name, strstr(name, "_")+1, -1); /* قرار دادن پيشوند */
MakeName(ea, name);
}
حالا بايد اين دو اسكريپت رو اجرا كنيم، مي تونيم ديباگر رو متوقف كنيم ( Ctrl + F2 ) و از محتويات حافظه كپي تهيه كنيم. دستور "Load Addititional Binary File" در داخل فايل، منويي به شكل زير نمايش داده خواهد شد :
لطفا توجه داشته باشيد كه هيچ احتياجي به ساخت سگمنت نيست، اون از قبل موجود هست ( تيك "Create Segments" رو بر داريد) همچنين احتياجي به تعيين آدرس در پاراگراف نيست ( خود برنامه تعيين مي كند )
فايل رو لود كنيد، كليد Pرا در آدرس0x401000 فشار دهيد و....... اينجا رو ببينيد! شما يه ليست خوب داريد:
مابقي اين آناليز فرايندي خوشايند و دلپذير است كه به عهده خواننده گذارده مي شود ....شما حدس بزنيد.
منبع : http://www.hex-rays.com/idapro/unpack_pe/manual.htm
مترجم :
...:: DiDi ::....
-------------------------------------------------------------------------------
براي دانلود برنامه IDA به بخش ابزار كرك مراجعه نمائيد.
همچنين مي تونيد نسخه Html آموزش رو همراه با تصاوير به طور كامل از اينجا دانلود نمائيد.
[attachment=1618]