Used for scoped process switching. using (var switcher = new ProcessSwitcher(process)) { // Invoke DbgEng.dll interface function } Use this class for accessing process information from DbgEng.dll interfaces to insure correct process information access. For performance reasons, after using scope, previous process won't be set until it is needed. Always use this class to insure correctness.
상속: IDisposable
예제 #1
0
 /// <summary>
 /// Gets the symbol tag of the specified type.
 /// </summary>
 /// <param name="module">The module.</param>
 /// <param name="typeId">The type identifier.</param>
 public SymTag GetTypeTag(Module module, uint typeId)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
     {
         return(typedData[Tuple.Create(module.Address, typeId, module.Process.PebAddress)].Tag);
     }
 }
예제 #2
0
        /// <summary>
        /// Gets the runtime code type and offset to original code type.
        /// </summary>
        /// <param name="vtableAddress">The vtable address.</param>
        public Tuple <CodeType, int> GetRuntimeCodeTypeAndOffset(uint vtableAddress)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                uint          nameSize;
                ulong         displacement;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                DbgEngDll.Symbols.GetNameByOffset(vtableAddress + Module.Address, sb, (uint)sb.Capacity, out nameSize, out displacement);

                // Fully undecorated name should be in form: "DerivedClass::`vftable'"
                string       fullyUndecoratedName = sb.ToString();
                const string vftableString        = "::`vftable'";

                if (string.IsNullOrEmpty(fullyUndecoratedName) || !fullyUndecoratedName.EndsWith(vftableString))
                {
                    // Pointer is not vtable.
                    return(null);
                }

                string   codeTypeName = fullyUndecoratedName.Substring(0, fullyUndecoratedName.Length - vftableString.Length);
                CodeType codeType     = CodeType.Create(Module.Process, codeTypeName);

                // TODO: We need to be able to get partially undecorated name in order to find offset (See DiaModule.cs for more info)
                return(Tuple.Create(codeType, 0));
            }
        }
예제 #3
0
 /// <summary>
 /// Gets the size of the specified type.
 /// </summary>
 /// <param name="typeId">The type identifier.</param>
 public uint GetTypeSize(uint typeId)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
     {
         return(DbgEngDll.Symbols.GetTypeSize(Module.Address, typeId));
     }
 }
예제 #4
0
 /// <summary>
 /// Gets the type identifier.
 /// </summary>
 /// <param name="typeName">Name of the type.</param>
 public uint GetTypeId(string typeName)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
     {
         return(DbgEngDll.Symbols.GetTypeIdWide(Module.Address, Module.Name + "!" + typeName));
     }
 }
예제 #5
0
        /// <summary>
        /// Gets the global variable address.
        /// </summary>
        /// <param name="globalVariableName">Name of the global variable.</param>
        public ulong GetGlobalVariableAddress(string globalVariableName)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                string name = Module.Name + "!" + globalVariableName;

                return(DbgEngDll.Symbols.GetOffsetByNameWide(name));
            }
        }
예제 #6
0
        /// <summary>
        /// Gets the code type tag of the specified type.
        /// </summary>
        /// <param name="typeId">The type identifier.</param>
        public CodeTypeTag GetTypeTag(uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                SymTagEnum symTag = DbgEngSymbolProvider.typedData[Tuple.Create(Module.Address, typeId, Module.Process.PebAddress)].Tag;

                return(symTag.ToCodeTypeTag());
            }
        }
예제 #7
0
        /// <summary>
        /// Gets the name of the enumeration value.
        /// </summary>
        /// <param name="enumTypeId">The enumeration type identifier.</param>
        /// <param name="enumValue">The enumeration value.</param>
        public string GetEnumName(uint enumTypeId, ulong enumValue)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                uint          enumNameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                DbgEngDll.Symbols.GetConstantNameWide(Module.Offset, enumTypeId, enumValue, sb, (uint)sb.Capacity, out enumNameSize);
                return(sb.ToString());
            }
        }
예제 #8
0
        /// <summary>
        /// Determines whether the specified process address is function type public symbol.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <returns>
        ///   <c>true</c> if the specified process address is function type public symbol; otherwise, <c>false</c>.
        /// </returns>
        public bool IsFunctionAddressPublicSymbol(uint address)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                ulong moduleAddress;
                uint  typeId;

                DbgEngDll.Symbols.GetOffsetTypeId(address + Module.Address, out typeId, out moduleAddress);
                return(typeId == 0);
            }
        }
