示例#1
0
        public ContextManager(String name, Logger loggerInstance, Specifics specificsInstance,
            Func<ContextManager, int, Win32Imports.ContextX64, bool, ContextTracer.TraceReturn> breakPointCallBack,
            ImportResolver importResolver) {

            LoggerInstance = loggerInstance;
            BreakPointCallBack = breakPointCallBack;
            _importResolver = importResolver;

            setDebugPrivilege();

            CurrentProcess = DebugProcessUtils.GetFirstProcessByName(name);

            foreach (ProcessThread thread in CurrentProcess.Threads) {
                loggerInstance.WriteLine($"main thread: {thread.Id}");
                break;
            }

            SpecificsInstance = specificsInstance;

            Console.WriteLine("debugger");

            Console.WriteLine("pid: " + CurrentProcess.Id);

#if RestartEachTime
            // Attach to the process we provided the thread as an argument
            if (!Win32Imports.DebugActiveProcess(CurrentProcess.Id)) {
                    throw new Win32Exception();
                }

                if (!Win32Imports.DebugSetProcessKillOnExit(false)) {
                    throw new Win32Exception();
                }

                ClearEvents();
            }
示例#2
0
        public List<ThreadData> GetContexts() {

            // Attach to the process we provided the thread as an argument
#if RestartEachTime
#if UseDebugger
            if (!Win32Imports.DebugActiveProcess(CurrentProcess.Id)) {
                throw new Win32Exception();
            }

            if (!Win32Imports.DebugSetProcessKillOnExit(false)) {
                throw new Win32Exception();
            }
#endif
#endif

            var retval = new List<ThreadData>();

            //CONTEXT_X64 context = new CONTEXT_X64();
            Win32Imports.ContextX64 context = new Win32Imports.ContextX64();

            foreach (ProcessThread thread in CurrentProcess.Threads) {
                uint iThreadId = (uint)thread.Id;

                getRip(iThreadId, ref context, GetRipAction.ActionGetContext);
                //Console.WriteLine($"Rip: {Rip}");
                retval.Add(new ThreadData() {
                    ThreadId = iThreadId,
                    Rip = context.Rip
                });

                //Console.WriteLine($"thread id: {iThreadId}");
                //Console.WriteLine($"RIP: {context.Rip}");
            }

#if RestartEachTime
#if UseDebugger
            if (!Win32Imports.DebugActiveProcessStop(CurrentProcess.Id))
            {
                throw new Win32Exception();
            }
#endif
#endif
            return retval;
        }
