روشهای بررسی وجود یک دیباگر رو میشه از نظر سطح دسترسی ، به دو دستهء Ring 3‌ ( سطح کاربر ) و Ring 0 ( سطح کرنل ) طبقه بندی کرد . سعی میکنم طی چند نوشته کوتاه و حتی الامکان ساده ، روشهای متداول هر کدام از این دسته ها رو معرفی کنم . بدیهیه که این روشها ، شناخته شده و متداول هستند و برای کاربرد مناسب اونها ، باید از خلاقیت استفاده کرد .

شناسائی دیباگر در سطح کاربر

1. استفاده از API های ویندوز : CheckRemoteDebuggerPresent و IsDebuggerPresent . به MSDN مراجعه کنید .

2. استفاده از SEH یا Structured Exception Handling : عموما" هنگام استفاده از یک دیباگر یک یا تعدادی Breakepoint موجوده ؛ اگر نرم افزار دارای Thread خاصی باشه که تو همهء روتینهای برنامه لااقل یکبار فراخوانی بشه و با برانگیختن یک استثناء زمان اجرای مجازی دائما" روتینهای SEH رو فراخوانی کنه ، بالاخره یکجا ، Hardware Breakpoint های دیباگر گیر خواهند افتاد . طبیعیه که این روش باعث کاهش کارائی نرم افزار نمیشه چون صرفا" قسمتهای خاصی که نیاز به حفاظت دارند رو پوشش میده که قاعدتا" بخشهای کوچک و خاصی از برنامه هستند . رجوع به تاپیک همه چیز دربارهء SEH .

3. Process Injection : بررسی مورد دیباگرهای مورد نظر و کسب اطلاع از فضاهای اختصاص نیافتهء حافظه در قسمتهای بالای محدوده آدرسی پروسه اصلی و آنگاه تلاش برای تخصیص حافظه ( VirtualAllocEx ) و دسترسی به این نقاط روی کلیه پروسه های سیستم و بررسی خطاهای بازگردانده شده . اگر و فقط اگر خطای دریافت شده ، دربارهء Commit نشدن آدرس مذکور بود ، دیباگر "مورد نظر" فعال است . رجوع به تاپیک Process Injection .

4. یکی از رکوردهای PEB ( یا Process Environment Block ) بنام NtGlobalFlag اگر 0x70 بود دیباگری وجود دارد . PEB روی ویندوز اکس پی از آدرس 0x7ffdf000 ( یا همان FS:0x30 ) شروع میشه ، روی سایر نسخ ویندوز ممکنه این آدرس تغییر کنه یا کرده باشه یا نکرده باشه ، هر چند عموما" این آدرس ثابته ، اما تضمینی برای این مساله وجود نداره . تابعی برای دریافت PEB :

کد:
کد:
DWORD GetPEB()
{
    DWORD* dwPebBase = NULL;
    /* Return PEB address for current process
       address is located at FS:0x30 */
        __asm 
        {
            push eax
            mov eax, FS:[0x30]
            mov [dwPebBase], eax
            pop eax
        }
    return (DWORD)dwPebBase;
}
( کد رو از Phrack برداشتم ؛ خدایش بیامرزاد )

5. استفاده از ProcessHeap : تابع ProcessHeap همیشه هندل Heap پیش فرض رو برمیگردونه . اگر دیباگری وجود داشته باشه و از یک یا چند Memory Breakpoint هم استفاده کرده باشه ، قاعدتا" قبل از فراخوانی تابعی که قراره حافظه رو تخصیص بده و نهایتا" به اجرای ProcessHeap منجر بشه ( مثلا" malloc روی سی یا new روی دلفی و ... ) آدرس روتین SEH دیباگر بجای آدرس ProcessHeap بازنویسی شده ( که دیباگر بتونه وقوع دسترسی به اون آفست رو درک و شناسائی کنه و دوباره آدرس اصلی ProcessHeap رو جایگزین کنه و برنامه به کنترل عادی برگرده )

ادامه دارد