예제 #9
0
        /// <summary>
        /// Gets the name of the specified type.
        /// </summary>
        /// <param name="typeId">The type identifier.</param>
        public string GetTypeName(uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                uint          nameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                DbgEngDll.Symbols.GetTypeName(Module.Address, typeId, sb, (uint)sb.Capacity, out nameSize);
                return(sb.ToString());
            }
        }
예제 #10
0
        /// <summary>
        /// Gets the name of the function for the specified stack frame.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="functionName">Name of the function.</param>
        /// <param name="displacement">The displacement.</param>
        public void GetFunctionNameAndDisplacement(uint address, out string functionName, out ulong displacement)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                uint          functionNameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                DbgEngDll.Symbols.GetNameByOffset(address + Module.Address, sb, (uint)sb.Capacity, out functionNameSize, out displacement);
                functionName = sb.ToString();
            }
        }
        /// <summary>
        /// Gets the name of the enumeration value.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="enumTypeId">The enumeration type identifier.</param>
        /// <param name="enumValue">The enumeration value.</param>
        public string GetEnumName(Module module, uint enumTypeId, ulong enumValue)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                uint enumNameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                dbgEngDll.Symbols.GetConstantNameWide(module.Offset, enumTypeId, enumValue, sb, (uint)sb.Capacity, out enumNameSize);
                return sb.ToString();
            }
        }
예제 #12
0
        /// <summary>
        /// Gets the source file name and line for the specified stack frame.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="sourceFileName">Name of the source file.</param>
        /// <param name="sourceFileLine">The source file line.</param>
        /// <param name="displacement">The displacement.</param>
        public void GetSourceFileNameAndLine(uint address, out string sourceFileName, out uint sourceFileLine, out ulong displacement)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                uint          fileNameLength;
                StringBuilder sb = new StringBuilder(Constants.MaxFileName);

                DbgEngDll.Symbols.GetLineByOffset(address + Module.Address, out sourceFileLine, sb, (uint)sb.Capacity, out fileNameLength, out displacement);
                sourceFileName = sb.ToString();
            }
        }
예제 #13
0
        /// <summary>
        /// Gets the global variable type identifier.
        /// </summary>
        /// <param name="globalVariableName">Name of the global variable.</param>
        public uint GetGlobalVariableTypeId(string globalVariableName)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                string name = Module.Name + "!" + globalVariableName.Replace("::", ".");
                uint   typeId;
                ulong  moduleId;

                DbgEngDll.Symbols.GetSymbolTypeIdWide(name, out typeId, out moduleId);
                return(typeId);
            }
        }
예제 #14
0
        /// <summary>
        /// Gets the symbol name by address.
        /// </summary>
        /// <param name="address">The address.</param>
        public Tuple <string, ulong> GetSymbolNameByAddress(uint address)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);
                ulong         displacement;
                uint          nameSize;

                DbgEngDll.Symbols.GetNameByOffsetWide(address + Module.Address, sb, (uint)sb.Capacity, out nameSize, out displacement);
                return(Tuple.Create(sb.ToString(), displacement));
            }
        }
예제 #15
0
        /// <summary>
        /// Gets the type pointer to type of the specified type.
        /// </summary>
        /// <param name="typeId">The type identifier.</param>
        public uint GetTypePointerToTypeId(uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                var typedData = DbgEngSymbolProvider.typedData[Tuple.Create(Module.Address, typeId, Module.Process.PebAddress)];
                typedData.Data = Module.Process.PebAddress;
                var result = DbgEngDll.Advanced.Request(DebugRequest.ExtTypedDataAnsi, new EXT_TYPED_DATA()
                {
                    Operation = ExtTdop.GetPointerTo,
                    InData    = typedData,
                }).OutData.TypeId;

                return(result);
            }
        }
예제 #16
0
        /// <summary>
        /// Gets the element type of the specified type.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="typeId">The type identifier.</param>
        public uint GetTypeElementTypeId(Module module, uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                var typedData = DbgEngSymbolProvider.typedData[Tuple.Create(module.Address, typeId, module.Process.PEB)];
                typedData.Data = module.Process.PEB;
                var result = dbgEngDll.Advanced.Request(DebugRequest.ExtTypedDataAnsi, new EXT_TYPED_DATA()
                {
                    Operation = ExtTdop.GetDereference,
                    InData    = typedData,
                }).OutData.TypeId;

                return(result);
            }
        }
