Beispiel #1
0
        void IFunctionTracer.OnExitBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException)
        {
            FunctionTraceEntryDataItem traceDataItem = bp.GetDataItem <FunctionTraceEntryDataItem>();

            if (OnFunctionExited != null)
            {
                DkmStackWalkFrame  frame        = thread.GetTopStackWalkFrame(bp.RuntimeInstance);
                StackFrameAnalyzer exitAnalyzer = null;
                if (traceDataItem != null)
                {
                    DkmSystemInformationFlags systemInformationFlags =
                        frame.ModuleInstance.Process.SystemInformation.Flags;
                    bool isTarget64Bit = systemInformationFlags.HasFlag(DkmSystemInformationFlags.Is64Bit);
                    int  pointerSize   = (isTarget64Bit) ? 8 : 4;
                    exitAnalyzer = new CachedFrameAnalyzer(
                        frameAnalyzer.Parameters,
                        traceDataItem.EntryArgumentValues,
                        pointerSize);
                }
                OnFunctionExited(frame, exitAnalyzer);
            }

            // Since this was a one-shot breakpoint, it is unconditionally closed.
            bp.Close();
        }
Beispiel #2
0
        public FunctionTracer(DkmNativeInstructionAddress address, StackFrameAnalyzer analyzer)
        {
            this.frameAnalyzer = analyzer;

            DkmProcess process = address.ModuleInstance.Process;

            entryAddress = address;
        }
Beispiel #3
0
        void createProcessTracer_OnFunctionEntered(
            DkmStackWalkFrame frame,
            StackFrameAnalyzer functionAnalyzer,
            out bool suppressExitBreakpoint)
        {
            // If this was not created with CREATE_SUSPENDED, then we can't automatically attach to this
            // child process.
            // TODO(zturner): OR in CREATE_SUSPENDED using WriteProcessMemory, then when the exit bp
            // hits, check if we OR'ed in CREATE_SUSPENDED, and if so, resume the process after the
            // attach.
            ProcessCreationFlags flags = (ProcessCreationFlags)
                                         Convert.ToUInt32(functionAnalyzer.GetArgumentValue(frame, "dwCreationFlags"));

            suppressExitBreakpoint = !flags.HasFlag(ProcessCreationFlags.CREATE_SUSPENDED);
        }
Beispiel #4
0
        void createProcessTracer_OnFunctionExited(
            DkmStackWalkFrame frame,
            StackFrameAnalyzer frameAnalyzer)
        {
            try {
                ulong processInfoAddr = Convert.ToUInt64(
                    frameAnalyzer.GetArgumentValue(frame, "lpProcessInformation"));

                // Check the return address first, it should be in EAX.  CreateProcessAsUser and
                // CreateProcess both return 0 on failure.  If the function failed, there is no child to
                // attach to.
                if (0 == frame.VscxGetRegisterValue32(CpuRegister.Eax))
                {
                    return;
                }

                // The process was successfully created.  Extract the PID from the PROCESS_INFORMATION
                // output param.  An attachment request must happend through the EnvDTE, which can only
                // be accessed from the VsPackage, so a request must be sent via a component message.
                DkmProcess process = frame.Process;
                int        size    = Marshal.SizeOf(typeof(PROCESS_INFORMATION));
                byte[]     buffer  = new byte[size];
                process.ReadMemory(processInfoAddr, DkmReadMemoryFlags.None, buffer);
                PROCESS_INFORMATION info          = MarshalUtility.ByteArrayToStructure <PROCESS_INFORMATION>(buffer);
                DkmCustomMessage    attachRequest = DkmCustomMessage.Create(
                    process.Connection,
                    process,
                    PackageServices.VsPackageMessageGuid,
                    (int)VsPackageMessage.AttachToChild,
                    process.LivePart.Id,
                    info.dwProcessId);
                attachRequest.SendToVsService(PackageServices.DkmComponentEventHandler, false);
            } catch (Exception exception) {
                Logger.LogError(
                    exception,
                    "An error occured handling the exit breakpoint.  HR = 0x{0:X}",
                    exception.HResult);
            }
        }
Beispiel #5
0
        private void HookCreateProcess(DkmNativeModuleInstance module, string export, StackFrameAnalyzer frameAnalyzer)
        {
            try {
                FunctionTracer tracer = new FunctionTracer(
                    module.FindExportName(export, true), frameAnalyzer);
                tracer.OnFunctionEntered += createProcessTracer_OnFunctionEntered;
                tracer.OnFunctionExited  += createProcessTracer_OnFunctionExited;
                tracer.Enable();

                _functionTracers.Add(tracer);
            } catch (DkmException) {
                // For some reason, sandboxed processes act strangely (e.g. FindExportName throws an
                // exception with E_FAIL.  It's not clear why this happens, but these processes can't
                // create child processes anyway, so just handle this failure gracefully.
                return;
            }
        }