Exemple #1
0
        private uint OnLoadDllDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            var LoadDll = DebugEv.u.LoadDll;

            UnsafeMethods.CloseHandle(LoadDll.hFile);
            return(DBG_CONTINUE);
        }
Exemple #2
0
        private uint OnCreateThreadDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            var CreateThread = DebugEv.u.CreateThread;

            openHandles.Add(DebugEv.dwThreadId, CreateThread.hThread);
            return(DBG_CONTINUE);
        }
Exemple #3
0
        private uint OnOutputDebugStringEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            if (!logger.IsTraceEnabled)
            {
                return(DBG_CONTINUE);
            }

            var hProc       = openHandles[DebugEv.dwProcessId];
            var DebugString = DebugEv.u.DebugString;

            int len = DebugString.nDebugStringLength;

            if (DebugString.fUnicode != 0)
            {
                len *= 2;
            }

            byte[] buf = new byte[len];
            uint   lenRead;

            if (!UnsafeMethods.ReadProcessMemory(hProc, DebugString.lpDebugStringData, buf, (uint)len, out lenRead))
            {
                var ex = new Win32Exception(Marshal.GetLastWin32Error());
                logger.Trace("  Failed to read debug string.  {0}.", ex.Message);
            }
            else
            {
                var    encoding = DebugString.fUnicode != 0 ? Encoding.Unicode : Encoding.ISOLatin1;
                string str      = encoding.GetString(buf, 0, (int)lenRead);
                logger.Trace("  {0}", str);
            }
            return(DBG_CONTINUE);
        }
Exemple #4
0
        private uint OnCreateProcessDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            var CreateProcessInfo = DebugEv.u.CreateProcessInfo;

            UnsafeMethods.CloseHandle(CreateProcessInfo.hFile);
            _openHandles.Add(DebugEv.dwProcessId, CreateProcessInfo.hProcess);
            _openHandles.Add(DebugEv.dwThreadId, CreateProcessInfo.hThread);
            return(DBG_CONTINUE);
        }
Exemple #5
0
        private uint OnExitProcessDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            if (dwProcessId == DebugEv.dwProcessId)
            {
                processExit = true;
            }

            _openHandles.Remove(DebugEv.dwProcessId);
            return(DBG_CONTINUE);
        }
Exemple #6
0
        private uint OnExitProcessDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            lock (mutex)
            {
                processHandles.Remove(openHandles[DebugEv.dwProcessId]);
            }

            openHandles.Remove(DebugEv.dwProcessId);
            openHandles.Remove(DebugEv.dwThreadId);

            return(DBG_CONTINUE);
        }
Exemple #7
0
        private uint OnExceptionDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            // Filter for target process id.  It is possible to get a 2nd
            // chance exception for a process that we stopped wanting
            // to monitor after processing a 1st chance exception. Or anytime
            // the ContinueDebugging callback returns false before processExit is true.
            uint result    = DBG_EXCEPTION_NOT_HANDLED;
            var  Exception = DebugEv.u.Exception;

            if (logger.IsTraceEnabled)
            {
                logger.Trace("  {0}", ExceptionToString(Exception));
            }

            bool notify = DebugEv.dwProcessId == this.dwProcessId && HandleAccessViolation != null;

            if (Exception.dwFirstChance == 0 && notify)
            {
                HandleAccessViolation(DebugEv);
                notify = false;
                result = DBG_CONTINUE;
            }

            switch (Exception.ExceptionRecord.ExceptionCode)
            {
            case EXCEPTION_ACCESS_VIOLATION:
                // First chance: Pass this on to the system.
                // Last chance: Display an appropriate error.
                if (notify)
                {
                    HandleAccessViolation(DebugEv);
                }

                break;

            case EXCEPTION_BREAKPOINT:
                // From: http://stackoverflow.com/questions/3799294/im-having-problems-with-waitfordebugevent-exception-debug-event
                // If launch a process and expect to debug it using the Windows API calls,
                // you should know that Windows will send one EXCEPTION_BREAKPOINT (INT3)
                // when it first loads. You must DEBUG_CONTINUE this first breakpoint
                // exception... if you DBG_EXCEPTION_NOT_HANDLED you will get the popup
                // message box: The application failed to initialize properly (0x80000003).
                if (!initialBreak)
                {
                    result = DBG_CONTINUE;
                }

                initialBreak = true;
                break;
            }

            return(result);
        }
Exemple #8
0
        private uint OnCreateProcessDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            var CreateProcessInfo = DebugEv.u.CreateProcessInfo;

            UnsafeMethods.CloseHandle(CreateProcessInfo.hFile);

            lock (mutex)
            {
                processHandles.Add(CreateProcessInfo.hProcess);
            }

            openHandles.Add(DebugEv.dwProcessId, CreateProcessInfo.hProcess);
            openHandles.Add(DebugEv.dwThreadId, CreateProcessInfo.hThread);

            if (ProcessId == DebugEv.dwProcessId && ProcessCreated != null)
            {
                ProcessCreated();
            }

            return(DBG_CONTINUE);
        }