예제 #17
0
        /// <summary>
        /// Reads the simple data (1 to 8 bytes) for specified type and address to read from.
        /// </summary>
        /// <param name="codeType">Type of the code.</param>
        /// <param name="address">The address.</param>
        public ulong ReadSimpleData(CodeType codeType, ulong address)
        {
            NativeCodeType nativeCodeType = codeType as NativeCodeType;

            if (nativeCodeType == null)
            {
                return(Debugger.ReadSimpleData(codeType, address));
            }

            Module module = codeType.Module;

            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                return(DbgEngSymbolProvider.typedData[Tuple.Create(module.Address, nativeCodeType.TypeId, address)].Data);
            }
        }
예제 #18
0
        /// <summary>
        /// Reads the simple data (1 to 8 bytes) for specified type and address to read from.
        /// </summary>
        /// <param name="codeType">Type of the code.</param>
        /// <param name="address">The address.</param>
        public ulong ReadSimpleData(CodeType codeType, ulong address)
        {
            NativeCodeType nativeCodeType = codeType as NativeCodeType;

            if (nativeCodeType == null)
            {
                throw new ArgumentOutOfRangeException(nameof(codeType), "This is only supported for NativeCodeType");
            }

            Module module = codeType.Module;

            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                return(typedData[Tuple.Create(module.Address, nativeCodeType.TypeId, address)].Data);
            }
        }
예제 #19
0
        /// <summary>
        /// Gets the field type id and offset of the specified type.
        /// </summary>
        /// <param name="typeId">The type identifier.</param>
        /// <param name="fieldName">Name of the field.</param>
        public Tuple <uint, int> GetTypeAllFieldTypeAndOffset(uint typeId, string fieldName)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                try
                {
                    uint fieldTypeId, fieldOffset;

                    DbgEngDll.Symbols.GetFieldTypeAndOffsetWide(Module.Address, typeId, fieldName, out fieldTypeId, out fieldOffset);
                    return(Tuple.Create(fieldTypeId, (int)fieldOffset));
                }
                catch (Exception)
                {
                    return(Tuple.Create <uint, int>(0, -1));
                }
            }
        }
예제 #20
0
        /// <summary>
        /// Gets the names of all fields of the specified type.
        /// </summary>
        /// <param name="typeId">The type identifier.</param>
        public string[] GetTypeAllFieldNames(uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, Module.Process))
            {
                List <string> fields = new List <string>();
                uint          nameSize;

                try
                {
                    for (uint fieldIndex = 0; ; fieldIndex++)
                    {
                        StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                        DbgEngDll.Symbols.GetFieldName(Module.Address, typeId, fieldIndex, sb, (uint)sb.Capacity, out nameSize);
                        fields.Add(sb.ToString());
                    }
                }
                catch (Exception)
                {
                }

                return(fields.ToArray());
            }
        }
        /// <summary>
        /// Gets the name of the function for the specified address.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="address">The address.</param>
        /// <param name="functionName">Name of the function.</param>
        /// <param name="displacement">The displacement.</param>
        public void GetProcessAddressFunctionName(Process process, ulong address, out string functionName, out ulong displacement)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, process))
            {
                uint functionNameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                dbgEngDll.Symbols.GetNameByOffset(address, sb, (uint)sb.Capacity, out functionNameSize, out displacement);
                functionName = sb.ToString();
            }
        }
        /// <summary>
        /// Gets the symbol name by address.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="address">The address.</param>
        public Tuple<string, ulong> GetSymbolNameByAddress(Process process, ulong address)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, process))
            {
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);
                ulong displacement;
                uint nameSize;

                dbgEngDll.Symbols.GetNameByOffsetWide(address, sb, (uint)sb.Capacity, out nameSize, out displacement);
                return Tuple.Create(sb.ToString(), displacement);
            }
        }
        /// <summary>
        /// Gets the field type id and offset of the specified type.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="typeId">The type identifier.</param>
        /// <param name="fieldName">Name of the field.</param>
        public Tuple<uint, int> GetTypeAllFieldTypeAndOffset(Module module, uint typeId, string fieldName)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                try
                {
                    uint fieldTypeId, fieldOffset;

                    dbgEngDll.Symbols.GetFieldTypeAndOffsetWide(module.Address, typeId, fieldName, out fieldTypeId, out fieldOffset);
                    return Tuple.Create(fieldTypeId, (int)fieldOffset);
                }
                catch (Exception)
                {
                    return Tuple.Create<uint, int>(0, -1);
                }
            }
        }
        /// <summary>
        /// Gets the name of the specified type.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="typeId">The type identifier.</param>
        public string GetTypeName(Module module, uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                uint nameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                dbgEngDll.Symbols.GetTypeName(module.Address, typeId, sb, (uint)sb.Capacity, out nameSize);
                return sb.ToString();
            }
        }
 /// <summary>
 /// Gets the size of the specified type.
 /// </summary>
 /// <param name="module">The module.</param>
 /// <param name="typeId">The type identifier.</param>
 public uint GetTypeSize(Module module, uint typeId)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
     {
         return dbgEngDll.Symbols.GetTypeSize(module.Address, typeId);
     }
 }
        /// <summary>
        /// Reads the simple data (1 to 8 bytes) for specified type and address to read from.
        /// </summary>
        /// <param name="codeType">Type of the code.</param>
        /// <param name="address">The address.</param>
        public ulong ReadSimpleData(CodeType codeType, ulong address)
        {
            NativeCodeType nativeCodeType = codeType as NativeCodeType;

            if (nativeCodeType == null)
            {
                return Debugger.ReadSimpleData(codeType, address);
            }

            Module module = codeType.Module;

            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                return typedData[Tuple.Create(module.Address, nativeCodeType.TypeId, address)].Data;
            }
        }
