Beispiel #1
0
        /// <summary>
        /// See <see cref="StepIn"/>.
        /// If there's a call as next instruction, it'll be skipped.
        /// </summary>
        public void StepOver(DebugThread th)
        {
            var code = APIIntermediate.ReadArray <byte>(th.OwnerProcess.Handle, th.CurrentInstruction, DisAsm86.MaximumInstructionLength);

            int instructionLength = 0;
            var instrType         = DisAsm86.GetInstructionType(code, false, out instructionLength);

            /*
             * If there's a call, set a breakpoint right after the call to skip the called subroutine
             */
            if (instrType == InstructionType.Call)
            {
                var bpAddr = IntPtr.Add(th.CurrentInstruction, instructionLength);

                var  tempBreakPoint          = Breakpoints.ByAddress(bpAddr);
                bool keepBpAfterStepComplete = false;
                if (keepBpAfterStepComplete = tempBreakPoint == null)
                {
                    tempBreakPoint = Breakpoints.CreateBreakpoint(bpAddr);
                }

                th.ContinueDebugging();
                Debuggee.WaitForDebugEvent();

                if (!keepBpAfterStepComplete)
                {
                    Breakpoints.Remove(tempBreakPoint);
                }
            }
            else
            {
                StepIn(th);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Removes the breakpoint from the code
        /// </summary>
        public void Disable()
        {
            if (enabled)
            {
                APIIntermediate.RemoveInterrupt(Owner.Handle, Address, originalInstruction);
            }

            enabled = false;
        }
Beispiel #3
0
 /// <summary>
 /// Inserts the breakpoint into the code
 /// </summary>
 public void Enable()
 {
     if (!enabled)
     {
         APIIntermediate.SetInterrupt(Owner.Handle, Address, out originalInstruction);
         enabled             = true;
         temporarilyDisabled = false;
     }
 }
Beispiel #4
0
        void BuildCallStack()
        {
            callstack.Clear();

            var ebp = lastReadCtxt.ebp;

            const int MaxFrames = 128;
            var       proc      = Thread.OwnerProcess;
            var       p         = proc.Handle;

            callstack.Add(new Stackframe(new IntPtr(ebp), new IntPtr(lastReadCtxt.eip)));

            do
            {
                // The return address is stored at ebp+1
                var returnTo = APIIntermediate.Read <uint>(p, new IntPtr(ebp + 4));
                ebp = APIIntermediate.Read <uint>(p, new IntPtr(ebp));

                if (ebp == 0 || returnTo == ebp)
                {
                    break;
                }

                callstack.Add(new Stackframe(new IntPtr(ebp), new IntPtr(returnTo)));
            }while (callstack.Count < MaxFrames);

            string file = "";
            ushort line = 0;

            Console.WriteLine("------------------------\r\nCall stack begin:\r\n------------------------");
            foreach (var sf in callstack)
            {
                Console.Write("0x" + sf.CodeAddress.ToString("X8"));
                if (proc.MainModule.ContainsSymbolData &&
                    proc.MainModule.ModuleMetaInfo.TryDetermineCodeLocation((uint)sf.CodeAddress.ToInt32(), out file, out line))
                {
                    Console.WriteLine(" @ " + file + ":" + line);
                }
                else
                {
                    Console.WriteLine();
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Executes until the currently executed method's point of return has been reached.
        /// </summary>
        public void StepOut(DebugThread th)
        {
            var returnPtr = APIIntermediate.Read <IntPtr>(th.OwnerProcess.Handle, new IntPtr(th.Context.lastReadCtxt.ebp + 4));

            var  tempBreakPoint          = Breakpoints.ByAddress(returnPtr);
            bool keepBpAfterStepComplete = false;

            if (keepBpAfterStepComplete = tempBreakPoint == null)
            {
                tempBreakPoint = Breakpoints.CreateBreakpoint(returnPtr);
            }

            th.ContinueDebugging();
            Debuggee.WaitForDebugEvent();

            if (!keepBpAfterStepComplete)
            {
                Breakpoints.Remove(tempBreakPoint);
            }
        }
Beispiel #6
0
        public DebugProcess(Debuggee dbg, Win32.CREATE_PROCESS_DEBUG_INFO info, uint id, uint threadId)
        {
            this.Debuggee = dbg;
            Handle        = info.hProcess;
            Id            = id == 0 ? API.GetProcessId(Handle) : id;

            var moduleFile = APIIntermediate.GetModulePath(Handle, info.lpBaseOfImage, info.hFile);

            // Deduce main module
            MainModule = new DebugProcessModule(info.lpBaseOfImage, moduleFile, ExecutableMetaInfo.ExtractFrom(moduleFile));
            RegModule(MainModule);

            // Create main thread
            MainThread = new DebugThread(this,
                                         info.hThread,
                                         threadId == 0 ? API.GetThreadId(info.hThread) : threadId,
                                         info.lpStartAddress,
                                         info.lpThreadLocalBase);
            RegThread(MainThread);
        }
Beispiel #7
0
        void HandleDebugEvent(DebugEventData de)
        {
            var p  = ProcessById(de.dwProcessId);
            var th = CurrentThread = p.ThreadById(de.dwThreadId);

            switch (de.dwDebugEventCode)
            {
            case DebugEventCode.EXCEPTION_DEBUG_EVENT:
                HandleException(th, de.Exception);
                break;


            case DebugEventCode.CREATE_PROCESS_DEBUG_EVENT:
                var cpi = de.CreateProcessInfo;

                if (MainProcess != null && de.dwProcessId == MainProcess.Id)
                {
                    API.CloseHandle(cpi.hProcess);
                    API.CloseHandle(cpi.hThread);
                    API.CloseHandle(cpi.hFile);

                    foreach (var l in DDebugger.EventListeners)
                    {
                        l.OnCreateProcess(MainProcess);
                    }
                    break;
                }

                // After a new process was created (also occurs after initial WaitForDebugEvent()!!),
                p = new DebugProcess(this, cpi, de.dwProcessId, de.dwThreadId);

                API.CloseHandle(cpi.hFile);

                // enlist it
                processes.Add(p);

                // and call the listeners
                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnCreateProcess(p);
                }
                break;


            case DebugEventCode.CREATE_THREAD_DEBUG_EVENT:
                p = ProcessById(de.dwProcessId);

                // Create new thread wrapper
                th = CurrentThread = new DebugThread(p,
                                                     de.CreateThread.hThread,
                                                     de.dwThreadId,
                                                     de.CreateThread.lpStartAddress,
                                                     de.CreateThread.lpThreadLocalBase);
                // Register it to main process
                p.RegThread(th);

                // Call listeners
                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnCreateThread(th);
                }
                break;


            case DebugEventCode.EXIT_PROCESS_DEBUG_EVENT:

                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnProcessExit(p, de.ExitProcess.dwExitCode);
                }

                processes.Remove(p);
                p.Dispose();
                break;


            case DebugEventCode.EXIT_THREAD_DEBUG_EVENT:

                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnThreadExit(th, de.ExitThread.dwExitCode);
                }

                p.RemThread(th);
                th.Dispose();
                break;


            case DebugEventCode.LOAD_DLL_DEBUG_EVENT:
                var loadParam = de.LoadDll;

                var modName = APIIntermediate.GetModulePath(p.Handle, loadParam.lpBaseOfDll, loadParam.hFile);
                API.CloseHandle(loadParam.hFile);

                var mod = new DebugProcessModule(loadParam.lpBaseOfDll, modName, ExecutableMetaInfo.ExtractFrom(modName));
                p.RegModule(mod);

                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnModuleLoaded(p, mod);
                }
                break;


            case DebugEventCode.UNLOAD_DLL_DEBUG_EVENT:
                mod = p.ModuleByBase(de.UnloadDll.lpBaseOfDll);

                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnModuleUnloaded(p, mod);
                }

                p.RemModule(mod);
                break;


            case DebugEventCode.OUTPUT_DEBUG_STRING_EVENT:
                var message = APIIntermediate.ReadString(p.Handle,
                                                         de.DebugString.lpDebugStringData,
                                                         de.DebugString.fUnicode == 0 ? Encoding.ASCII : Encoding.Unicode,
                                                         (int)de.DebugString.nDebugStringLength);

                foreach (var l in DDebugger.EventListeners)
                {
                    l.OnDebugOutput(th, message);
                }
                break;
            }
        }
Beispiel #8
0
 internal DebugEventData WaitForDebugEventInternal(uint timeOut)
 {
     lastDebugEvent.ApplyFrom(APIIntermediate.WaitForDebugEvent(timeOut));
     return(lastDebugEvent);
 }