Exemplo n.º 1
0
        /// <summary>
        /// Gets the thread's context.
        /// </summary>
        /// <returns>A CONTEXT struct.</returns>
        public ContextAmd64 GetContext(ContextFlagsAmd64 flags)
        {
            ContextAmd64 context = new ContextAmd64();

            context.ContextFlags = flags;
            this.GetContext(ref context);

            return(context);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Sets the thread's context.
        /// </summary>
        /// <param name="context">A CONTEXT struct.</param>
        public void SetContext(ContextAmd64 context)
        {
            // HACK: To avoid a datatype misalignment error, allocate
            // some aligned memory.
            using (AlignedMemoryAlloc data = new AlignedMemoryAlloc(Utils.SizeOf(16, ContextAmd64.SizeOf), 16))
            {
                data.WriteStruct(context);

                Win32.NtSetContextThread(this, data).ThrowIf();
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Sets the thread's context.
        /// </summary>
        /// <param name="context">A CONTEXT struct.</param>
        public void SetContext(ContextAmd64 context)
        {
            NtStatus status;

            // HACK: To avoid a datatype misalignment error, allocate
            // some aligned memory.
            using (var data = new AlignedMemoryAlloc(Utils.SizeOf <ContextAmd64>(16), 16))
            {
                data.WriteStruct <ContextAmd64>(context);

                if ((status = Win32.NtSetContextThread(this, data)) >= NtStatus.Error)
                {
                    Win32.Throw(status);
                }
            }
        }
Exemplo n.º 4
0
 public static extern bool StackWalk64(
     [In] MachineType MachineType,
     [In] IntPtr ProcessHandle,
     [In] IntPtr ThreadHandle,
     ref StackFrame64 StackFrame,
     ref ContextAmd64 ContextRecord,
     [In] [Optional] ReadProcessMemoryProc64 ReadMemoryRoutine,
     [In] [Optional] FunctionTableAccessProc64 FunctionTableAccessRoutine,
     [In] [Optional] GetModuleBaseProc64 GetModuleBaseRoutine,
     [In] [Optional] IntPtr TranslateAddress
     );
Exemplo n.º 5
0
 public static extern NtStatus NtGetContextThread(
     [In] IntPtr ThreadHandle,
     ref ContextAmd64 ThreadContext
     );
Exemplo n.º 6
0
        /// <summary>
        /// Walks the call stack for the thread.
        /// </summary>
        /// <param name="parentProcess">A handle to the thread's parent process.</param>
        /// <param name="walkStackCallback">A callback to execute.</param>
        /// <param name="architecture">
        /// The type of stack walk. On 32-bit systems, this value is ignored.
        /// On 64-bit systems, this value can be set to I386 to walk the
        /// 32-bit stack.
        /// </param>
        public unsafe void WalkStack(ProcessHandle parentProcess, WalkStackDelegate walkStackCallback, OSArch architecture)
        {
            bool suspended = false;

            // Suspend the thread to avoid inaccurate thread stacks.
            try
            {
                this.Suspend();
                suspended = true;
            }
            catch (WindowsException)
            {
                suspended = false;
            }

            // Use KPH for reading memory if we can.
            ReadProcessMemoryProc64 readMemoryProc = null;

            if (KProcessHacker.Instance != null)
            {
                readMemoryProc = new ReadProcessMemoryProc64(
                    delegate(IntPtr processHandle, ulong baseAddress, IntPtr buffer, int size, out int bytesRead)
                {
                    return(KProcessHacker.Instance.KphReadVirtualMemorySafe(
                               ProcessHandle.FromHandle(processHandle), (int)baseAddress, buffer, size, out bytesRead).IsSuccess());
                });
            }

            try
            {
                // x86/WOW64 stack walk.
                if (OSVersion.Architecture == OSArch.I386 || (OSVersion.Architecture == OSArch.Amd64 && architecture == OSArch.I386))
                {
                    Context context = new Context();

                    context.ContextFlags = ContextFlags.All;

                    if (OSVersion.Architecture == OSArch.I386)
                    {
                        // Get the context.
                        this.GetContext(ref context);
                    }
                    else
                    {
                        // Get the WOW64 x86 context.
                        this.GetContextWow64(ref context);
                    }

                    // Set up the initial stack frame structure.
                    var stackFrame = new StackFrame64();

                    stackFrame.AddrPC.Mode      = AddressMode.AddrModeFlat;
                    stackFrame.AddrPC.Offset    = (ulong)context.Eip;
                    stackFrame.AddrStack.Mode   = AddressMode.AddrModeFlat;
                    stackFrame.AddrStack.Offset = (ulong)context.Esp;
                    stackFrame.AddrFrame.Mode   = AddressMode.AddrModeFlat;
                    stackFrame.AddrFrame.Offset = (ulong)context.Ebp;

                    while (true)
                    {
                        using (Win32.DbgHelpLock.AcquireContext())
                        {
                            if (!Win32.StackWalk64(
                                    MachineType.I386,
                                    parentProcess,
                                    this,
                                    ref stackFrame,
                                    ref context,
                                    readMemoryProc,
                                    Win32.SymFunctionTableAccess64,
                                    Win32.SymGetModuleBase64,
                                    IntPtr.Zero
                                    ))
                            {
                                break;
                            }
                        }

                        // If we got an invalid eip, break.
                        if (stackFrame.AddrPC.Offset == 0)
                        {
                            break;
                        }

                        // Execute the callback.
                        if (!walkStackCallback(new ThreadStackFrame(ref stackFrame)))
                        {
                            break;
                        }
                    }
                }
                // x64 stack walk.
                else if (OSVersion.Architecture == OSArch.Amd64)
                {
                    ContextAmd64 context = new ContextAmd64();

                    context.ContextFlags = ContextFlagsAmd64.All;
                    // Get the context.
                    this.GetContext(ref context);

                    // Set up the initial stack frame structure.
                    var stackFrame = new StackFrame64();

                    stackFrame.AddrPC.Mode      = AddressMode.AddrModeFlat;
                    stackFrame.AddrPC.Offset    = (ulong)context.Rip;
                    stackFrame.AddrStack.Mode   = AddressMode.AddrModeFlat;
                    stackFrame.AddrStack.Offset = (ulong)context.Rsp;
                    stackFrame.AddrFrame.Mode   = AddressMode.AddrModeFlat;
                    stackFrame.AddrFrame.Offset = (ulong)context.Rbp;

                    while (true)
                    {
                        using (Win32.DbgHelpLock.AcquireContext())
                        {
                            if (!Win32.StackWalk64(
                                    MachineType.Amd64,
                                    parentProcess,
                                    this,
                                    ref stackFrame,
                                    ref context,
                                    readMemoryProc,
                                    Win32.SymFunctionTableAccess64,
                                    Win32.SymGetModuleBase64,
                                    IntPtr.Zero
                                    ))
                            {
                                break;
                            }
                        }

                        // If we got an invalid rip, break.
                        if (stackFrame.AddrPC.Offset == 0)
                        {
                            break;
                        }

                        // Execute the callback.
                        if (!walkStackCallback(new ThreadStackFrame(ref stackFrame)))
                        {
                            break;
                        }
                    }
                }
            }
            finally
            {
                // If we suspended the thread before, resume it.
                if (suspended)
                {
                    try
                    {
                        this.Resume();
                    }
                    catch (WindowsException)
                    { }
                }
            }
        }