예제 #27
0
 /// <summary>
 /// Gets the effective processor type of the specified process.
 /// </summary>
 /// <param name="process">The process.</param>
 public ImageFileMachine GetProcessEffectiveProcessorType(Process process)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
     {
         return (ImageFileMachine)Control.GetEffectiveProcessorType();
     }
 }
예제 #28
0
        /// <summary>
        /// Gets the name of the module.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="modname">The type of module name.</param>
        /// <returns>Read name</returns>
        private string GetModuleName(Module module, DebugModname modname)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, module.Process))
            {
                uint nameSize;
                StringBuilder sb = new StringBuilder(Constants.MaxFileName);

                Symbols.GetModuleNameStringWide((uint)modname, 0xffffffff, module.Address, sb, (uint)sb.Capacity, out nameSize);
                return sb.ToString();
            }
        }
예제 #29
0
        /// <summary>
        /// Gets the module version.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="major">The version major number.</param>
        /// <param name="minor">The version minor number.</param>
        /// <param name="revision">The version revision number.</param>
        /// <param name="patch">The version patch number.</param>
        public void GetModuleVersion(Module module, out int major, out int minor, out int revision, out int patch)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, module.Process))
            {
                uint index, bufferSize;
                ulong baseAddress;

                Symbols.GetModuleByOffset(module.Address, 0, out index, out baseAddress);
                Symbols.GetModuleVersionInformation(index, module.Address, "\\", IntPtr.Zero, 0, out bufferSize);

                IntPtr buffer = Marshal.AllocHGlobal((int)bufferSize);

                try
                {
                    Symbols.GetModuleVersionInformation(index, module.Address, "\\", buffer, bufferSize, out bufferSize);
                    minor = (ushort)Marshal.ReadInt16(buffer, 8);
                    major = (ushort)Marshal.ReadInt16(buffer, 10);
                    patch = (ushort)Marshal.ReadInt16(buffer, 12);
                    revision = (ushort)Marshal.ReadInt16(buffer, 14);
                }
                finally
                {
                    Marshal.FreeHGlobal(buffer);
                }
            }
        }
예제 #30
0
        /// <summary>
        /// Gets the address of the module loaded into specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="moduleName">Name of the module.</param>
        public ulong GetModuleAddress(Process process, string moduleName)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                uint index;
                ulong moduleAddress;

                Symbols.GetModuleByModuleName2Wide(moduleName, 0, 0, out index, out moduleAddress);
                return moduleAddress;
            }
        }
