/// <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)); } }
/// <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)); } }
/// <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)); } }
/// <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()); } }
/// <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)); } }
/// <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); } }
/// <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()); } }
/// <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()); } }
/// <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(); } }
/// <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 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)); } }
/// <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); } }
/// <summary> /// Gets the type pointer to type of the specified type. /// </summary> /// <param name="typeId">The type identifier.</param> /// <returns>Type id to pointer type, or <c>int.MaxValue</c> if it doesn't exist and fake should be used.</returns> 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); } }
/// <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); } }
/// <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)); } } }
/// <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()); } }