/// <summary> /// Initializes a new instance of the <see cref="WrongCodeTypeException" /> class. /// </summary> /// <param name="variable">The variable.</param> /// <param name="argumentName">Name of the argument.</param> /// <param name="expectedText">The expected text.</param> public WrongCodeTypeException(Variable variable, string argumentName, string expectedText) : base(string.Format("Wrong code type [{0}] of passed parameter '{1}'. Expected {2}.", variable.GetCodeType().Name, argumentName, expectedText)) { Variable = variable; CodeType = variable.GetCodeType(); ArgumentName = argumentName; }
/// <summary> /// Initializes a new instance of the <see cref="CodeFunction"/> class. /// </summary> /// <param name="variable">The variable.</param> public CodeFunction(Variable variable) : this(variable.GetPointerAddress(), variable.GetCodeType().Module.Process) { // Verify code type if (!VerifyCodeType(variable.GetCodeType())) { throw new WrongCodeTypeException(variable, nameof(variable), "function"); } }
/// <summary> /// Initializes a new instance of the <see cref="ClrString"/> class. /// </summary> /// <param name="variable">The variable.</param> public ClrString(Variable variable) : base(variable) { // Check if code type is string type ClrCodeType codeType = variable.GetCodeType() as ClrCodeType; if (codeType == null || !codeType.ClrType.IsString) { throw new WrongCodeTypeException(variable.GetCodeType(), nameof(variable), "System.String"); } }
/// <summary> /// Initializes a new instance of the <see cref="pair{TFirst, TSecond}"/> class. /// </summary> /// <param name="variable">The variable.</param> /// <exception cref="WrongCodeTypeException">std::pair</exception> public pair(Variable variable) : base(variable) { // Verify code type if (!VerifyCodeType(variable.GetCodeType())) { throw new WrongCodeTypeException(variable, nameof(variable), "std::pair"); } // Initialize members first = UserMember.Create(() => variable.GetField("first").CastAs <TFirst>()); second = UserMember.Create(() => variable.GetField("second").CastAs <TSecond>()); }
public void GetFieldTests() { IClrThread clrThread = Thread.Current.ClrThread; StackFrame frame = clrThread.ClrStackTrace.Frames.Where(f => f.FunctionNameWithoutModule.StartsWith("Program.Main(")).Single(); Variable foo = frame.Locals["foo"]; Assert.Equal("Foo", foo.GetCodeType().Name); Assert.True((bool)foo.GetField("b")); Variable inner = foo.GetField("st").GetField("middle").GetField("inner"); Assert.True((bool)inner.GetField("b")); }
/// <summary> /// Initializes a new instance of the <see cref="VariableResultVisualizer"/> class. /// </summary> /// <param name="variable">Variable to be visualized.</param> /// <param name="variableType">Type of the resulting object that should be visualized.</param> /// <param name="name">Name of the variable / property.</param> /// <param name="dataType">Data type that will be used to generate icon of the variable / property</param> /// <param name="interactiveResultVisualizer">Interactive result visualizer that can be used for creating UI elements.</param> public VariableResultVisualizer(Variable variable, Type variableType, string name, CompletionDataType dataType, InteractiveResultVisualizer interactiveResultVisualizer) : base(variable, variableType, name, dataType, interactiveResultVisualizer) { this.variable = variable; try { extractUsingClasses = variable.GetCodeType().ClassFieldNames != null; } catch { extractUsingClasses = false; } }
public void ReadingFloatPointTypes() { Variable doubleTest = DefaultModule.GetVariable("doubleTest"); Assert.AreEqual(3.5, (double)doubleTest.GetField("d")); Assert.AreEqual(2.5, (float)doubleTest.GetField("f")); Assert.AreEqual(5, (int)doubleTest.GetField("i")); Variable doubleTest2 = Process.Current.GetGlobal($"{DefaultModuleName}!doubleTest"); Assert.AreEqual(doubleTest.GetPointerAddress(), doubleTest2.GetPointerAddress()); Assert.AreEqual(doubleTest.GetCodeType(), doubleTest2.GetCodeType()); }
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()); }
/// <summary> /// Initializes a new instance of the <see cref="Exception"/> class. /// </summary> /// <param name="variable">The variable.</param> public Exception(Variable variable) : base(variable) { // Check if code type is exception type ClrCodeType codeType = variable.GetCodeType() as ClrCodeType; bool found = false; while (!found && codeType != null) { if (codeType.Name == "System.Exception") { found = true; } else { codeType = (ClrCodeType)codeType.InheritedClass; } } if (!found) { throw new WrongCodeTypeException(variable.GetCodeType(), nameof(variable), "System.Exception"); } }
/// <summary> /// Initializes a new instance of the <see cref="shared_ptr{T}"/> class. /// </summary> /// <param name="variable">The variable.</param> public shared_ptr(Variable variable) { // Verify code type if (!VerifyCodeType(variable.GetCodeType())) { throw new WrongCodeTypeException(variable, nameof(variable), "std::shared_ptr"); } // Initialize members pointer = UserMember.Create(() => variable.GetField("_Ptr")); element = UserMember.Create(() => pointer.Value.DereferencePointer().CastAs <T>()); sharedCount = UserMember.Create(() => (int)variable.GetField("_Rep").GetField("_Uses")); weakCount = UserMember.Create(() => (int)variable.GetField("_Rep").GetField("_Weaks")); isCreatedWithMakeShared = UserMember.Create(() => variable.GetField("_Rep").DowncastInterface().GetCodeType().Name.StartsWith("std::_Ref_count_obj<")); }
/// <summary> /// Initializes a new instance of the <see cref="ClrException"/> class. /// </summary> /// <param name="variable">The variable.</param> public ClrException(Variable variable) : base(variable) { // Check if code type is exception type ClrCodeType codeType = variable.GetCodeType() as ClrCodeType; bool found = false; while (!found && codeType != null) { if (codeType.Name == "System.Exception") { found = true; } else { codeType = (ClrCodeType)codeType.InheritedClass; } } if (!found) { throw new WrongCodeTypeException(variable.GetCodeType(), nameof(variable), "System.Exception"); } }
/// <summary> /// Does the full downcast, looks up the type based on virtual table and shifts variable address if multi-inheritance was involved. /// </summary> /// <param name="variable">The variable.</param> public static Variable DowncastInterface(this Variable variable) { if (variable == null) { return(null); } var runtimeTypeAndOffset = variable.runtimeCodeTypeAndOffset.Value; if (runtimeTypeAndOffset.Item2 != 0 || variable.GetCodeType() != runtimeTypeAndOffset.Item1) { return(Variable.CreatePointer(runtimeTypeAndOffset.Item1.PointerToType, variable.GetPointerAddress() - (uint)runtimeTypeAndOffset.Item2)); } return(variable); }
public void ObjectArgumentAndLocalTest() { ClrThread clrThread = Thread.Current.FindClrThread(); StackFrame frame = clrThread.ClrStackTrace.Frames.Where(f => f.FunctionNameWithoutModule.StartsWith("Program.Main(")).Single(); Variable args = frame.Arguments.Single(); Assert.IsNotNull(args); Assert.AreEqual("System.String[]", args.GetCodeType().Name); Assert.AreEqual("args", args.GetName()); Variable foo = frame.Locals.Single(); Assert.IsNotNull(foo); Assert.IsFalse(foo.IsNullPointer()); Assert.AreEqual("Foo", foo.GetCodeType().Name); Assert.AreEqual("foo", foo.GetName()); Assert.AreEqual(8.4, (double)foo.GetField("d")); Assert.AreEqual("Foo string", new ClrString(foo.GetField("FooString")).Text); }
/// <summary> /// Enumerates this unordered_map. /// </summary> private IEnumerable <KeyValuePair <TKey, TValue> > Enumerate() { //foreach (Variable bucket in buckets.Value) Variable bucket = beforeBegin.Value; { Variable element = bucket; while (element != null && !element.IsNullPointer()) { if (element.GetPointerAddress() != beforeBegin.Value.GetPointerAddress()) { ulong itemAddress = element.GetPointerAddress() + element.GetCodeType().ElementType.Size; pair <TKey, TValue> item = new pair <TKey, TValue>(Variable.Create(elementCodeType, itemAddress)); yield return(new KeyValuePair <TKey, TValue>(item.First, item.Second)); } element = element.GetField("_M_nxt"); } } }
/// <summary> /// Initializes a new instance of the <see cref="LibStdCpp6"/> class. /// </summary> /// <param name="variable">The variable.</param> public LibStdCpp6(Variable variable) { buckets = UserMember.Create(() => { Variable h = variable.GetField("_M_h"); Variable b = h.GetField("_M_buckets"); int count = (int)h.GetField("_M_bucket_count"); elementCodeType = (CodeType)h.GetCodeType().TemplateArguments[1]; return(new CodeArray <Variable>(b, count)); }); beforeBegin = UserMember.Create(() => { Variable h = variable.GetField("_M_h"); elementCodeType = (CodeType)h.GetCodeType().TemplateArguments[1]; return(h.GetField("_M_before_begin")); }); elementCount = UserMember.Create(() => (int)variable.GetField("_M_h").GetField("_M_element_count")); }
/// <summary> /// Creates <see cref="IBitmap"/> with the specified pixel type. /// </summary> /// <typeparam name="PixelType">Type of the pixel.</typeparam> /// <param name="width">Width of the image.</param> /// <param name="height">Height of the image.</param> /// <param name="data">Bitmap data.</param> /// <param name="channels">Description of the image channels.</param> /// <param name="stride">Bitmap stride.</param> /// <returns>Instance of the <see cref="IBitmap"/> object.</returns> public IBitmap CreateImage <PixelType>(dynamic width, dynamic height, dynamic data, ChannelType[] channels, dynamic stride = null) { int imageWidth = Convert.ToInt32(width); int imageHeight = Convert.ToInt32(width); int dataStride = stride == null ? -1 : Convert.ToInt32(stride); Variable dataVariable = data as Variable; NakedPointer dataPointer; if (dataVariable != null) { dataPointer = new NakedPointer(dataVariable.GetCodeType().Module.Process, dataVariable.GetPointerAddress()); } else { dataPointer = new NakedPointer(Convert.ToUInt64(data)); } // pixels will be PixelType[], but if we use dynamic, compiler will do the magic to call the right function. dynamic pixels = ReadPixels <PixelType>(imageWidth, imageHeight, dataPointer, dataStride, channels.Length); return(Graphics.CreateBitmap(imageWidth, imageHeight, channels, pixels)); }
/// <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 templateCodeType = (CodeType)codeType.TemplateArguments[0]; CodeType listNodeCodeType = GetListNodeCodeType(codeType); count = UserMember.Create(() => { int count = 0; Variable start = anchor.Value; Variable next = start.GetField("_M_next"); while (next.GetPointerAddress() != start.GetPointerAddress()) { next = next.GetField("_M_next"); count++; } return(count); }); anchor = UserMember.Create(() => variable.GetField("_M_impl").GetField("_M_node")); head = UserMember.Create(() => new item(anchor.Value.GetField("_M_next").CastAs(listNodeCodeType), templateCodeType)); }
public void CheckCodeFunction() { StackFrame defaultTestCaseFrame = GetFrame($"{DefaultModuleName}!DefaultTestCase"); CodeFunction defaultTestCaseFunction = new CodeFunction(defaultTestCaseFrame.InstructionOffset); Assert.NotEqual(0U, defaultTestCaseFunction.Address); Assert.NotEqual(0U, defaultTestCaseFunction.FunctionDisplacement); Assert.Equal($"{DefaultModuleName}!DefaultTestCase", defaultTestCaseFunction.FunctionName); Assert.Equal($"DefaultTestCase", defaultTestCaseFunction.FunctionNameWithoutModule); Assert.Equal(Process.Current, defaultTestCaseFunction.Process); Assert.Contains(MainSourceFileName, defaultTestCaseFunction.SourceFileName.ToLower()); Assert.NotEqual(0U, defaultTestCaseFunction.SourceFileLine); Console.WriteLine("SourceFileDisplacement: {0}", defaultTestCaseFunction.SourceFileDisplacement); Variable codeFunctionVariable = DefaultModule.GetVariable($"{DefaultModuleName}!defaultTestCaseAddress"); Assert.True(codeFunctionVariable.GetCodeType().IsPointer); CodeFunction codeFunction = new CodePointer <CodeFunction>(new NakedPointer(codeFunctionVariable)).Element; Assert.Equal($"{DefaultModuleName}!DefaultTestCase", codeFunction.FunctionName); }
/// <summary> /// Reads the memory from current process. /// </summary> /// <param name="pointer">The pointer.</param> /// <param name="size">The size.</param> /// <returns>Buffer containing read memory</returns> public static MemoryBuffer ReadMemory(Variable pointer, uint size) { return(ReadMemory(pointer.GetCodeType().Module.Process, pointer, size)); }
/// <summary> /// Initializes a new instance of the <see cref="item" /> class. /// </summary> /// <param name="variable">The variable.</param> /// <param name="templateCodeType">Template code type.</param> public item(Variable variable, CodeType templateCodeType) { next = UserMember.Create(() => new item(variable.GetField("_M_next").CastAs(variable.GetCodeType()), templateCodeType)); previous = UserMember.Create(() => new item(variable.GetField("_M_prev").CastAs(variable.GetCodeType()), templateCodeType)); value = UserMember.Create(() => variable.GetField("_M_storage").GetField("_M_storage").CastAs(templateCodeType).CastAs <T>()); }
/// <summary> /// Initializes a new instance of the <see cref="GenericsElementCaster{T}"/> class. /// </summary> /// <param name="thisClass">The thisClass variable in generated UserType.</param> /// <param name="argumentNumber">The argument number in original user type.</param> public GenericsElementCaster(Variable thisClass, int argumentNumber) : this(thisClass.GetCodeType(), argumentNumber) { }
/// <summary> /// Does the full downcast, looks up the type based on virtual table and shifts variable address if multi-inheritance was involved. /// Difference from <see cref="VariableCastExtender.DowncastInterface(Variable)"/> is that this function returns downcasted .NET object /// if T contains <see cref="DerivedClassAttribute"/>. /// </summary> /// <typeparam name="T">The base user type which will be downcasted.</typeparam> /// <param name="userType">The user type.</param> /// <returns>Downcasted .NET object, but upcasted to the original user type.</returns> public static T DowncastObject <T>(this T userType) where T : UserType, ICastableObject { if (userType == null) { return(null); } Dictionary <string, DerivedClassAttribute> attributes = UserTypeDelegates <T> .Instance.DerivedClassAttributesDictionary; if (attributes.Count == 0) { throw new Exception(string.Format("Specified type {0} doesn't contain derived class attributes", typeof(T).Name)); } Variable variable = userType.DowncastInterface(); CodeType originalCodeType = variable.GetCodeType(); List <Tuple <CodeType, int> > types = new List <Tuple <CodeType, int> >(); if (originalCodeType.IsPointer) { originalCodeType = originalCodeType.ElementType; } types.Add(Tuple.Create(originalCodeType, 0)); while (types.Count > 0) { List <Tuple <CodeType, int> > newTypes = new List <Tuple <CodeType, int> >(); foreach (Tuple <CodeType, int> tuple in types) { int offset = tuple.Item2; CodeType codeType = tuple.Item1; DerivedClassAttribute attribute; if (attributes.TryGetValue(codeType.Name, out attribute)) { // Check if we don't have top level code type if (originalCodeType != codeType) { if (offset > 0) { variable = variable.AdjustPointer(offset); } variable = variable.CastAs(codeType); } UserType downcastedObject = (UserType)variable.CastAs(attribute.Type); return(AsUpcast <T>(downcastedObject, (int)(userType.GetPointerAddress() - variable.GetPointerAddress()))); } // Add base classes foreach (var t in codeType.InheritedClassesSorted) { newTypes.Add(Tuple.Create(t.Item1, offset + t.Item2)); } } // Continue with new types types = newTypes; } return(userType); }