예제 #31
0
        /// <summary>
        /// Gets the all memory regions available in the specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <returns>Array of <see cref="MemoryRegion"/> objects available in the specified process</returns>
        public MemoryRegion[] GetMemoryRegions(Process process)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                List<MemoryRegion> regionsList = new List<MemoryRegion>();
                ulong currentAddress = 0, baseAddress, regionSize;

                try
                {
                    while (true)
                    {
                        currentAddress = DataSpaces.GetNextDifferentlyValidOffsetVirtual(currentAddress);
                        if (currentAddress == 0)
                        {
                            break;
                        }

                        QueryVirtual(process, currentAddress, out baseAddress, out regionSize);

                        // Merge consecutive regions
                        if (regionsList.Count > 0 && regionsList[regionsList.Count - 1].MemoryEnd == baseAddress)
                            regionsList[regionsList.Count - 1] = new MemoryRegion { BaseAddress = regionsList[regionsList.Count - 1].BaseAddress, MemoryEnd = baseAddress + regionSize };
                        else
                            regionsList.Add(new MemoryRegion { BaseAddress = baseAddress, RegionSize = regionSize });
                        currentAddress = baseAddress + regionSize - 1;
                    }
                }
                catch
                {
                }

                return regionsList.ToArray();
            }
        }
예제 #32
0
        /// <summary>
        /// Finds the pattern in memory of the specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="memoryStart">The memory start.</param>
        /// <param name="memoryEnd">The memory end.</param>
        /// <param name="pattern">The pattern.</param>
        /// <param name="patternStart">The pattern start.</param>
        /// <param name="patternEnd">The pattern end.</param>
        /// <param name="searchAlignment">The search alignment in number of bytes. For a successful match, the difference between the location of the found pattern and memoryStart must be a multiple of searchAlignment.</param>
        /// <param name="searchWritableMemoryOnly">if set to <c>true</c> search through writable memory only.</param>
        /// <returns>Address of the successful match or 0 if patterns wasn't found.</returns>
        public ulong FindPatternInMemory(Process process, ulong memoryStart, ulong memoryEnd, byte[] pattern, int patternStart, int patternEnd, uint searchAlignment = 1, bool searchWritableMemoryOnly = false)
        {
            if (memoryEnd <= memoryStart)
            {
                throw new ArgumentOutOfRangeException("memoryEnd", "less than memoryStart");
            }

            int patternSize = patternEnd - patternStart;
            IntPtr pointer = Marshal.AllocHGlobal(patternSize);

            try
            {
                Marshal.Copy(pattern, patternStart, pointer, patternSize);
                using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
                {
                    return DataSpaces.SearchVirtual2(memoryStart, memoryEnd - memoryStart, searchWritableMemoryOnly ? 1U : 0U, pointer, (uint)patternSize, searchAlignment);
                }
            }
            catch (COMException ex)
            {
                if ((uint)ex.HResult == 0x9000001A)
                {
                    return 0;
                }

                throw;
            }
            finally
            {
                Marshal.FreeHGlobal(pointer);
            }
        }
예제 #33
0
 /// <summary>
 /// Releases the process that is being debugged.
 /// </summary>
 public void ContinueExecution(Process process)
 {
     using (var processSwitcher = new ProcessSwitcher(StateCache, process))
     {
         DebuggeeFlowController flowControler = debugeeFlowControlers[process.Id];
         flowControler.DebugStatusBreak.WaitOne();
         Control.Execute(0, "g", 0);
     }
 }
예제 #34
0
        /// <summary>
        /// Reads the memory from the specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="address">The memory address.</param>
        /// <param name="size">The buffer size.</param>
        /// <returns>
        /// Buffer containing read memory
        /// </returns>
        public MemoryBuffer ReadMemory(Process process, ulong address, uint size)
        {
            try
            {
                using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
                {
                    IntPtr buffer = Marshal.AllocHGlobal((int)size);
                    uint read;

                    try
                    {
                        DataSpaces.ReadVirtual(address, buffer, size, out read);

                        byte[] bytes = new byte[size];

                        Marshal.Copy(buffer, bytes, 0, (int)size);
                        return new MemoryBuffer(bytes);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(buffer);
                    }
                }
            }
            catch (Exception)
            {
                throw new InvalidMemoryAddressException(address);
            }
        }
