/// <summary> /// Verifies if the specified code type is correct for this class. /// </summary> /// <param name="codeType">The code type.</param> /// <returns>Extracted data object or <c>null</c> if fails.</returns> internal static object VerifyCodeType(CodeType codeType) { // We want to have this kind of hierarchy // __end_ // | __next_ // | __prev_ // | __value_ (exists in list node type) // __size_alloc_ // | __value_ CodeType __end_, __next_, __prev_, __size_alloc_, __value_; if (!codeType.GetFieldTypes().TryGetValue("__end_", out __end_)) { return(null); } if (!__end_.GetFieldTypes().TryGetValue("__next_", out __next_) || !__end_.GetFieldTypes().TryGetValue("__prev_", out __prev_)) { return(null); } if (!codeType.GetFieldTypes().TryGetValue("__size_alloc_", out __size_alloc_)) { return(null); } if (!__size_alloc_.GetFieldTypes().TryGetValue("__value_", out __value_)) { return(null); } CodeType listNodeType, __value_2; try { CodeType listNodeBaseType = codeType.GetFieldType("__end_"); const string listNodeBaseNameStart = "std::__1::__list_node_base<"; const string listNodeNameStart = "std::__1::__list_node<"; listNodeType = CodeType.Create(listNodeNameStart + listNodeBaseType.Name.Substring(listNodeBaseNameStart.Length), listNodeBaseType.Module); } catch { return(null); } if (!listNodeType.GetFieldTypes().TryGetValue("__value_", out __value_2)) { return(null); } return(new ExtractedData { ReadLength = codeType.Module.Process.GetReadInt(codeType, "__size_alloc_.__value_"), HeadOffset = codeType.GetFieldOffset("__end_") + __end_.GetFieldOffset("__next_"), HeadHasValue = true, ItemNextOffset = listNodeType.GetFieldOffset("__next_"), ItemPreviousOffset = listNodeType.GetFieldOffset("__prev_"), ItemValueOffset = listNodeType.GetFieldOffset("__value_"), ItemValueCodeType = __value_2, CodeType = codeType, Process = codeType.Module.Process, }); }
/// <summary> /// Reinterpret Cast, changes underlaying code type. /// </summary> /// <remarks> /// Requested Type must be a primitive (int, short etc). /// </remarks> /// <typeparam name="T">Primitive type to cast variable to.</typeparam> /// <param name="variable">The variable.</param> /// <returns>Return CodePointer to Variable pointer address.</returns> public static CodePointer <T> ReinterpretPointerCast <T>(this Variable variable) where T : struct { // Get CodeType from the generic argument. // string codeTypeName; if (typeof(T) == typeof(int)) { codeTypeName = "int"; } else if (typeof(T) == typeof(short)) { codeTypeName = "short"; } else if (typeof(T) == typeof(uint)) { codeTypeName = "unsigned int"; } else if (typeof(T) == typeof(ushort)) { codeTypeName = "unsigned short"; } else { throw new NotSupportedException("Requested type is not supported."); } // Return CodePointer<T> // return(new CodePointer <T>( Variable.CreatePointer( CodeType.Create(codeTypeName, variable.GetCodeType().Module).PointerToType, variable.GetPointerAddress()))); }
/// <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> /// Initializes a new instance of the <see cref="GenericsElementCaster{T}"/> class. /// </summary> /// <param name="parentCodeType">CodeType of the generics class that will be using this helper class.</param> /// <param name="argumentNumber">The argument number in original user type.</param> public GenericsElementCaster(CodeType parentCodeType, int argumentNumber) { try { elementCodeType = CodeType.Create(parentCodeType.TemplateArgumentsStrings[argumentNumber], parentCodeType.Module); } catch (Exception) { } }
/// <summary> /// Initializes a new instance of the <see cref="LibStdCpp6_NoAbi"/> class. /// </summary> /// <param name="variable">The variable.</param> public LibStdCpp6_NoAbi(Variable variable) { CodeType codeType = variable.GetCodeType(); CodeType _Rep = CodeType.Create($"{codeType.Name}::_Rep", codeType.Module); header = UserMember.Create(() => text.Value.AdjustPointer(-(int)_Rep.Size).CastAs(_Rep)); length = UserMember.Create(() => (int)header.Value.GetField("_M_length")); text = UserMember.Create(() => variable.GetField("_M_dataplus").GetField("_M_p")); capacity = UserMember.Create(() => (int)header.Value.GetField("_M_capacity")); }
/// <summary> /// Verifies if the specified code type is correct for this class. /// </summary> /// <param name="codeType">The code type.</param> /// <returns>Extracted data object or <c>null</c> if fails.</returns> internal static object VerifyCodeType(CodeType codeType) { // We want to have this kind of hierarchy // _M_dataplus // | _M_p // basic_string<>::_Rep type // _M_length // _M_capacity // _M_refcount CodeType _M_dataplus, _M_p, _Rep, _M_length, _M_capacity, _M_refcount; try { _Rep = CodeType.Create($"{codeType.Name}::_Rep", codeType.Module); } catch { return(null); } if (!codeType.GetFieldTypes().TryGetValue("_M_dataplus", out _M_dataplus)) { return(null); } if (!_M_dataplus.GetFieldTypes().TryGetValue("_M_p", out _M_p)) { return(null); } if (!_Rep.GetFieldTypes().TryGetValue("_M_length", out _M_length)) { return(null); } if (!_Rep.GetFieldTypes().TryGetValue("_M_capacity", out _M_capacity)) { return(null); } if (!_Rep.GetFieldTypes().TryGetValue("_M_refcount", out _M_refcount)) { return(null); } int repOffset = -(int)_Rep.Size; return(new ExtractedData { ReadLength = codeType.Module.Process.GetReadInt(_Rep, "_M_length", repOffset), ReadCapacity = codeType.Module.Process.GetReadInt(_Rep, "_M_capacity", repOffset), CharSize = (int)_M_p.ElementType.Size, PointerOffset = codeType.GetFieldOffset("_M_dataplus") + _M_dataplus.GetFieldOffset("_M_p"), CodeType = codeType, Process = codeType.Module.Process, }); }
public void TestGetTypeByName() { Module types = Process.Current.Modules.Where(m => m.Name == "Types").Single(); Assert.IsNotNull(CodeType.Create("Foo", types)); try { CodeType.Create("Foo2", types); Assert.Fail(); } catch (Exception ex) { Assert.AreEqual("Type 'Foo2' wasn't found", ex.Message); } }
public void FieldNameAndValueTests() { IClrHeap heap = Process.Current.ClrRuntimes.Single().Heap; Module typesModule = Module.All.Single(m => m.Name == "Types"); CodeType fooType = CodeType.Create("Foo", typesModule); Variable s_foo = typesModule.GetVariable("Types.s_foo"); Assert.Equal(fooType, s_foo.GetCodeType()); Assert.Equal(42, (int)s_foo.GetField("i")); Assert.Equal("string", new ClrString(s_foo.GetField("s")).Text); Assert.True((bool)s_foo.GetField("b")); Assert.Equal(4.2f, (float)s_foo.GetField("f")); Assert.Equal(8.4, (double)s_foo.GetField("d")); Assert.Contains(s_foo, heap.EnumerateObjects()); }
public void TestGetTypeByName() { Module types = Process.Current.Modules.Where(m => m.Name == "Types").Single(); Assert.NotNull(CodeType.Create("Foo", types)); try { CodeType.Create("Foo2", types); throw new Exception("This should never happen"); } catch (Exception ex) { Assert.Equal("Type 'Foo2' wasn't found", ex.Message); } }
/// <summary> /// Finds _List_node code type for the specified list code type. /// </summary> /// <param name="codeType">std::list code type</param> private static CodeType GetListNodeCodeType(CodeType codeType) { string elementTypeName = codeType.TemplateArgumentsStrings[0]; string listNodeCodeTypeName; if (elementTypeName.EndsWith(">")) { listNodeCodeTypeName = $"std::_List_node<{elementTypeName} >"; } else { listNodeCodeTypeName = $"std::_List_node<{elementTypeName}>"; } return(CodeType.Create(listNodeCodeTypeName, codeType.Module)); }
public void TestGetTypeByName() { var modules = Process.Current.Modules; Module types = modules.Where(m => m.Name == "Types").Single(); Exception ex = Assert.Throws <Exception>(() => CodeType.Create("Foo", types)); Assert.Equal("Type 'Foo' wasn't found", ex.Message); Module sharedLibrary = modules.Where(m => m.Name == "SharedLibrary").Single(); Assert.NotNull(CodeType.Create("Foo", sharedLibrary)); ex = Assert.Throws <Exception>(() => CodeType.Create("Foo2", sharedLibrary)); Assert.Equal("Type 'Foo2' wasn't found", ex.Message); }
/// <summary> /// Initializes a new instance of the <see cref="ClangLibCpp"/> class. /// </summary> /// <param name="variable">The variable.</param> /// <param name="savedData">Data returned from VerifyCodeType function.</param> public ClangLibCpp(Variable variable, object savedData) { data = (ExtractedData)savedData; address = variable.GetPointerAddress(); ulong managerAddress = data.Process.ReadPointer(address + (uint)data.ManagerPointerOffset); if (managerAddress != 0) { Tuple <string, ulong> nameAndOffset = Context.SymbolProvider.GetSymbolNameByAddress(data.Process, managerAddress); if (nameAndOffset != null) { managerName = nameAndOffset.Item1; } } if (HasValue) { string codeTypeName; string handlerCodeTypeName; if (IsSmall) { string moduleName = managerName.Substring(0, managerName.IndexOf('!') + 1); codeTypeName = moduleName + managerName.Substring(moduleName.Length + SmallHandlerNameStart.Length, managerName.Length - moduleName.Length - SmallHandlerNameStart.Length - SmallHandlerNameEnd.Length); handlerCodeTypeName = $"{moduleName}std::__1::__any_imp::_SmallHandler<{codeTypeName.Substring(moduleName.Length)}>"; } else if (IsLarge) { string moduleName = managerName.Substring(0, managerName.IndexOf('!') + 1); codeTypeName = moduleName + managerName.Substring(moduleName.Length + LargeHandlerNameStart.Length, managerName.Length - moduleName.Length - LargeHandlerNameStart.Length - LargeHandlerNameEnd.Length); handlerCodeTypeName = $"{moduleName}std::__1::__any_imp::_LargeHandler<{codeTypeName.Substring(moduleName.Length)}>"; } else { throw new NotImplementedException(); } CodeType handlerCodeType = CodeType.Create(handlerCodeTypeName); valueCodeType = handlerCodeType.TemplateArguments[0] as CodeType ?? CodeType.Create(codeTypeName.Trim()); } }
/// <summary> /// Gets the runtime code type and offset to original code type. /// </summary> /// <param name="vtableAddress">The vtable address within the module.</param> public Tuple <CodeType, int> GetRuntimeCodeTypeAndOffset(uint vtableAddress) { IDiaSymbol symbol; int displacement; string fullyUndecoratedName, partiallyUndecoratedName; session.findSymbolByRVAEx(vtableAddress, SymTagEnum.PublicSymbol, out symbol, out displacement); fullyUndecoratedName = symbol.get_undecoratedNameEx(UndecoratedNameOptions.NameOnly | UndecoratedNameOptions.NoEscu) ?? symbol.name; partiallyUndecoratedName = symbol.get_undecoratedNameEx(UndecoratedNameOptions.NoEscu) ?? symbol.name; // Fully undecorated name should be in form: "DerivedClass::`vftable'" or "DerivedClass::`vbtable'" const string vftableString = "::`vftable'"; const string vbtableString = "::`vbtable'"; string vtableString = vftableString; if (string.IsNullOrEmpty(fullyUndecoratedName) || !fullyUndecoratedName.EndsWith(vftableString)) { vtableString = vbtableString; if (string.IsNullOrEmpty(fullyUndecoratedName) || !fullyUndecoratedName.EndsWith(vbtableString)) { // Pointer is not vtable. return(null); } } string codeTypeName = fullyUndecoratedName.Substring(0, fullyUndecoratedName.Length - vtableString.Length); CodeType codeType = CodeType.Create(codeTypeName, Module); // Partially undecorated name should be in form: "const DerivedClass::`vftable'{for `BaseClass'}" string partiallyUndecoratedNameStart = string.Format("const {0}{1}{{for `", codeTypeName, vtableString); if (!partiallyUndecoratedName.StartsWith(partiallyUndecoratedNameStart)) { // Single Inheritace return(Tuple.Create(codeType, 0)); } string innerCodeTypeName = partiallyUndecoratedName.Substring(partiallyUndecoratedNameStart.Length, partiallyUndecoratedName.Length - 2 - partiallyUndecoratedNameStart.Length); var baseClassWithVTable = codeType.BaseClasses[innerCodeTypeName]; return(Tuple.Create(codeType, baseClassWithVTable.Item2)); }
public void ArrayTests() { Module typesModule = Module.All.Single(m => m.Name == "Types"); CodeType fooType = CodeType.Create("Types", typesModule); Variable s_array = fooType.GetStaticField("s_array"); Variable s_one = fooType.GetStaticField("s_one"); Variable s_two = fooType.GetStaticField("s_two"); Variable s_three = fooType.GetStaticField("s_three"); CodeArray <Variable> codeArray = new CodeArray <Variable>(s_array); Variable[] expected = new Variable[] { s_one, s_two, s_three }; Assert.Equal(expected.Length, codeArray.Length); for (int i = 0; i < expected.Length; i++) { Assert.Equal(expected[i], codeArray[i]); } }
public void TestBuiltinTypes() { CodeType codeType = CodeType.Create("BuiltinTypesTest", DefaultModule); VerifyFieldBuiltinType(codeType, "b", BuiltinType.Bool); VerifyFieldBuiltinType(codeType, "c1", BuiltinType.Char8, BuiltinType.Int8); VerifyFieldBuiltinType(codeType, "c2", BuiltinType.Char16, BuiltinType.Char32); VerifyFieldBuiltinType(codeType, "i8", BuiltinType.Int8, BuiltinType.Char8); VerifyFieldBuiltinType(codeType, "i16", BuiltinType.Int16); VerifyFieldBuiltinType(codeType, "i32", BuiltinType.Int32); VerifyFieldBuiltinType(codeType, "i64", BuiltinType.Int64); VerifyFieldBuiltinType(codeType, "u8", BuiltinType.UInt8); VerifyFieldBuiltinType(codeType, "u16", BuiltinType.UInt16); VerifyFieldBuiltinType(codeType, "u32", BuiltinType.UInt32); VerifyFieldBuiltinType(codeType, "u64", BuiltinType.UInt64); VerifyFieldBuiltinType(codeType, "f32", BuiltinType.Float32); VerifyFieldBuiltinType(codeType, "f64", BuiltinType.Float64); VerifyFieldBuiltinType(codeType, "f80", BuiltinType.Float80, BuiltinType.Float64); }
/// <summary> /// Verifies if the specified code type is correct for this class. /// </summary> /// <param name="codeType">The code type.</param> internal static bool VerifyCodeType(CodeType codeType) { // We want to have this kind of hierarchy // _M_dataplus // | _M_p // basic_string<>::_Rep type // _M_length // _M_capacity // _M_refcount CodeType _M_dataplus, _M_p, _Rep, _M_length, _M_capacity, _M_refcount; try { _Rep = CodeType.Create($"{codeType.Name}::_Rep", codeType.Module); } catch { return(false); } if (!codeType.GetFieldTypes().TryGetValue("_M_dataplus", out _M_dataplus)) { return(false); } if (!_M_dataplus.GetFieldTypes().TryGetValue("_M_p", out _M_p)) { return(false); } if (!_Rep.GetFieldTypes().TryGetValue("_M_length", out _M_length)) { return(false); } if (!_Rep.GetFieldTypes().TryGetValue("_M_capacity", out _M_capacity)) { return(false); } if (!_Rep.GetFieldTypes().TryGetValue("_M_refcount", out _M_refcount)) { return(false); } return(true); }
/// <summary> /// Resolves code type by the specified name. /// </summary> /// <param name="process">The process where type is defined.</param> /// <param name="module">The module where type is defined.</param> /// <param name="codeTypeName">The code type name.</param> /// <returns>Resolved code type.</returns> internal static CodeType ResolveCodeType(Process process, Module module, string codeTypeName) { CodeType codeType; int pointer = 0; FixCodeTypeSearchName(ref codeTypeName); while (codeTypeName.EndsWith("*")) { pointer++; codeTypeName = codeTypeName.Substring(0, codeTypeName.Length - 1).TrimEnd(); FixCodeTypeSearchName(ref codeTypeName); } FixCodeTypeSearchName(ref codeTypeName); codeType = CodeType.Create(process, codeTypeName, module); for (int i = 0; i < pointer; i++) { codeType = codeType.PointerToType; } return(codeType); }
/// <summary> /// Initializes a new instance of the <see cref="VisualStudio"/> class. /// </summary> /// <param name="variable">The variable.</param> /// <param name="savedData">Data returned from VerifyCodeType function.</param> public VisualStudio(Variable variable, object savedData) { data = (ExtractedData)savedData; address = variable.GetPointerAddress(); typeData = data.Process.ReadPointer(address + (uint)data.TypeDataOffset); if (HasValue) { Tuple <string, ulong> nameAndOffset = Context.SymbolProvider.GetSymbolNameByAddress(data.Process, TypeInfoAddress); if (nameAndOffset != null) { string name = nameAndOffset.Item1; if (name.EndsWith(rttiSignature)) { name = name.Substring(0, name.Length - rttiSignature.Length); valueCodeType = CodeType.Create(name); } } } }
/// <summary> /// Initializes a new instance of the <see cref="LibStdCpp7"/> class. /// </summary> /// <param name="variable">The variable.</param> /// <param name="savedData">Data returned from VerifyCodeType function.</param> public LibStdCpp7(Variable variable, object savedData) { data = (ExtractedData)savedData; address = variable.GetPointerAddress(); ulong managerAddress = data.Process.ReadPointer(address + (uint)data.ManagerPointerOffset); if (managerAddress != 0) { Tuple <string, ulong> nameAndOffset = Context.SymbolProvider.GetSymbolNameByAddress(data.Process, managerAddress); if (nameAndOffset != null) { managerName = nameAndOffset.Item1; } } if (HasValue) { string codeTypeName; if (IsInternal) { string moduleName = managerName.Substring(0, managerName.IndexOf('!') + 1); codeTypeName = moduleName + managerName.Substring(moduleName.Length + InternalManagerNameStart.Length, managerName.Length - moduleName.Length - InternalManagerNameStart.Length - InternalManagerNameEnd.Length); } else if (IsExternal) { string moduleName = managerName.Substring(0, managerName.IndexOf('!') + 1); codeTypeName = moduleName + managerName.Substring(moduleName.Length + ExternalManagerNameStart.Length, managerName.Length - moduleName.Length - ExternalManagerNameStart.Length - ExternalManagerNameEnd.Length); } else { throw new NotImplementedException(); } valueCodeType = CodeType.Create(codeTypeName.Trim()); } }
/// <summary> /// Gets the runtime code type and offset to original code type. /// </summary> /// <param name="process">The process.</param> /// <param name="vtableAddress">The vtable address.</param> /// <param name="distance">The distance within the module.</param> public Tuple <CodeType, int> GetRuntimeCodeTypeAndOffset(Process process, ulong vtableAddress, uint distance) { IDiaSymbol symbol; int displacement; string fullyUndecoratedName, partiallyUndecoratedName; session.findSymbolByRVAEx(distance, SymTagEnum.SymTagNull, out symbol, out displacement); symbol.get_undecoratedNameEx(0 | 0x8000 | 0x1000, out fullyUndecoratedName); symbol.get_undecoratedNameEx(0 | 0x8000, out partiallyUndecoratedName); // Fully undecorated name should be in form: "DerivedClass::`vftable'" 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(codeTypeName, Module); // Partially undecorated name should be in form: "const DerivedClass::`vftable'{for `BaseClass'}" string partiallyUndecoratedNameStart = string.Format("const {0}{1}{{for `", codeTypeName, vftableString); if (!partiallyUndecoratedName.StartsWith(partiallyUndecoratedNameStart)) { // Single Inheritace return(Tuple.Create(codeType, 0)); } string innerCodeTypeName = partiallyUndecoratedName.Substring(partiallyUndecoratedNameStart.Length, partiallyUndecoratedName.Length - 2 - partiallyUndecoratedNameStart.Length); var baseClassWithVTable = codeType.BaseClasses[innerCodeTypeName]; return(Tuple.Create(codeType, baseClassWithVTable.Item2)); }
/// <summary> /// Gets the code type for Heap for the specified process. /// </summary> /// <param name="process">The process.</param> public static CodeType GetCodeType(Process process) { return(CodeType.Create(process, "ntdll!_HEAP", "nt!_HEAP", "wow64!_HEAP")); }
/// <summary> /// Gets the pointer code type for the specified process. /// </summary> /// <param name="process">The process.</param> private static CodeType GetPointerCodeType(Process process) { return(CodeType.Create(CodeType.NakedPointerCodeTypeName, process.Modules[0])); }
/// <summary> /// Verifies if the specified code type is correct for this class. /// </summary> /// <param name="codeType">The code type.</param> /// <returns>Extracted data object or <c>null</c> if fails.</returns> internal static object VerifyCodeType(CodeType codeType) { // We want to have this kind of hierarchy // __tree_ // | __begin_node_ // | __left_ // | __is_black_ // | __left_ // | __parent_ // | __right_ // | __pair1_ // | __value_ (same type as __begin_node_) // | __left_ // | __is_black_ // | __left_ // | __parent_ // | __right_ // | __pair3_ // | __value_ CodeType __tree_, __begin_node_, __left_, __is_black_, __left_2, __parent_, __right_, __pair1_, __value_, __pair3_, __value_2; if (!codeType.GetFieldTypes().TryGetValue("__tree_", out __tree_)) { return(null); } if (!__tree_.GetFieldTypes().TryGetValue("__begin_node_", out __begin_node_) || !__tree_.GetFieldTypes().TryGetValue("__pair1_", out __pair1_) || !__tree_.GetFieldTypes().TryGetValue("__pair3_", out __pair3_)) { return(null); } if (!__begin_node_.GetFieldTypes().TryGetValue("__left_", out __left_)) { return(null); } if (!__left_.GetFieldTypes().TryGetValue("__is_black_", out __is_black_) || !__left_.GetFieldTypes().TryGetValue("__left_", out __left_2) || !__left_.GetFieldTypes().TryGetValue("__parent_", out __parent_) || !__left_.GetFieldTypes().TryGetValue("__right_", out __right_)) { return(null); } if (!__pair1_.GetFieldTypes().TryGetValue("__value_", out __value_) || __value_ != __begin_node_.ElementType) { return(null); } if (!__pair3_.GetFieldTypes().TryGetValue("__value_", out __value_2)) { return(null); } CodeType pairCodeType, treeNodeCodeType; string pairFieldName; try { CodeType valueCodeType = (CodeType)__tree_.TemplateArguments[0]; pairFieldName = valueCodeType.GetFieldTypes().ContainsKey("__nc") ? "__nc" : "__cc"; pairCodeType = valueCodeType.GetFieldType(pairFieldName); CodeType treeNodeBaseCodeType = __left_.ElementType; const string treeNodeBaseNameStart = "std::__1::__tree_node_base<"; const string treeNodeNameStart = "std::__1::__tree_node<"; string treeNodeName = treeNodeNameStart + valueCodeType.Name + ", " + treeNodeBaseCodeType.Name.Substring(treeNodeBaseNameStart.Length); treeNodeCodeType = CodeType.Create(treeNodeName, valueCodeType.Module); } catch { return(null); } if (!pair <TKey, TValue> .VerifyCodeType(pairCodeType)) { return(null); } return(new ExtractedData { ReadSize = codeType.Module.Process.GetReadInt(codeType, "__tree_.__pair3_.__value_"), HeadIsPointer = true, HeadIsAtParent = false, HeadOffset = codeType.GetFieldOffset("__tree_") + __tree_.GetFieldOffset("__pair1_") + __pair1_.GetFieldOffset("__value_") + __value_.GetFieldOffset("__left_"), ItemLeftOffset = treeNodeCodeType.GetFieldOffset("__left_"), ItemParentOffset = treeNodeCodeType.GetFieldOffset("__parent_"), ItemRightOffset = treeNodeCodeType.GetFieldOffset("__right_"), ItemValueOffset = treeNodeCodeType.GetFieldOffset("__value_") + treeNodeCodeType.GetFieldType("__value_").GetFieldOffset(pairFieldName), ItemValueCodeType = pairCodeType, ReadItemIsNil = null, CodeType = codeType, Process = codeType.Module.Process, }); }