示例#3
0
        // remember to set targetAddress before using this function
        public List<ThreadData> TestBreak() {

#if RestartEachTime
#if UseDebugger
            // Attach to the process we provided the thread as an argument
            if (!Win32Imports.DebugActiveProcess(CurrentProcess.Id)) {
                throw new Win32Exception();
            }

            if (!Win32Imports.DebugSetProcessKillOnExit(false)) {
                throw new Win32Exception();
            }
#endif
#endif

        var retval = new List<ThreadData>();
            var context = new Win32Imports.ContextX64();

            //Console.WriteLine("TestBreak");

            if (!CheckBreakPointActive()) {
                //Console.WriteLine("adding breakpoints: " + breakPoints.Keys.Count);

                foreach (var breakPoint in BreakPoints.Keys) {
                    var shouldEnable = BreakPoints[breakPoint].ShouldEnable;
                    //Console.WriteLine($"enumerating breakPoint: 0x{breakPoint}, shouldEnable: {shouldEnable}");
                    if (shouldEnable) {
                        var msg = BreakPoints[breakPoint].Description;
                        Console.WriteLine($"installing continuation breakpoint at {breakPoint:X}: {msg}");
                        LoggerInstance.WriteLine($"installing continuation breakpoint at {breakPoint:X}: {msg}");
                        /*
                        if (!Specifics.useDebugger) {
                            LoggerInstance.WriteLine("Suspending all threads");
                            foreach (ProcessThread thread2 in process.Threads) {
                                getRip((uint)thread2.Id, ref context, ACTION_SUSPEND);
                            }
                        }*/

                        try {
#if UseHardwareBreakPoints
                            foreach (ProcessThread thread in CurrentProcess.Threads) {
                                InstallHardwareBreakPoint((uint) thread.Id, breakPoint);
                            }
#else
                            InstallBreakPoint(breakPoint);
      
#endif
                        }
                        catch (Exception e) {
                            Console.WriteLine($"Exception: {e.Message}");
                            Console.WriteLine(e.StackTrace);
                            LoggerInstance.WriteLine($"Exception: {e.Message}");
                            LoggerInstance.WriteLine(e.StackTrace);
                        }
                    } else {
                        Console.WriteLine("stale breakpoint" + BreakPoints[breakPoint].Description);
                    }
                }
            }

            foreach (ProcessThread thread in CurrentProcess.Threads) {
                uint iThreadId = (uint)thread.Id;

#if UseDebugger
                var traceInterval = Specifics.TraceInterval;
                var waitInterval = Specifics.WaitInterval;

                var sw = new Stopwatch();
                sw.Start();
                // trace program. slows down program a lot
                var done = false;
                foreach (ProcessThread thread2 in CurrentProcess.Threads) {
                    //Console.WriteLine("reinstalling CloseHandle breakpoint");
                    InstallHardwareBreakPoint((uint)thread2.Id,
                        BreakPoints.First(kv => kv.Value.Description.Equals(CloseHandleDescription)).Key);
                }
                while (sw.ElapsedMilliseconds <= traceInterval) {
                    getRip(iThreadId, ref context, GetRipAction.ActionGetContext);
                    var breakAddress = context.Rip;
                    if (BreakPoints.ContainsKey(breakAddress) && BreakPoints[breakAddress].IsActive) {
                        LoggerInstance.WriteLine("setting initial trace");
                        setTrace(iThreadId);
                    }
                    if (ResumeBreak()) {
                        done = true;
                        break;
                    }
                }
                sw.Stop();
                if (!done) {
                    sw = new Stopwatch();
                    sw.Start();
                    // give program time to run without debugging
                    while (sw.ElapsedMilliseconds <= waitInterval) {
                        ResumeBreak(false);
                    }
                    sw.Stop();
                }
#else
                    var sw = new Stopwatch();
                    sw.Start();

                    //getRip(iThreadId, ref context, ACTION_RESUME);

                    while (sw.ElapsedMilliseconds <= Specifics.loopWaitInterval) {
                        foreach (ProcessThread thread2 in CurrentProcess.Threads) {
                            uint iThreadId2 = (uint)thread2.Id;

                            getRip(iThreadId2, ref context, ActionGetContext);

                            var breakAddress = context.Rip;

                            if (BreakPoints.ContainsKey(breakAddress) && BreakPoints[breakAddress].IsActive) {
                                LoggerInstance.WriteLine($"match at {breakAddress:X} for thread {iThreadId2}");

                                setTrace((uint)iThreadId2, true);
                                UninstallBreakPoint(breakAddress);
                                _lastBreakAddress = breakAddress;

                                CurrentInfo.LastContext = context;
                                CurrentInfo.LastContextReady = true;
                                // trace
                                BreakPointCallBack(this, (int)iThreadId2, context, true);
                            }
                        }
                    }

                    //getRip(iThreadId, ref context, ACTION_SUSPEND);

                    sw.Stop();
#endif

            // XXX: ONLY FIRST THREAD
            /*if (Specifics.useDebugger) {
                break;
            }*/
            break;
            }

            /*
            if (!Specifics.useDebugger) {
                foreach (var address in originalCode.Keys) {
                    if (activeBreakPoints[address]) {
                        RemoveBreakPoint(address);
                    }
                }

                if (!Specifics.useDebugger) {
                    LoggerInstance.WriteLine("Resuming all threads");
                    foreach (ProcessThread thread2 in process.Threads) {
                        getRip((uint)thread2.Id, ref context, ACTION_RESUME);
                    }
                }
            }*/

            //ResumeBreak(address);
            //Thread.Sleep(5000);

#if RestartEachTime
#if UseDebugger
            if (!Win32Imports.DebugActiveProcessStop(CurrentProcess.Id)) {
                throw new Win32Exception();
            }
#endif
#endif
            return retval;
        }