예제 #35
0
 /// <summary>
 /// Gets the process environment block address of the specified process.
 /// </summary>
 /// <param name="process">The process.</param>
 public ulong GetProcessEnvironmentBlockAddress(Process process)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
     {
         return SystemObjects.GetCurrentProcessPeb();
     }
 }
 /// <summary>
 /// Gets the symbol tag of the specified type.
 /// </summary>
 /// <param name="module">The module.</param>
 /// <param name="typeId">The type identifier.</param>
 public SymTag GetTypeTag(Module module, uint typeId)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
     {
         return typedData[Tuple.Create(module.Address, typeId, module.Process.PebAddress)].Tag;
     }
 }
예제 #37
0
 /// <summary>
 /// Gets the executable name of the specified process.
 /// </summary>
 /// <param name="process">The process.</param>
 public string GetProcessExecutableName(Process process)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
     {
         return SystemObjects.GetCurrentProcessExecutableName();
     }
 }
        /// <summary>
        /// Gets the type pointer to type of the specified type.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="typeId">The type identifier.</param>
        public uint GetTypePointerToTypeId(Module module, uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                var typedData = DbgEngSymbolProvider.typedData[Tuple.Create(module.Address, typeId, module.Process.PebAddress)];
                typedData.Data = module.Process.PebAddress;
                var result = dbgEngDll.Advanced.Request(DebugRequest.ExtTypedDataAnsi, new EXT_TYPED_DATA()
                {
                    Operation = ExtTdop.GetPointerTo,
                    InData = typedData,
                }).OutData.TypeId;

                return result;
            }
        }
예제 #39
0
        /// <summary>
        /// Gets all modules of the specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        public Module[] GetProcessModules(Process process)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                uint loaded, unloaded;

                Symbols.GetNumberModules(out loaded, out unloaded);
                Module[] modules = new Module[loaded + unloaded];

                for (int i = 0; i < modules.Length; i++)
                {
                    ulong moduleId = Symbols.GetModuleByIndex((uint)i);

                    modules[i] = process.ModulesById[moduleId];
                }

                return modules;
            }
        }
예제 #40
0
        /// <summary>
        /// Gets all threads of the specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        public Thread[] GetProcessThreads(Process process)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                uint threadCount = SystemObjects.GetNumberThreads();
                Thread[] threads = new Thread[threadCount];
                uint[] threadIds = new uint[threadCount];
                uint[] threadSytemIds = new uint[threadCount];

                unsafe
                {
                    fixed (uint* ids = &threadIds[0])
                    fixed (uint* systemIds = &threadSytemIds[0])
                    {
                        SystemObjects.GetThreadIdsByIndex(0, threadCount, out *ids, out *systemIds);
                    }
                }

                for (uint i = 0; i < threadCount; i++)
                {
                    threads[i] = new Thread(threadIds[i], threadSytemIds[i], process);
                }

                return threads;
            }
        }
예제 #41
0
 /// <summary>
 /// Gets the up time of the specified process.
 /// </summary>
 /// <param name="process">The process.</param>
 public uint GetProcessUpTime(Process process)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
     {
         return SystemObjects.GetCurrentProcessUpTime();
     }
 }
 /// <summary>
 /// Gets the type identifier.
 /// </summary>
 /// <param name="module">The module.</param>
 /// <param name="typeName">Name of the type.</param>
 public uint GetTypeId(Module module, string typeName)
 {
     using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
     {
         return dbgEngDll.Symbols.GetTypeIdWide(module.Address, module.Name + "!" + typeName);
     }
 }
예제 #43
0
        /// <summary>
        /// Determines whether the specified process is being debugged as minidump without heap.
        /// </summary>
        /// <param name="process">The process.</param>
        public bool IsMinidump(Process process)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                uint cls, qual;

                Control.GetDebuggeeType(out cls, out qual);
                if (qual == (uint)Defines.DebugDumpSmall)
                {
                    uint flags = Control.GetDumpFormatFlags();

                    return (flags & (uint)Defines.DebugFormatUserSmallFullMemory) == 0;
                }
            }

            return false;
        }
        /// <summary>
        /// Gets the names of all fields of the specified type.
        /// </summary>
        /// <param name="module">The module.</param>
        /// <param name="typeId">The type identifier.</param>
        public string[] GetTypeAllFieldNames(Module module, uint typeId)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, module.Process))
            {
                List<string> fields = new List<string>();
                uint nameSize;

                try
                {
                    for (uint fieldIndex = 0; ; fieldIndex++)
                    {
                        StringBuilder sb = new StringBuilder(Constants.MaxSymbolName);

                        dbgEngDll.Symbols.GetFieldName(module.Address, typeId, fieldIndex, sb, (uint)sb.Capacity, out nameSize);
                        fields.Add(sb.ToString());
                    }
                }
                catch (Exception)
                {
                }

                return fields.ToArray();
            }
        }
