arash_ebrahimi_nk
سه شنبه 14 خرداد 1392, 13:14 عصر
سلام خدمت دوستان عزیز. میخوام اندک اطلاعاتی که در مورد مبهم سازی یا پیچیده کردن کُدهای دارم رو توی این تاپیک به اشتراک بذارم. امیدوارم مورد استفاده دوستان قرار بگیره.
قبل از شروع مطلب این رو بگم که برنامه های NET. بحثشون جداست و صد البته مبهم سازی براشون اهمیت بیشتری داره ولی من در ادامه فقط درباره مبهم سازی کُدهای باینری صحبت میکنم.
مبهم سازی کُد چیه؟ و فایدش چیه؟
اگه شما برید چند تا از این فیلم های آموزشی کرک رو ببینید متوجه میشد که وقتی یه کرکر میخواد یه برنامه رو کرک کنه اول دنبال جایی میگرده که باید کرک رو از اونجا شروع کنه (منظور این که یه کرکر نمیاد از اولین خط برنامه شروع بکنه و خط به خط بره جلو تا به نقطه کرک کردن برسه). بنابراین یه کرکر سرنخ ها رو مثل یه کارگاه دنبال میکنه تا به نقاط مورد نظر خودش برسه (حالا چقدر کارگاه خوبیه دیگه به تجربه و اطلاعات خودش برمیگرده). خب حالا اگه شما رد پاها رو پاک یا مدارک رو مخدوش کنید شاید بتونید از دستش دربرید!
بذارید به جای حرف زدن یه مقدار کُد بذارم:
فرض کنید شما یه تابع دارید که شماره سریال رو از رجیستری براتون میخونه و اسمش هست ReadSnFromReg که آدرس حقیقی اون توی برنامه های دیباگر میشه 005B15F0.
حالا شما از این تابع سه چهار بار درجاهای مختلف استفاده میکنید که شماره سریال رو باهاش چک بکنید.
کرکر در یکی از توابع چک کردن شما، داستان خوندن و چک کردن شماره سریال رو پیدا و اون رو کرک میکنه.
حالا وقتی برنامه رو امتحان میکنه بطور کامل موفق نمیشه چون دو سه جای دیگه هم وجود داره که باید کرک کنه.
بنابراین میاد تا جاهای دیگه رو پیدا کنه و میره توی برنامه دیباگر روی آدرس حقیقی تابع شما راست کلیک کرده و (برای مثال) گزینه Find Same Addresses رو میزنه و برنامه دیباگر جاهای دیگه ای که تابع ReadSnFromReg استفاده شده رو بهش نشون میده، حالا به راحتی جاهای دیگه رو هم کرک کرده و برنامه رو کامل کرک شده تحویل میده.
خب در اینجا کُدهای یه ترفند ساده رو مینویسم که میتونه از جستجوی یه آدرس (به روش فوق) جلوگیری کنه.
با فرض اینکه کُد اصلی به این صورت باشه:
S := ReadSnFromReg;
کُد اسمبلیش رو از توی محیطی که توش برنامه مینویسن در بیارید و کپی پیستش کنید.
http://s2.picofile.com/file/7790200321/Code1.png
یه نگاه با دیباگر هم بهش بندازید بد نیست.
http://s2.picofile.com/file/7790211177/Debug1.png
وقتی توی دیباگر بهش نگاه میکنید میبینید که آدرس واقعی (005B15F0) نشون داده میشه بنابراین همونطور که قبلا گفتیم برنامه دیباگر میتونه این آدرس واقعی رو در جاهای دیگه هم پیدا کنه.
خب حالا اگه ما کُد اصلی رو که اسمبلیش به این صورت هست:
asm
lea eax, [ebp-$08]
call ReadSnFromReg
end;
کمی بپیچونیم:
asm
lea eax, [ebp-$08]
mov ecx, offset ReadSnFromReg + 500
sub ecx, 500
call ecx
end;
به نظرتون توی دیباگر چی میبینیم:
http://s2.picofile.com/file/7790234080/Debug2.png
خب همونطور که ملاحظه میکنید دیباگر آدرس واقعی تابع ReadSnFromReg رو نشون نمیده و اگه هم از جای دیگه ای آدرس واقعی جستجو بشه در این قسمت چیزی پیدا نمیشه.
تنها کاری که ما انجام دادیم این بود که آدرس واقعی (005B15F0 = offset ReadSnFromReg) رو به اضافه 500 کردیم و وقتی برنامه کامپایل شد عدد محاسبه شده (005B17E4) در دیباگر نشون داده شد به همین خاطر دیگه جستجوی آدرس واقعی (005B15F0) در این قسمت بی نتیجه میشه چون توی کُدهای حقیقی، این آدرس نوشته نشده که در صورت جستجو بشه پیداش کرد!
خب ما با روش بالا سرنخ پیدا کردن یک تابع رو مخدوش کردیم.
ادامه میدم... فعلا...
قبل از شروع مطلب این رو بگم که برنامه های NET. بحثشون جداست و صد البته مبهم سازی براشون اهمیت بیشتری داره ولی من در ادامه فقط درباره مبهم سازی کُدهای باینری صحبت میکنم.
مبهم سازی کُد چیه؟ و فایدش چیه؟
اگه شما برید چند تا از این فیلم های آموزشی کرک رو ببینید متوجه میشد که وقتی یه کرکر میخواد یه برنامه رو کرک کنه اول دنبال جایی میگرده که باید کرک رو از اونجا شروع کنه (منظور این که یه کرکر نمیاد از اولین خط برنامه شروع بکنه و خط به خط بره جلو تا به نقطه کرک کردن برسه). بنابراین یه کرکر سرنخ ها رو مثل یه کارگاه دنبال میکنه تا به نقاط مورد نظر خودش برسه (حالا چقدر کارگاه خوبیه دیگه به تجربه و اطلاعات خودش برمیگرده). خب حالا اگه شما رد پاها رو پاک یا مدارک رو مخدوش کنید شاید بتونید از دستش دربرید!
بذارید به جای حرف زدن یه مقدار کُد بذارم:
فرض کنید شما یه تابع دارید که شماره سریال رو از رجیستری براتون میخونه و اسمش هست ReadSnFromReg که آدرس حقیقی اون توی برنامه های دیباگر میشه 005B15F0.
حالا شما از این تابع سه چهار بار درجاهای مختلف استفاده میکنید که شماره سریال رو باهاش چک بکنید.
کرکر در یکی از توابع چک کردن شما، داستان خوندن و چک کردن شماره سریال رو پیدا و اون رو کرک میکنه.
حالا وقتی برنامه رو امتحان میکنه بطور کامل موفق نمیشه چون دو سه جای دیگه هم وجود داره که باید کرک کنه.
بنابراین میاد تا جاهای دیگه رو پیدا کنه و میره توی برنامه دیباگر روی آدرس حقیقی تابع شما راست کلیک کرده و (برای مثال) گزینه Find Same Addresses رو میزنه و برنامه دیباگر جاهای دیگه ای که تابع ReadSnFromReg استفاده شده رو بهش نشون میده، حالا به راحتی جاهای دیگه رو هم کرک کرده و برنامه رو کامل کرک شده تحویل میده.
خب در اینجا کُدهای یه ترفند ساده رو مینویسم که میتونه از جستجوی یه آدرس (به روش فوق) جلوگیری کنه.
با فرض اینکه کُد اصلی به این صورت باشه:
S := ReadSnFromReg;
کُد اسمبلیش رو از توی محیطی که توش برنامه مینویسن در بیارید و کپی پیستش کنید.
http://s2.picofile.com/file/7790200321/Code1.png
یه نگاه با دیباگر هم بهش بندازید بد نیست.
http://s2.picofile.com/file/7790211177/Debug1.png
وقتی توی دیباگر بهش نگاه میکنید میبینید که آدرس واقعی (005B15F0) نشون داده میشه بنابراین همونطور که قبلا گفتیم برنامه دیباگر میتونه این آدرس واقعی رو در جاهای دیگه هم پیدا کنه.
خب حالا اگه ما کُد اصلی رو که اسمبلیش به این صورت هست:
asm
lea eax, [ebp-$08]
call ReadSnFromReg
end;
کمی بپیچونیم:
asm
lea eax, [ebp-$08]
mov ecx, offset ReadSnFromReg + 500
sub ecx, 500
call ecx
end;
به نظرتون توی دیباگر چی میبینیم:
http://s2.picofile.com/file/7790234080/Debug2.png
خب همونطور که ملاحظه میکنید دیباگر آدرس واقعی تابع ReadSnFromReg رو نشون نمیده و اگه هم از جای دیگه ای آدرس واقعی جستجو بشه در این قسمت چیزی پیدا نمیشه.
تنها کاری که ما انجام دادیم این بود که آدرس واقعی (005B15F0 = offset ReadSnFromReg) رو به اضافه 500 کردیم و وقتی برنامه کامپایل شد عدد محاسبه شده (005B17E4) در دیباگر نشون داده شد به همین خاطر دیگه جستجوی آدرس واقعی (005B15F0) در این قسمت بی نتیجه میشه چون توی کُدهای حقیقی، این آدرس نوشته نشده که در صورت جستجو بشه پیداش کرد!
خب ما با روش بالا سرنخ پیدا کردن یک تابع رو مخدوش کردیم.
ادامه میدم... فعلا...