Exemple #9
0
        private uint OnExceptionDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            var Exception = DebugEv.u.Exception;

            if (logger.IsTraceEnabled)
            {
                logger.Trace("  Pid: {0}, Exception: {1}", DebugEv.dwProcessId, ExceptionToString(Exception));
            }

            switch (Exception.ExceptionRecord.ExceptionCode)
            {
            case STATUS_WX86_BREAKPOINT:
            case EXCEPTION_BREAKPOINT:
                // From: http://stackoverflow.com/questions/3799294/im-having-problems-with-waitfordebugevent-exception-debug-event
                // If launch a process and expect to debug it using the Windows API calls,
                // you should know that Windows will send one EXCEPTION_BREAKPOINT (INT3)
                // when it first loads. You must DEBUG_CONTINUE this first breakpoint
                // exception... if you DBG_EXCEPTION_NOT_HANDLED you will get the popup
                // message box: The application failed to initialize properly (0x80000003).
                return(DBG_CONTINUE);
            }

            bool stop = HandleAccessViolation == null ? false : !HandleAccessViolation(DebugEv);

            // If 1st chance, only stop if HandleAccessViolation returns false
            // If 2nd chance, always stop

            // Stop by calling TerminateProcess and continuing
            // so we get thread & process exit notifications
            if (stop || Exception.dwFirstChance == 0)
            {
                TerminateProcess();
                return(DBG_CONTINUE);
            }

            return(DBG_EXCEPTION_NOT_HANDLED);
        }
Exemple #10
0
 private uint OnExitThreadDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
 {
     openHandles.Remove(DebugEv.dwThreadId);
     return(DBG_CONTINUE);
 }
Exemple #11
0
 private uint OnUnloadDllDebugEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
 {
     return(DBG_CONTINUE);
 }
Exemple #12
0
        private uint ProcessDebugEvent(ref UnsafeMethods.DEBUG_EVENT DebugEv)
        {
            uint dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED;

            switch (DebugEv.dwDebugEventCode)
            {
            case UnsafeMethods.DebugEventType.EXCEPTION_DEBUG_EVENT:
                // Process the exception code. When handling
                // exceptions, remember to set the continuation
                // status parameter (dwContinueStatus). This value
                // is used by the ContinueDebugEvent function.
                logger.Trace("EXCEPTION_DEBUG_EVENT");
                dwContinueStatus = OnExceptionDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.CREATE_THREAD_DEBUG_EVENT:
                // As needed, examine or change the thread's registers
                // with the GetThreadContext and SetThreadContext functions;
                // and suspend and resume thread execution with the
                // SuspendThread and ResumeThread functions.

                logger.Trace("CREATE_THREAD_DEBUG_EVENT");
                dwContinueStatus = OnCreateThreadDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.CREATE_PROCESS_DEBUG_EVENT:
                // As needed, examine or change the registers of the
                // process's initial thread with the GetThreadContext and
                // SetThreadContext functions; read from and write to the
                // process's virtual memory with the ReadProcessMemory and
                // WriteProcessMemory functions; and suspend and resume
                // thread execution with the SuspendThread and ResumeThread
                // functions. Be sure to close the handle to the process image
                // file with CloseHandle.

                logger.Trace("CREATE_PROCESS_DEBUG_EVENT");
                dwContinueStatus = OnCreateProcessDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.EXIT_THREAD_DEBUG_EVENT:
                // Display the thread's exit code.

                logger.Trace("EXIT_THREAD_DEBUG_EVENT");
                dwContinueStatus = OnExitThreadDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.EXIT_PROCESS_DEBUG_EVENT:
                // Display the process's exit code.

                logger.Trace("EXIT_PROCESS_DEBUG_EVENT");
                dwContinueStatus = OnExitProcessDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.LOAD_DLL_DEBUG_EVENT:
                // Read the debugging information included in the newly
                // loaded DLL. Be sure to close the handle to the loaded DLL
                // with CloseHandle.

                logger.Trace("LOAD_DLL_DEBUG_EVENT");
                dwContinueStatus = OnLoadDllDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.UNLOAD_DLL_DEBUG_EVENT:
                // Display a message that the DLL has been unloaded.

                logger.Trace("UNLOAD_DLL_DEBUG_EVENT");
                dwContinueStatus = OnUnloadDllDebugEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.OUTPUT_DEBUG_STRING_EVENT:
                // Display the output debugging string.

                logger.Trace("OUTPUT_DEBUG_STRING_EVENT");
                dwContinueStatus = OnOutputDebugStringEvent(DebugEv);
                break;

            case UnsafeMethods.DebugEventType.RIP_EVENT:
                logger.Trace("RIP_EVENT");
                dwContinueStatus = OnRipEvent(DebugEv);
                break;

            default:
                logger.Trace("UNKNOWN DEBUG EVENT: 0x" + DebugEv.dwDebugEventCode.ToString("X8"));
                break;
            }

            return(dwContinueStatus);
        }
Exemple #13
0
 private uint OnOutputDebugStringEvent(UnsafeMethods.DEBUG_EVENT DebugEv)
 {
     return(DBG_CONTINUE);
 }