예제 #45
0
        /// <summary>
        /// Finds memory range where the specified address belongs to.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="address">The address.</param>
        /// <param name="baseAddress">The base address.</param>
        /// <param name="regionSize">Size of the region.</param>
        public void QueryVirtual(Process process, ulong address, out ulong baseAddress, out ulong regionSize)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                var memoryInfo = DataSpaces.QueryVirtual(address);

                baseAddress = memoryInfo.BaseAddress;
                regionSize = memoryInfo.RegionSize;
            }
        }
        /// <summary>
        /// Gets the source file name and line for the specified address.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="address">The address.</param>
        /// <param name="sourceFileName">Name of the source file.</param>
        /// <param name="sourceFileLine">The source file line.</param>
        /// <param name="displacement">The displacement.</param>
        public void GetProcessAddressSourceFileNameAndLine(Process process, ulong address, out string sourceFileName, out uint sourceFileLine, out ulong displacement)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(DbgEngDll.StateCache, process))
            {
                uint fileNameLength;
                StringBuilder sb = new StringBuilder(Constants.MaxFileName);

                dbgEngDll.Symbols.GetLineByOffset(address, out sourceFileLine, sb, (uint)sb.Capacity, out fileNameLength, out displacement);
                sourceFileName = sb.ToString();
            }
        }
예제 #47
0
        /// <summary>
        /// Reads the unicode string.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <param name="address">The address.</param>
        /// <param name="length">The length. If length is -1, string is null terminated</param>
        public string ReadUnicodeString(Process process, ulong address, int length = -1)
        {
            try
            {
                using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
                {
                    bool readAll = true;

                    if (length < 0)
                    {
                        readAll = false;
                        length = (int)Constants.MaxStringReadLength;
                    }

                    uint byteLength = 0;
                    StringBuilder sb = new StringBuilder(length);

                    if (readAll)
                    {
                        while (length > 0)
                        {
                            StringBuilder temp = new StringBuilder(length);

                            DataSpaces.ReadUnicodeStringVirtualWide(address, (uint)temp.Capacity * 2, temp, (uint)temp.Capacity, out byteLength);
                            sb.Append(temp);
                            length -= (int)byteLength / 2;
                            if (length > 0)
                            {
                                address += byteLength;
                                sb.Append('\0');
                            }
                        }
                    }
                    else
                    {
                        DataSpaces.ReadUnicodeStringVirtualWide(address, (uint)sb.Capacity * 2, sb, (uint)sb.Capacity, out byteLength);
                    }

                    return sb.ToString();
                }
            }
            catch (Exception)
            {
                throw new InvalidMemoryAddressException(address);
            }
        }
예제 #48
0
        /// <summary>
        /// Gets the dump file name of the specified process.
        /// </summary>
        /// <param name="process">The process.</param>
        public string GetProcessDumpFileName(Process process)
        {
            using (ProcessSwitcher switcher = new ProcessSwitcher(StateCache, process))
            {
                uint dumpsFiles = Client.GetNumberDumpFiles();

                if (dumpsFiles > 1)
                {
                    throw new Exception("Unexpected number of dump files");
                }

                if (dumpsFiles == 1)
                {
                    StringBuilder sb = new StringBuilder(Constants.MaxFileName);
                    uint nameSize, type;
                    ulong handle;

                    Client.GetDumpFileWide(0, sb, (uint)sb.Capacity, out nameSize, out handle, out type);
                    return sb.ToString();
                }

                return "";
            }
        }
예제 #49
0
        /// <summary>
        /// Breaks the process that is being debugged.
        /// </summary>
        public void BreakExecution(Process process)
        {
            using (var processSwitcher = new ProcessSwitcher(StateCache, process))
            {
                DebuggeeFlowController flowControler = debugeeFlowControlers[process.Id];
                flowControler.DebugStatusBreak.Reset();
                Control.SetInterrupt(0);
                flowControler.DebugStatusBreak.WaitOne();

                // Drop the cache.
                // TODO: When support for debugging multiple processes is added.
                //       this needs to clear the cache of all the processes.
                //
                process.InvalidateProcessCache();
            }
        }