Ejemplo n.º 1
0
 private void ExecuteCommand(IDebugControl6 debugControl, string command, string comment = null)
 {
     debugControl.Execute(DEBUG_OUTCTL.ALL_CLIENTS, " ", DEBUG_EXECUTE.DEFAULT);             // empty new line
     Echo(debugControl, $"now running command '{command}'" + (string.IsNullOrEmpty(comment) ? string.Empty : $" ({comment})"));
     Echo(debugControl, "=======================================================================");
     LogOnErrorHR(debugControl.Execute(DEBUG_OUTCTL.ALL_CLIENTS, command, DEBUG_EXECUTE.DEFAULT), $"failed to run '{command}'");
 }
Ejemplo n.º 2
0
 private static void LoadExtensions(IDebugControl6 debugControl)
 {
     LoadExtension(debugControl, @"ext.dll");
     LoadExtension(debugControl, @"exts.dll");
     LoadExtension(debugControl, @"uext.dll");
     LoadExtension(debugControl, @"ntsdexts.dll");
 }
Ejemplo n.º 3
0
        private static ulong LoadExtension(IDebugControl6 debugControl, string path)
        {
            ulong handle;

            LogOnErrorHR(debugControl.AddExtension(path, 0, out handle), $"failed to load '{path}'");
            return(handle);
        }
Ejemplo n.º 4
0
        public WdbgExts(IDebugControl6 debugControl)
        {
            if (null == debugControl)
            {
                throw new ArgumentNullException("debugControl");
            }

            m_debugControl = debugControl;
        } // end constructor
Ejemplo n.º 5
0
        public static void ExecuteDbgEngCommand(this DataTarget target, string command, CommandExecutionContext context)
        {
            IDebugControl6 control = (IDebugControl6)target.DebuggerInterface;
            int            hr      = control.ExecuteWide(
                DEBUG_OUTCTL.THIS_CLIENT, command, DEBUG_EXECUTE.DEFAULT);

            if (HR.Failed(hr))
            {
                context.WriteErrorLine("Command execution failed with hr = {0:x8}", hr);
            }
        }
Ejemplo n.º 6
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="DebugEngineProxy" /> class.
 /// </summary>
 /// <param name="control">The control.</param>
 /// <param name="client">The client.</param>
 /// <param name="registers">The registers.</param>
 /// <param name="systemObjects">The system objects.</param>
 /// <param name="debugDataSpaces">The debug data spaces.</param>
 public DebugEngineProxy(IDebugControl6 control, IDebugClient5 client, IDebugRegisters2 registers,
     IDebugSystemObjects systemObjects, IDebugDataSpaces debugDataSpaces, IExecuteWrapper executeWrapper)
 {
     Control = control;
     Client = client;
     Registers = registers;
     Dataspaces = debugDataSpaces;
     ExecuteWrapper = executeWrapper;
     RegisterEngine = new RegisterEngine(); // todo: inject
     MemoryEngine = new MemoryEngine();
     SystemObjects = systemObjects;
     Is32Bit =
         Regex.Match(ExecuteWrapper.Execute("!peb"), @"PEB at (?<peb>[a-fA-F0-9]+)").Groups["peb"].Value
             .Length == 8;
 }
Ejemplo n.º 7
0
        private DebugClient(object client, TaskScheduler scheduler)
        {
            _scheduler = scheduler;

            Client        = (IDebugClient5)client;
            Control       = (IDebugControl6)client;
            DataSpaces    = (IDebugDataSpaces4)client;
            SystemObjects = (IDebugSystemObjects2)client;
            Symbols       = (IDebugSymbols5)client;
            Advanced      = (IDebugAdvanced3)client;

            Client.SetEventCallbacksWide(this).ThrowIfFailed();
            Client.SetOutputCallbacksWide(this).ThrowIfFailed();

            Control.AddEngineOptions(DEBUG_ENGOPT.INITIAL_BREAK);
        }
Ejemplo n.º 8
0
 internal static void INIT_API()
 {
     LastHR = HRESULT.S_OK;
     if (client == null)
     {
         try
         {
             client  = (IDebugClient5)CreateIDebugClient();
             control = (IDebugControl6)client;
         }
         catch
         {
             LastHR = HRESULT.E_UNEXPECTED;
         }
     }
 }