示例#4
0
        public static void TraceIt(Process process, ulong patchSite, Logger logger, bool debug, Action <Process, ulong, Logger> installTracer)
        {
            if (debug)
            {
                if (!Win32Imports.DebugActiveProcess(process.Id))
                {
                    throw new Win32Exception();
                }

                if (!Win32Imports.DebugSetProcessKillOnExit(false))
                {
                    throw new Win32Exception();
                }
            }
            foreach (ProcessThread thread in process.Threads)
            {
                var threadId = thread.Id;
                var context  = new Win32Imports.ContextX64();
                ContextManager.getRip((uint)threadId, ref context, ContextManager.GetRipAction.ActionSuspend);
            }

            Console.WriteLine("installing tracer");
            installTracer(process, patchSite, logger);

            var mainThread = 0;

            foreach (ProcessThread thread in process.Threads)
            {
                var threadId     = thread.Id;
                var context      = new Win32Imports.ContextX64();
                var breakAddress = ContextManager.getRip((uint)threadId, ref context, ContextManager.GetRipAction.ActionGetContext);
                var diff         = new BigInteger(breakAddress) - new BigInteger(patchSite);
                diff = diff < 0 ? -diff : diff;
                if (diff < 1000)
                {
                    mainThread = threadId;
                    logger.WriteLine($"thread {threadId} setting Rip to patch site: {patchSite:X}");
                    ContextManager.setRip((uint)threadId, false, patchSite);
                    if (debug)
                    {
                        ContextManager.setTrace((uint)threadId, false);
                    }
                }
                ContextManager.getRip((uint)threadId, ref context, ContextManager.GetRipAction.ActionResume);
            }

            /*if (!Win32Imports.DebugBreakProcess(process.Id)) {
             *  throw new Win32Exception();
             * }*/

            if (debug)
            {
                Dictionary <int, OldState> oldThreadState = new Dictionary <int, OldState>();
                try {
                    while (true)
                    {
                        Win32Imports.DebugEvent evt;
                        if (Win32Imports.WaitForDebugEvent(out evt, -1))
                        {
                            Console.WriteLine($"debug event {evt.dwDebugEventCode}");
                            var continueCode = Win32Imports.DbgContinue;
                            if (evt.dwDebugEventCode == Win32Imports.DebugEventType.ExceptionDebugEvent && evt.dwThreadId == mainThread)
                            {
                                var exceptionAddress = (ulong)evt.Exception.ExceptionRecord.ExceptionAddress.ToInt64();
                                var context          = new Win32Imports.ContextX64();
                                var breakAddress     = ContextManager.getRip((uint)evt.dwThreadId, ref context, ContextManager.GetRipAction.ActionGetContext);
                                var code             = evt.Exception.ExceptionRecord.ExceptionCode;
                                Console.WriteLine($"thread {evt.dwThreadId} break at 0x{exceptionAddress:X} code {code}, 0x{breakAddress:X}");
                                ContextManager.setTrace((uint)evt.dwThreadId);

                                var instr      = AssemblyUtil.Disassemble(process, exceptionAddress);
                                var asm        = AssemblyUtil.FormatInstruction(instr);
                                var strContext = oldThreadState.ContainsKey(evt.dwThreadId) ?
                                                 AssemblyUtil.FormatContextDiff(context, oldThreadState[evt.dwThreadId].Context, oldThreadState[evt.dwThreadId].Instruction) :
                                                 AssemblyUtil.FormatContext(context);
                                logger.WriteLine($"thread {evt.dwThreadId} break at 0x{exceptionAddress:X}, 0x{breakAddress:X} code {code}: {asm}, regs-1: {strContext}");

                                oldThreadState[evt.dwThreadId] = new OldState {
                                    Context     = context,
                                    Instruction = instr
                                };

                                if (code == Win32Imports.ExceptionCodeStatus.ExceptionAccessViolation)
                                {
                                    continueCode = Win32Imports.DbgExceptionNotHandled;
                                }
                            }

                            if (!Win32Imports.ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueCode))
                            {
                                throw new Win32Exception();
                            }
                        }
                    }
                }
                finally {
                    if (!Win32Imports.DebugActiveProcessStop(process.Id))
                    {
                        throw new Win32Exception();
                    }
                }
            }
        }