zoukankan      html  css  js  c++  java
  • 反调试

     Github上看到的一个Demo:https://github.com/cetfor/AntiDBG

     检测一个Demo是否被调试  无非就是从四个方面进行入手:

      内存   通过查询窗口、父进程、PEB、DbgPort等标志位检测

      CPU   通过CTX标志位进行判断

      时间   通过比较时间确定是否被调试

      异常 各种类型的异常都会走进调试器的处理  如果调试器的话

    /*
     * Anti-DBG is a collection of anti-debugging tricks.
     * gauntlet.c is a sample application you can test under a debugger.
     * The anti-debugging methods are located in antidbg.c
     */
    
    #include "antidbg.h"
    #include "gauntlet.h"
    
     // =======================================================================
    // The Gauntlet
    // =======================================================================
    int main(int argc, char *argv[])
    {
        /*
        This sample application calls all included anti-debugging methods
        one after the other. Your goal is to start from the entry point,
        and debug your way to the end without the debugger closing on you.
        
        Good Luck!
        */
    
        // -------------------------------------------------------------------
        // -- Memory Checks --------------------------------------------------
        // -------------------------------------------------------------------
        /*
        最简单也是最基础的,Windows提供的API接口:IsDebuggerPresent(),这API实际上就是访问PEB的BeingDebugged标志来判断是否处于调试状态。
        */
        //adbg_IsDebuggerPresent();
        /*
        CheckRemoteDebuggerPresent实际上调用了ntdll里面的ZwQueryInformationProcess来检测。这是一个Native API
        */
        //adbg_CheckRemoteDebuggerPresent();
        adbg_CheckWindowName();
        //adbg_NtQueryInformationProcess();
    
        /*
        mov   eax, fs:18h            // TEB Self指针
        mov   eax, fs:[0x30];        // PEB
        movzx eax, [eax + 0x02];    // PEB->BeingDebugged
        */
        //adbg_BeingDebuggedPEB();
        /*
        NtGlobalFlag 也是类似于BeingDebugged的一个标志,在Peb中取出。如果是调试状态下,
    
        NtGlobalFlag的值会是0x70,正常情况下不是。
        */
        //adbg_NtGlobalFlagPEB();
        //adbg_NtSetInformationThread();
    //    adbg_DebugActiveProcess(argv[1]);
    
        // -------------------------------------------------------------------
        // -- CPU Checks -----------------------------------------------------
        // -------------------------------------------------------------------
        adbg_HardwareDebugRegisters();
    //    adbg_MovSS();
    
        // -------------------------------------------------------------------
        // -- Timing Checks --------------------------------------------------
        // -------------------------------------------------------------------
    //    adbg_RDTSC();
    //    adbg_QueryPerformanceCounter();
    //    adbg_GetTickCount();
    
        // -------------------------------------------------------------------
        // -- Exception Checks -----------------------------------------------
        // -------------------------------------------------------------------
    //    adbg_CloseHandleException();
    //    adbg_SingleStepException();
    //    adbg_Int3();
    //    adbg_Int2D();        //这个有惊喜  
        adbg_PrefixHop();
    
        // Your goal is to get here in a debugger without modifying EIP yourself.
        MessageBoxA(NULL, "Congratulations! You made it!", "You Win!", 0);
    
        return 0;
    }
    #include <Windows.h>
    #include "antidbg.h"
    
    #define SHOW_DEBUG_MESSAGES
    
    // =======================================================================
    // Debugging helper
    // =======================================================================
    void DBG_MSG(WORD dbg_code, char* message)
    {
    #ifdef SHOW_DEBUG_MESSAGES
        printf("[MSG-0x%X]: %s
    ", dbg_code, message);
        MessageBoxA(NULL, message, "GAME OVER!", 0);
    #endif
    }
    
    // =======================================================================
    // Memory Checks
    // These checks focus on Windows structures containing information which 
    // can reveal the presence of a debugger. 
    // =======================================================================
    
    /*
     * // adbg_BeingDebuggedPEB()
     *
     * // How it works:
     * Checks the Process Environment Block (PEB) for a "BeingDebugged"
     * field which is set when the process launches under a debugger. This
     * method is exactly what IsDebuggerPresent() checks under the hood,
     * it is simply the assembly version of this call.
     * 
     * // Indication:
     * Look for PEB references.
     * These references typically start with FS:[0x30h]. FS stands for
     * "Frame Segment" and generally indicates references to an application's
     * own internal header structures. These should not raise red flags,
     * however they should be noted.
     *
     * // Bypass:
     * Once the BeingDebugged byte in the PEB is queried, flip the value
     * from 1 to 0 before it is evaluated by the application logic.
     */
    void adbg_BeingDebuggedPEB(void)
    {
        BOOL found = FALSE;
        _asm
        {
            xor eax, eax;            // clear eax
            mov eax, fs:[0x30];        // Reference start of the PEB
            mov eax, [eax + 0x02];    // PEB+2 points to BeingDebugged
            and eax, 0x000000FF;    // only reference one byte
            mov found, eax;            // Copy BeingDebugged into 'found'
        }
    
        if (found)
        {
            DBG_MSG(DBG_BEINGEBUGGEDPEB, "Caught by BeingDebugged PEB check!");
            exit(DBG_BEINGEBUGGEDPEB);
        }
    }
    
    
    /* 
     * // adbg_CheckRemoteDebuggerPresent()
     *
     * // How it works:
     * ...
     * 
     * // Indication: 
     * Look for this imported function or calls to GetProcAddress().
     * CheckRemoteDebuggerPresent is similar to IsDebuggerPresent,
     * except. It allows an applicaion to query the debugging state of
     * another application via a process handle. The BOOL return value
     * is used to determine if the process (hProcess) is being debugged.
     *
     * // Bypass: 
     * Set a breakpoint on CheckRemoteDebuggerPresent(), single step, 
     * then switch the return value to 0.
     */
    void adbg_CheckRemoteDebuggerPresent(void)
    {
        HANDLE hProcess = INVALID_HANDLE_VALUE;
        BOOL found = FALSE;
            
        hProcess = GetCurrentProcess();
        int a = GetLastError();
        CheckRemoteDebuggerPresent(hProcess, &found);
    
        if (found)
        {
            DBG_MSG(DBG_CHECKREMOTEDEBUGGERPRESENT, "Caught by CheckRemoteDebuggerPresent!");
            exit(DBG_CHECKREMOTEDEBUGGERPRESENT);
        }
    }
    
    
    /*
    * // adbg_CheckWindowName()
    *
    * // How it works:
    * Checks for a window with a specific Class name. This name is
    * not the title of the Window. Use tools like Nirsoft Winlister
    * to find this value.
    *
    * // Indication:
    * Look for FindWindow on the imports list or strings of common
    * begugger names. Some exeptions exist, like in the case of IDA
    * whose window Class name is "QWidget" and nothing related to IDA.
    *
    * // Bypass:
    * Set a breakpoint on FindWindow, single step, then
    * switch the return value to 0.
    */
    void adbg_CheckWindowName(void)
    {
        BOOL found = FALSE;
        HANDLE hWindow = NULL;
        wchar_t *WindowClassNameIDA = L"Qt5QWindowIcon";    // IDA Pro
        wchar_t *WindowClassNameOlly = L"OLLYDBG";            // OllyDbg
        wchar_t *WindowClassNameImmunity = L"ID";            // Immunity Debugger
        
        // Check for IDA Pro
        hWindow = FindWindow(WindowClassNameIDA, 0);
        if (hWindow)
        {
            found = TRUE;
        }
        
        // Check for OllyDBG
        hWindow = FindWindow(WindowClassNameOlly, 0);
        if (hWindow)
        {
            found = TRUE;
        }
        
        // Check for Immunity
        hWindow = FindWindow(WindowClassNameImmunity, 0);
        if (hWindow)
        {
            found = TRUE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_FINDWINDOW, "Caught by FindWindow!");
            exit(DBG_FINDWINDOW);
        }
    }
    
    
    /*
     * // adbg_IsDebuggerPresent()
     *
     * // How it works:
     * Checks the PEB structure for the value of BeingDebugged.
     * 
     * // Indication:
     * Look for this imported function or calls to GetProcAddress().
     * IsDebuggerPresent is exported from kernel32.dll. The BOOL return value
     * is used to determine if an application is being debugged.
     *
     * // Bypass:
     * Set a breakpoint on IsDebuggerPresent(), single step, then
     * switch the return value to 0.
     */
    void adbg_IsDebuggerPresent(void)
    {
        BOOL found = FALSE;
        found = IsDebuggerPresent();
    
        if (found)
        {
            DBG_MSG(DBG_ISDEBUGGERPRESENT, "Caught by IsDebuggerPresent!");
            exit(DBG_ISDEBUGGERPRESENT);
        }
    }
    
    
    /*
     * // adbg_NtGlobalFlagPEB()
     *
     * // How it works:
     * 
     * 
     * // Indication:
     * Look for Process Environment Block (PEB) references.
     * These references typically start with FS:[0x30h]. FS stands for
     * "Frame Segment" and generally indicates references to an application's
     * own internal header structures. These should not raise red flags,
     * however they should be noted. 0x68 offset from the PEB is the
     * NtGlobalFlag value. When a process is being debugged, three flags
     * are set, FLG_HEAP_ENABLE_TAIL_CHECK (0x10), FLG_HEAP_ENABLE_FREE_CHECK
     * (0x20), and FLG_HEAP_VALIDATE_PARAMETERS (0x40).
     *
     * // Bypass:
     * ...
     */
    void adbg_NtGlobalFlagPEB(void)
    {
        BOOL found = FALSE;
        _asm
        {
            xor eax, eax;            // clear eax
            mov eax, fs:[0x30];        // Reference start of the PEB
            mov eax, [eax + 0x68];    // PEB+0x68 points to NtGlobalFlags
            and eax, 0x00000070;    // check three flags
            mov found, eax;            // Copy result into 'found'
        }
    
        if (found)
        {
            DBG_MSG(DBG_NTGLOBALFLAGPEB, "Caught by NtGlobalFlag PEB check!");
            exit(DBG_NTGLOBALFLAGPEB);
        }
    }
    
    
    /* 
     * // adbg_NtQueryInformationProcess()
     *
     * // How it works:
     * ... There are two checks here... (1. xxx, 2. NoDebugInherit)
     * 
     * // Indication:
     * ...
     *
     * // Bypass:
     * ...
     */
    void adbg_NtQueryInformationProcess(void)
    {
        HANDLE hProcess = INVALID_HANDLE_VALUE;
        DWORD found = FALSE;
        DWORD ProcessDebugPort = 0x07;    // 1st method; See MSDN for details
        DWORD ProcessDebugFlags = 0x1F;    // 2nd method; See MSDN for details
        
        // Get a handle to ntdll.dll so we can import NtQueryInformationProcess
        HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
        if (hNtdll == INVALID_HANDLE_VALUE || hNtdll == NULL)
        {
            goto CANT_CHECK;
        }
    
        // Dynamically acquire the addres of NtQueryInformationProcess
        _NtQueryInformationProcess NtQueryInformationProcess = NULL;
        NtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
    
        if (NtQueryInformationProcess == NULL)
        {
            goto CANT_CHECK;
        }
    
        // Method 1: Query ProcessDebugPort
        hProcess = GetCurrentProcess();
        NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessDebugPort, &found, sizeof(DWORD), NULL);
    
        if (!status && found)
        {
            DBG_MSG(DBG_NTQUERYINFORMATIONPROCESS, "Caught by NtQueryInformationProcess, (ProcessDebugPort)!");
            exit(DBG_NTQUERYINFORMATIONPROCESS);
        }
    
        // Method 2: Query ProcessDebugFlags
        status = NtQueryInformationProcess(hProcess, ProcessDebugFlags, &found, sizeof(DWORD), NULL);
    
        // The ProcessDebugFlags caused 'found' to be 1 if no debugger is found, so we check !found.
        if (!status && !found)
        {
            DBG_MSG(DBG_NTQUERYINFORMATIONPROCESS, "Caught by NtQueryInformationProcess, (ProcessDebugFlags)!");
            exit(DBG_NTQUERYINFORMATIONPROCESS);
        }
    
        CANT_CHECK:
        _asm
        {
            nop;
        }
    }
    
    
    /*
     * // adbg_NtSetInformationThread()
     *
     * // How it works:
     * Hides the main thread from the debugger. Any attempt to control 
     * the process after this call will end the debugging session.
     *
     * // Indication:
     * ...
     *
     * // Bypass:
     * ...
     */
    void adbg_NtSetInformationThread(void)
    {
        DWORD ThreadHideFromDebugger = 0x11;
    
        // Get a handle to ntdll.dll so we can import NtSetInformationThread
        HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
        if (hNtdll == INVALID_HANDLE_VALUE || hNtdll == NULL)
        {
            goto CANT_CHECK;
        }
    
        // Dynamically acquire the addres of NtSetInformationThread and NtQueryInformationThread
        _NtSetInformationThread NtSetInformationThread = NULL;
        NtSetInformationThread = (_NtSetInformationThread)GetProcAddress(hNtdll, "NtSetInformationThread");
        
        if (NtSetInformationThread == NULL)
        {
            goto CANT_CHECK;
        }
        
        // There is nothing to check here after this call.
        NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, 0, 0);
    
    CANT_CHECK:
        _asm
        {
            nop;
        }
    }
    
    
    /*
    * // adbg_DebugActiveProcess()
    *
    * // How it works:
    * ...
    *
    * // Indication:
    * ...
    *
    * // Bypass:
    * ...
    */
    void adbg_DebugActiveProcess(const char *cpid)
    {
        BOOL found = FALSE;
        STARTUPINFOA si = { 0 };
        PROCESS_INFORMATION pi = { 0 };
        si.cb = sizeof(si);
        TCHAR szPath[MAX_PATH];
        DWORD exitCode = 0;
    
        CreateMutex(NULL, FALSE, L"antidbg");
        if (GetLastError() != ERROR_SUCCESS)
        {
            // If we get here we are in the child process
            if (DebugActiveProcess((DWORD)atoi(cpid)))
            {
                // No debugger found.
                return;
            }
            else
            {
                // Debugger found, exit child with a unique code we can check for.
                exit(555);
            }
        }
    
        // parent process
        DWORD pid = GetCurrentProcessId();
        GetModuleFileName(NULL, szPath, MAX_PATH);
        
        char cmdline[MAX_PATH + 1 + sizeof(int)];
        snprintf(cmdline, sizeof(cmdline), "%ws %d", szPath, pid);
    
        // Start the child process. 
        BOOL success = CreateProcessA(
            NULL,        // path (NULL means use cmdline instead)
            cmdline,    // Command line
            NULL,        // Process handle not inheritable
            NULL,        // Thread handle not inheritable
            FALSE,        // Set handle inheritance to FALSE
            0,            // No creation flags
            NULL,        // Use parent's environment block
            NULL,        // Use parent's starting directory 
            &si,        // Pointer to STARTUPINFO structure
            &pi);        // Pointer to PROCESS_INFORMATION structure
    
        // Wait until child process exits and get the code
        WaitForSingleObject(pi.hProcess, INFINITE);
    
        // Check for our unique exit code
        GetExitCodeProcess(pi.hProcess, &exitCode);
        if (exitCode == 555)
        {
            found = TRUE;
        }
    
        // Close process and thread handles. 
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    
        if (found)
        {
            DBG_MSG(DBG_DEBUGACTIVEPROCESS, "Caught by DebugActiveProcess!");
            exit(DBG_DEBUGACTIVEPROCESS);
        }
    }
    
    // =======================================================================
    // Timing Checks
    // These checks focus on comparison of time stamps between a portion
    // of code which is likely to be analyzed under a debugger. The goal
    // is to determine with high probability that a debugger is allowing
    // single step control, or that a breakpoint had been hit between
    // the time check locations.
    // =======================================================================
    
    /*
     * // adbg_RDTSC()
     *
     * // How it works:
     * ...
     *
     * // Indication:
     * ...
     *
     * // Bypass:
     * ...
     */
    void adbg_RDTSC(void)
    {
        BOOL found = FALSE;
    
        UINT64 timeA, timeB = 0;
        int timeUpperA, timeLowerA = 0;
        int timeUpperB, timeLowerB = 0;
    
        _asm
        {
            // rdtsc stores result across EDX:EAX
            rdtsc;
            mov timeUpperA, edx;
            mov timeLowerA, eax;
    
            // Junk code to entice stepping through or a breakpoint
            xor eax, eax;
            mov eax, 5;
            shr eax, 2;
            sub eax, ebx;
            cmp eax, ecx
    
            rdtsc;
            mov timeUpperB, edx;
            mov timeLowerB, eax;
        }
    
        timeA = timeUpperA;
        timeA = (timeA << 32) | timeLowerA;
    
        timeB = timeUpperB;
        timeB = (timeB << 32) | timeLowerB;
    
        /* 0x10000 is purely empirical and is based on the computer's clock cycle
           This value should be change depending on the length and complexity of 
           code between each RDTSC operation. */
        if (timeB - timeA > 0x10000)
        {
            found = TRUE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_RDTSC, "Caught by RDTSC!");
            exit(DBG_RDTSC);
        }
    }
    
    
    /*
    * // adbg_QueryPerformanceCounter()
    *
    * // How it works:
    * ...
    *
    * // Indication:
    * ...
    *
    * // Bypass:
    * ...
    */
    void adbg_QueryPerformanceCounter(void)
    {
        BOOL found = FALSE;
        LARGE_INTEGER t1;
        LARGE_INTEGER t2;
    
        QueryPerformanceCounter(&t1);
    
        // Junk or legit code.
        _asm
        {
            xor eax, eax;
            push eax;
            push ecx;
            pop eax;
            pop ecx;
            sub ecx, eax;
            shl ecx, 4;
        }
    
        QueryPerformanceCounter(&t2);
    
        // 30 is an empirical value            凭经验  哈哈
        if ((t2.QuadPart - t1.QuadPart) > 30) 
        {
            found = TRUE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_QUERYPERFORMANCECOUNTER, "Caught by QueryPerformanceCounter!");
            exit(DBG_QUERYPERFORMANCECOUNTER);
        }
    }
    
    
    /*
    * // adbg_RDTSC()
    *
    * // How it works:
    * ...
    *
    * // Indication:
    * ...
    *
    * // Bypass:
    * ...
    */
    void adbg_GetTickCount(void)
    {
        BOOL found = FALSE;
        DWORD t1;
        DWORD t2;
    
        t1 = GetTickCount();
    
        // Junk or legit code.
        _asm
        {
            xor eax, eax;
            push eax;
            push ecx;
            pop eax;
            pop ecx;
            sub ecx, eax;
            shl ecx, 4;
        }
    
        t2 = GetTickCount();
    
        // 30 milliseconds is an empirical value
        if ((t2 - t1) > 30)
        {
            found = TRUE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_GETTICKCOUNT, "Caught by GetTickCount!");
            exit(DBG_GETTICKCOUNT);
        }
    }
    
    
    // =======================================================================
    // CPU Checks
    // These checks focus on aspects of the CPU, including hardware break-
    // points, special interrupt opcodes, and flags.
    // =======================================================================
    
    /*
     * // adbg_HardwareDebugRegisters()
     * 
     * // How it works:
     * ...
     * 
     * // Indication:
     * ...
     * 
     * // Bypass:
     * ...
     */
    void adbg_HardwareDebugRegisters(void)
    {
        BOOL found = FALSE;
        CONTEXT ctx = { 0 };
        HANDLE hThread = GetCurrentThread();
    
        ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
        if(GetThreadContext(hThread, &ctx))
        {
            if ((ctx.Dr0 != 0x00) || (ctx.Dr1 != 0x00) || (ctx.Dr2 != 0x00) || (ctx.Dr3 != 0x00) || (ctx.Dr6 != 0x00) || (ctx.Dr7 != 0x00))
            {
                found = TRUE;
            }
        }
    
        if (found)
        {
            DBG_MSG(DBG_HARDWAREDEBUGREGISTERS, "Caught by a Hardware Debug Register Check!");
            exit(DBG_HARDWAREDEBUGREGISTERS);
        }
    }
    
    
    /*
    * // adbg_MovSS()
    *
    * // How it works:
    * ...
    *
    * // Indication:
    * ...
    *
    * // Bypass:
    * ...
    */
    void adbg_MovSS(void)
    {
        BOOL found = FALSE;
        
        _asm
        {
                push ss;
                pop ss;
                pushfd;
                test byte ptr[esp + 1], 1;
                jne fnd;
                jmp end;
            fnd:
                mov found, 1;
            end:
                nop;
        }
    
        if (found)
        {
            DBG_MSG(DBG_MOVSS, "Caught by a MOV SS Single Step Check!");
            exit(DBG_MOVSS);
        }
    }
    
    
    // =======================================================================
    // Exception Checks
    // These checks focus on exceptions that occur when under the control of 
    // a debugger. In several cases, there are certain exceptions that will
    // be thrown only when running under a debugger.
    // =======================================================================
    
    /* 
     * // adbg_CloseHandleException()
     *
     * // How it works:
     * CloseHandle will throw an exception when trying to close an
     * invalid handle, only when running under a debugger. We pass
     * an invalid handle into CloseHandle to force an exception, 
     * where our own exception handler will close the application.
     * 
     * // Indication:
     * Look for possibly invalid handles passed to CloseHandle().
     * The validity of a handle can be difficult to assess, but
     * an application closing shortly after CloseHandle is a great
     * indication.
     *
     * // Bypass:
     * Modify the invalid handle passed into CloseHandle()
     * to be INVALID_HANDLE_VALUE, patch the call, or adjust EIP to
     * skip over the invalid CloseHandle. This may be easier said than
     * done if the CloseHandle is called many times with a mix of
     * valid and invalid handles.
     *
     */
    void adbg_CloseHandleException(void)
    {
        HANDLE hInvalid = (HANDLE)0xDEADBEEF; // an invalid handle
        DWORD found = FALSE;
    
        __try
        {
            CloseHandle(hInvalid);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            found = TRUE;
        }
        
        if (found)
        {
            DBG_MSG(DBG_CLOSEHANDLEEXCEPTION, "Caught by an CloseHandle exception!");
            exit(DBG_CLOSEHANDLEEXCEPTION);
        }
    }
    
    
    /*
     * // adbg_SingleStepException()
     * 
     * // How it works:
     * ...
     *
     * // Indication:
     * ...
     *
     * // Bypass:
     * ...
     *
     */
    void adbg_SingleStepException(void)
    {
        DWORD found = TRUE;
    
        /*
        In this method we force an exception to occur. If it occurs
        outside of a debugger, the __except() handler is called setting
        found to FALSE. If the exception occurs inside of a debugger, the
        __except() will not be called (in certain cases) leading to
        found being TRUE.
        */
    
        __try
        {
            _asm 
            {
                pushfd;                        // save flag register
                or byte ptr[esp + 1], 1;    // set trap flag in EFlags
                popfd;                        // restore flag register
            }
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            found = FALSE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_SINGLESTEPEXCEPTION, "Caught by a Single Step Exception!");
            exit(DBG_SINGLESTEPEXCEPTION);
        }
    }
    
    /*
    * // adbg_Int3()
    *
    * // How it works:
    * INT 3 is a standard software breakpoint (opcode 0xCC). When
    * you set a breakpoint, your debugger replaces the first opcode
    * under the breakpoint location with a 0xCC (INT 3). When the
    * debugger hits this opcode it breaks and restores the original
    * opcode. We add an exeption handler that switches 'found' from
    * true to false. Without a debugger, *something must* handle the
    * breakpoint exception (which is our handler). If our handler does
    * not get hit, it means a debugger attempted to handle the
    * exception itself, an in turn, leaving 'found' marked true.
    *
    * // Indication:
    * Most debuggers go out of their way to hide the fact that they
    * have replaced an opcode with 0xCC. In IDA for example, you need
    * to specifically set an option to show these replacements. If you
    * ever see an INT 3 instruction or a 0xCC (standalone) opcode, 
    * red flags should go up.
    *
    * // Bypass:
    * Most debuggers will give you an option when an exception is 
    * thrown - either pass the exception to the application (and
    * hope it's equipped to handle it), or discard the exception
    * and have the debugger handle it instead. Your debugger is 
    * perfectly capacble of handling a breakpoint exception, but
    * if your debugger handles this exception, 'found' is never
    * marked false, and you're busted. When in doubt, pass
    * exceptions to the application.
    */
    void adbg_Int3(void)
    {
        BOOL found = TRUE;
    
        __try 
        {    
            _asm 
            {
                int 3;    // 0xCC standard software breakpoint
            }
        }
    
        __except (EXCEPTION_EXECUTE_HANDLER) 
        {
            found = FALSE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_INT3CC, "Caught by a rogue INT 3!");
            exit(DBG_INT3CC);
        }
    }
    
    
    /*
    * // adbg_PrefixHop()
    *
    * // How it works:
    * ...
    *
    * // Indication:
    * ...
    *
    * // Bypass:
    * ...
    *
    */
    void adbg_PrefixHop(void)
    {
        BOOL found = TRUE;
    
        __try
        {
            _asm 
            {
                __emit 0xF3;    // 0xF3 0x64 is the prefix 'REP'
                __emit 0x64;
                __emit 0xCC;    // this gets skipped over if being debugged
            }
        }
    
        __except (EXCEPTION_EXECUTE_HANDLER) 
        {
            found = FALSE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_PREFIXHOP, "Caught by a Prefix Hop!");
            exit(DBG_PREFIXHOP);
        }
    }
    
    
    /*
    * // adbg_Int2D()
    *
    * // How it works:
    * ...
    *
    * // Indication:
    * ...
    *
    * // Bypass:
    * ...
    *
    */
    void adbg_Int2D(void)
    {
        BOOL found = TRUE;
    
        __try
        {
            _asm
            {
                int 0x2D;    // kernel breakpoint  VT下有惊喜
            }
        }
    
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            found = FALSE;
        }
    
        if (found)
        {
            DBG_MSG(DBG_NONE, "Caught by a rogue INT 2D!");
            exit(DBG_NONE);
        }
    }
    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    NX二次开发-UF_MODL_ask_angle_tolerance获取建模的角度公差
    NX二次开发-UF_MODL_create_bplane创建有界平面
    NX二次开发-UF_MODL_ask_point_containment获取一个点是在体(面,边)的边界内部,外部,还是边界上
    NX二次开发-UFUN获取相邻面UF_MODL_ask_adjac_faces
    NX二次开发-UFUN链表UF_MODL_create_list等用法
    NX二次开发-UFUN发射线函数UF_MODL_trace_a_ray的用法
    NX二次开发-Ufun C函数例子目录【更新日期2020.7.5】
    NX二次开发-C++time函数计时
    NX二次开发-C++的vector用法
    关于C++里set_intersection(取集合交集)、set_union(取集合并集)、set_difference(取集合差集)等函数的使用总结
  • 原文地址:https://www.cnblogs.com/yifi/p/6526134.html
Copyright © 2011-2022 走看看