Ejemplo n.º 9
0
 private static void LoadExtensions(IDebugControl6 debugControl)
 {
     if (Environment.Is64BitProcess)
     {
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext\ext.dll");                 // do we need this configurable? should we ship these?
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\exts.dll");
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\uext.dll");
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP\ntsdexts.dll");
     }
     else
     {
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\winext\ext.dll");                 // do we need this configurable? should we ship these?
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\WINXP\exts.dll");
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\WINXP\uext.dll");
         LoadExtension(debugControl, @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\WINXP\ntsdexts.dll");
     }
 }
Ejemplo n.º 10
0
        public void Attach()
        {
            Task.Run(() =>
            {
                this.Client = DebugClient.DebugCreate();

                IDebugClient7 client   = this.Client as IDebugClient7;
                IDebugControl6 control = this.Client as IDebugControl6;

                client.SetOutputCallbacksWide(new OutputCallBacks());
                client.SetEventCallbacksWide(new EventCallBacks(control));


                this.Client.AttachProcess(0, unchecked ((UInt32)this.SystemProcess.Id), DebugAttach.InvasiveNoInitialBreak);

                while (true)
                {
                    control.WaitForEvent(0, UInt32.MaxValue);
                }
            });
        }
Ejemplo n.º 11
0
        private void Analyze(IDebugControl6 debugControl, string logfilepath)
        {
            debugControl.OpenLogFile(logfilepath, false);
            try {
                LoadExtensions(debugControl);

                ExecuteCommand(debugControl, "|.", "status about process");
                //ExecuteCommand(debugControl, ".loadby sos clr", "try to find sos"); // this will load sos.dll from the location of clr.dll. if symbol servers work correctly, this is not what we need
                ExecuteCommand(debugControl, ".cordll -ve -u -l", "verbose loading of mscordacwks");
                ExecuteCommand(debugControl, ".chain", "list loaded debug-extensions");
                ExecuteCommand(debugControl, "!eeversion");                 // clr version
                ExecuteCommand(debugControl, "!threads");
                ExecuteCommand(debugControl, "!tp", "threadpool info");
                ExecuteCommand(debugControl, "lmf");                 // list loaded .dlls
                ExecuteCommand(debugControl, ".exr -1");             // last exception
                ExecuteCommand(debugControl, "!analyze -v");
                ExecuteCommand(debugControl, "~* k", "native stacks");
                ExecuteCommand(debugControl, "~*e !clrstack", "managed stacks");
                ExecuteCommand(debugControl, "x *!", "symbol paths");                 // only shows symbols of modules that have been requested, so it's important to do this after listing stacks
            } finally {
                debugControl.CloseLogFile();
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 ///     Initializes the API.
 /// </summary>
 /// <param name="log">The log.</param>
 internal static void InitApi(ILog log = null)
 {
     LastHR = HRESULT.S_OK;
     if (client != null)
     {
         return;
     }
     try
     {
         log?.Debug("Client did not exist. Creating a new client and associated interfaces.");
         client          = (IDebugClient5)CreateIDebugClient();
         control         = (IDebugControl6)client;
         registers       = (IDebugRegisters2)client;
         symbols         = (IDebugSymbols5)client;
         systemObjects   = (IDebugSystemObjects)client;
         debugDataSpaces = (IDebugDataSpaces)client;
     }
     catch (Exception e)
     {
         log?.Fatal("Unable to create debug client. Are you missing DLLs?");
         log?.Fatal(e);
         LastHR = HRESULT.E_UNEXPECTED;
     }
 }
Ejemplo n.º 13
0
            } // end UpdateCmdlet()

            public int StartInput(uint BufferSize)
            {
                try
                {
                    // TODO: powershell-ize
                    Console.Write("StartInput( {0} )> ", BufferSize);
                    string input = Console.ReadLine();
                    // TODO: should this be in the debugger class?
                    IDebugControl6 dc6     = (IDebugControl6)m_cmdlet.Debugger.DebuggerInterface;
                    int            hresult = dc6.ReturnInputWide(input);
                    // TODO: apparently it can return S_FALSE, meaning it "already
                    // received the input", because it asks all clients for input. How
                    // should I inform the user?
                    if (hresult < 0)
                    {
                        Util.FailFast("ReturnInput failed", new Win32Exception(hresult));
                    }
                }
                catch (Exception e)
                {
                    Util.FailFast("Unexpected exception in StartInput callback.", e);
                }
                return(0);
            }
Ejemplo n.º 14
0
 private static void Echo(IDebugControl6 debugControl, string msg)
 {
     LogOnErrorHR(debugControl.Execute(DEBUG_OUTCTL.ALL_CLIENTS, $"$$ {msg}", DEBUG_EXECUTE.DEFAULT), $"failed to " + $"$$ {msg}");
 }
 public EventCallbacks(IDebugControl6 control)
 {
     _control = control;
 }
        public static void Run(Process clProcess)
        {
            ProcessModuleCollection clProcessModules = clProcess.Modules;



            /////////////////////////////////
            Guid guid = typeof(IDebugClient).GUID;

            // create debug client object
            //object obj;
            //CheckHr(Native.NativeMethods.DbgEng.DebugCreate(ref guid, out obj));
            IntPtr pObj = IntPtr.Zero;

            CheckHr(Native.NativeMethods.DbgEng.DebugCreate(ref guid, ref pObj));
            IDebugClient5Fixed    client     = (IDebugClient5Fixed)Marshal.GetTypedObjectForIUnknown(pObj, typeof(IDebugClient5Fixed));
            IDebugDataSpaces4     dataSpaces = client as IDebugDataSpaces4;
            IDebugRegisters2Fixed registers  = client as IDebugRegisters2Fixed;

            //IDebugClient5Fixed client = obj as IDebugClient5Fixed;
            IDebugControl6 control = client as IDebugControl6;
            var            events  = new EventCallbacks(control);

            client.SetEventCallbacksWide(events);
            client.SetOutputCallbacksWide(new OutputCallbacks());
            Console.CancelKeyPress += (s, e) => {
                e.Cancel = true;

                //control.SetInterrupt(DEBUG_INTERRUPT.ACTIVE);
            };
            CheckHr(client.AttachProcess(0, (uint)clProcess.Id, DEBUG_ATTACH.DEFAULT));

            ///////////
            ProcessModule progModule = null;

            foreach (ProcessModule module in clProcessModules)
            {
                if (module.ModuleName == "prog.dll")
                {
                    progModule = module;
                    break;
                }
            }

            Console.WriteLine(
                $"Module: {progModule.ModuleName}\r\n" +
                $"  BaseAddress: {progModule.BaseAddress.FormatAsHex()}\r\n" +
                $"  EntryPointAddress: {progModule.EntryPointAddress.FormatAsHex()}\r\n" +
                $"  ModuleMemorySize: 0x{progModule.ModuleMemorySize:X8}\r\n" +
                $"");


            //callbackProvider = new UnmanagedCodeSupplier((PickUpWeaponDelegate)ttExecutionCallback, IntPtr.Size == sizeof(int) ? x86CodeForFastcallWrapperForExecutionDelegate : x64CodeForFastcallWrapperForExecutionDelegate, IntPtr.Size == sizeof(int) ? new UIntPtr(0xF0F0F0F0) : new UIntPtr(0xF0F0F0F0F0F0F0F0));

            //byte[] progMemory = new byte[progModule.ModuleMemorySize];

            //return;


            ////////

            CheckHr(control.WaitForEvent(DEBUG_WAIT.DEFAULT, 5000));


            byte[] progMemory = new byte[progModule.ModuleMemorySize];
            uint   readMemoryBytes;

            ulong validbase;
            uint  validsize;

            CheckHr(dataSpaces.GetValidRegionVirtual((ulong)progModule.BaseAddress, (uint)progMemory.Length, out validbase, out validsize));


            //Console.WriteLine($"Read {readMemoryBytes} bytes");


            byte[] pickUpWeaponSignature;
            byte[] wildcard;
            ParseSearchPattern(
                "55 8B EC 83 E4 F8 80 3D A9 0F ?? 0F 00 56 57 8B F2 8B F9 75 23 80 3D 9A 0E ?? 0F 00 75 1A 56 E8 9C 94 F9 FF 83 FE 0F 75 0F 83 F8 32 7C 0A B9 D4",
                out pickUpWeaponSignature,
                out wildcard
                );
            //wildcard[3] = 1;
            ulong matchOffset;

            CheckHr(dataSpaces.ReadVirtualUncached((ulong)progModule.BaseAddress, progMemory, (uint)progMemory.Length, out readMemoryBytes));
            fixed(void *progMemoryPtr = progMemory, pickUpWeaponSignaturePtr = pickUpWeaponSignature, wildcardPtr = wildcard)
            {
                //pickUpWeaponAddress = (IntPtr) IndexOfUnchecked(progMemoryPtr, progMemory.Length, pickUpWeaponSignaturePtr, pickUpWeaponSignature.Length, wildcardPtr);
                int pickUpWeaponAddressOffset =
                    IndexOfUnchecked(progMemoryPtr, progMemory.Length, pickUpWeaponSignaturePtr, pickUpWeaponSignature.Length, wildcardPtr);

                Console.WriteLine($"PickUpWeapon offset: 0x{pickUpWeaponAddressOffset:X8}");
                if (pickUpWeaponAddressOffset == -1)
                {
                    throw new Exception("Pattern not found!");
                }

                pickUpWeaponAddress = new IntPtr(pickUpWeaponAddressOffset + (int)progModule.BaseAddress);
            }

            //dataSpaces.SearchVirtual((ulong) progModule.BaseAddress, (ulong) progModule.ModuleMemorySize, pickUpWeaponSignature, (uint) pickUpWeaponSignature.Length, 1, out matchOffset);
            //pickUpWeaponAddress = (IntPtr) matchOffset;
            Console.WriteLine($"PickUpWeapon address: {pickUpWeaponAddress.FormatAsHex()}");

            control.AddBreakpoint2(DEBUG_BREAKPOINT_TYPE.CODE, uint.MaxValue, out pickUpWeaponBreakpoint);
            pickUpWeaponBreakpoint.SetOffset((ulong)pickUpWeaponAddress);
            pickUpWeaponBreakpoint.SetFlags(DEBUG_BREAKPOINT_FLAG.ENABLED);

            pickUpWeaponBreakpoint.SetCommandWide(".echo WEAPON PICKUP!");

            // fixed (void* progMemoryPtr = progMemory, pickUpWeaponSignaturePtr = pickUpWeaponSignature) {
            //     int pickUpWeaponAddressOffset =
            //         IndexOfUnchecked(progMemoryPtr, progMemory.Length, pickUpWeaponSignaturePtr, pickUpWeaponSignature.Length);
            //     Console.WriteLine($"PickUpWeapon offset: 0x{pickUpWeaponAddressOffset:X8}");
            //     if (pickUpWeaponAddressOffset == -1)
            //         throw new Exception("Pattern not found!");
            //
            //     pickUpWeaponAddress = new IntPtr(pickUpWeaponAddressOffset + (int) progModule.BaseAddress);
            //     Console.WriteLine($"PickUpWeapon address: {pickUpWeaponAddress.FormatAsHex()}");
            // }

            control.SetExecutionStatus(DEBUG_STATUS.GO);

            File.WriteAllBytes("dump.bin", progMemory);

            DEBUG_STATUS status;
            int          hr;

            while (true)
            {
                CheckHr(control.GetExecutionStatus(out status));
                if (status == DEBUG_STATUS.NO_DEBUGGEE)
                {
                    Console.WriteLine("No Target");
                    break;
                }

                if (status == DEBUG_STATUS.GO || status == DEBUG_STATUS.STEP_BRANCH ||
                    status == DEBUG_STATUS.STEP_INTO ||
                    status == DEBUG_STATUS.STEP_OVER)
                {
                    hr = control.WaitForEvent(DEBUG_WAIT.DEFAULT, uint.MaxValue);
                    continue;
                }

                if (events.StateChanged)
                {
                    Console.WriteLine();
                    events.StateChanged = false;
                    if (events.BreakpointHit)
                    {
                        control.OutputCurrentState(DEBUG_OUTCTL.THIS_CLIENT,
                                                   DEBUG_CURRENT.DEFAULT);
                        events.BreakpointHit = false;
                    }
                }


                control.OutputPromptWide(DEBUG_OUTCTL.THIS_CLIENT, null);
                Console.Write(" ");
                Console.ForegroundColor = ConsoleColor.Gray;
                string command = Console.ReadLine();
                if (command == ".detach")
                {
                    client.DetachCurrentProcess();
                }
                else
                {
                    control.ExecuteWide(DEBUG_OUTCTL.THIS_CLIENT, command,
                                        DEBUG_EXECUTE.DEFAULT);
                }
            }
        }
Ejemplo n.º 17
0
 public EventCallBacks(IDebugControl6 control)
 {
     this.Control = control;
 }