예제 #1
0
        private bool GetArrayValue(ClrType type, ulong addr, int index, out object result)
        {
            var componentType = type.ArrayComponentType;

            // componentType being null is a dac bug which should only happen when we have an array of
            // value types, where we have never *actually* constructed one of the types.  If there are
            // other dac bugs which cause this, we unfortunately cannot work around it.
            if (addr == 0 || componentType == null)
            {
                result = new ClrNullValue(m_heap);
                return(true);
            }

            if (index < 0 || index >= m_len)
            {
                throw new IndexOutOfRangeException();
            }

            // Now construct the value based on the element type.
            if (componentType.ElementType == ClrElementType.Struct)
            {
                addr   = type.GetArrayElementAddress(addr, index);
                result = new ClrObject(m_heap, componentType, addr, true);
                return(true);
            }
            else if (componentType.IsObjectReference)
            {
                addr = type.GetArrayElementAddress(addr, index);
                if (!m_heap.GetRuntime().ReadPointer(addr, out addr) || addr == 0)
                {
                    result = new ClrNullValue(m_heap);
                    return(true);
                }
                else
                {
                    result = new ClrObject(m_heap, componentType, addr);
                    return(true);
                }
            }
            else if (componentType.IsPrimitive)
            {
                result = new ClrPrimitiveValue(type.GetArrayElementValue(addr, index), componentType.ElementType);
                return(true);
            }

            result = null;
            return(false);
        }
예제 #2
0
        public void ArrayOffsetsTest()
        {
            using (DataTarget dt = TestTargets.Types.LoadFullDump())
            {
                ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
                ClrHeap    heap    = runtime.Heap;

                ClrAppDomain domain = runtime.AppDomains.Single();

                ClrModule typesModule = runtime.GetModule("types.exe");
                ClrType   type        = heap.GetTypeByName("Types");

                ulong s_array = (ulong)type.GetStaticFieldByName("s_array").GetValue(domain);
                ulong s_one   = (ulong)type.GetStaticFieldByName("s_one").GetValue(domain);
                ulong s_two   = (ulong)type.GetStaticFieldByName("s_two").GetValue(domain);
                ulong s_three = (ulong)type.GetStaticFieldByName("s_three").GetValue(domain);

                ulong[] expected = new ulong[] { s_one, s_two, s_three };

                ClrType arrayType = heap.GetObjectType(s_array);

                for (int i = 0; i < expected.Length; i++)
                {
                    Assert.Equal(expected[i], (ulong)arrayType.GetArrayElementValue(s_array, i));

                    ulong address = arrayType.GetArrayElementAddress(s_array, i);
                    ulong value   = dt.DataReader.ReadPointerUnsafe(address);

                    Assert.NotEqual(0ul, address);
                    Assert.Equal(expected[i], value);
                }
            }
        }
예제 #3
0
파일: Program.cs 프로젝트: sunzu94/KeeThief
        public static KcpUserAccount GetKcpUserAccountInfo(ulong KcpUserAccountAddr, ClrType KcpUserAccountType, ClrHeap Heap, string databaseLocation)
        {
            KcpUserAccount UserAccountInfo = new KcpUserAccount();

            // Get the embedded ProtectedBinary
            ClrInstanceField KcpProtectedBinaryField   = KcpUserAccountType.GetFieldByName("m_pbKeyData");
            ulong            KcpProtectedBinaryAddr    = KcpProtectedBinaryField.GetAddress(KcpUserAccountAddr);
            ulong            KcpProtectedBinaryObjAddr = (ulong)KcpProtectedBinaryField.GetValue(KcpUserAccountAddr);

            ClrInstanceField EncDataField     = KcpProtectedBinaryField.Type.GetFieldByName("m_pbData");
            ulong            EncDataAddr      = EncDataField.GetAddress(KcpProtectedBinaryObjAddr);
            ulong            EncDataArrayAddr = (ulong)EncDataField.GetValue(KcpProtectedBinaryObjAddr);

            ClrType EncDataArrayType = Heap.GetObjectType(EncDataArrayAddr);
            int     len = EncDataField.Type.GetArrayLength(EncDataArrayAddr);

            if (len <= 0 || len % 16 != 0) // Small sanity check to make sure everything's ok
            {
                return(null);
            }

            byte[] EncData = new byte[len];
            for (int i = 0; i < len; i++)
            {
                EncData[i] = (byte)EncDataArrayType.GetArrayElementValue(EncDataArrayAddr, i);
            }

            UserAccountInfo.databaseLocation     = databaseLocation;
            UserAccountInfo.encryptedBlob        = EncData;
            UserAccountInfo.encryptedBlobAddress = (IntPtr)KcpUserAccountType.GetArrayElementAddress(EncDataArrayAddr, 0);
            UserAccountInfo.encryptedBlobLen     = len;

            return(UserAccountInfo);
        }
예제 #4
0
        static void ReadComplexArray(ClrType type, ulong obj)
        {
            int len = type.GetArrayLength(obj);

            Console.WriteLine("Object: {0:X}", obj);
            Console.WriteLine("Type:   {0}", type.Name);
            Console.WriteLine("Length: {0}", len);
            for (int i = 0; i < len; i++)
            {
                ulong addr = type.GetArrayElementAddress(obj, i);
                foreach (var field in type.ComponentType.Fields)
                {
                    string output;
                    if (field.HasSimpleValue)
                    {
                        var tmpOutput = field.GetValue(addr, true);
                        if (tmpOutput == null)
                        {
                            continue;
                        }
                        output = tmpOutput.ToString();        // <- true here, as this is an embedded struct
                    }
                    else
                    {
                        output = field.GetAddress(addr, true).ToString("X");   // <- true here as well
                    }

                    Console.WriteLine("{0}  +{1,2:X2} {2} {3} = {4}", i, field.Offset, field.Type.Name, field.Name, output);
                }
            }
        }
예제 #5
0
        public static List <KVP> GetKVPs(ClrType type, ulong items)
        {
            int length = type.GetArrayLength(items);
            var ret    = new List <KVP>();

            for (int i = 0; i < length; i++)
            {
                ulong addr = type.GetArrayElementAddress(items, i);

                var keyField = type.ComponentType.GetFieldByName("key");
                var key      = (ulong)keyField.GetValue(addr - (ulong)IntPtr.Size);

                // no need to add these pre-allocated entries
                if (key == 0)
                {
                    continue;
                }

                var valueField = type.ComponentType.GetFieldByName("value");
                var value      = (ulong)valueField.GetValue(addr - (ulong)IntPtr.Size);

                ret.Add(new KVP(key, value));
            }

            return(ret);
        }
예제 #6
0
        private ulong GetClrTypeArrayElementAddress(Tuple <int, ulong, int> input)
        {
            int     clrTypeId = input.Item1;
            ulong   address   = input.Item2;
            int     index     = input.Item3;
            ClrType clrType   = clrTypesCache[clrTypeId];

            return(clrType.GetArrayElementAddress(address, index));
        }
예제 #7
0
        public void InternalSetIndex(int[] indexes, object value)
        {
            Type    valueType = value.GetType();
            ClrType iobjType  = Type;
            nuint   addr      = iobjType.GetArrayElementAddress(BaseAddress, indexes);

            if (value is ClrObject obj)
            {
                Context.DataAccess.Write(addr, obj.Address);
            }
            else if (value is ClrValue val)
            {
                Context.DataAccess.WriteBytes(addr, Context.DataAccess.ReadBytes(val.Address, iobjType.ComponentSize));
            }
            else if (valueType.IsValueType)
            {
                Context.DataAccess.Write(addr, value);
            }
        }
        public List <T> Read <T>() where T : new()
        {
            ClrType type = Heap.GetObjectType(Value.Address);

            // Only consider types which are arrays that do not have simple values (I.E., are structs).
            if (!type.IsArray || type.ComponentType.HasSimpleValue)
            {
                return(null);
            }

            int len = type.GetArrayLength(Value.Address);

            List <T> list = new List <T>();

            FieldInfo[] fields = typeof(T).GetFields();

            for (int i = 0; i < len; i++)
            {
                ulong addr = type.GetArrayElementAddress(Value.Address, i);

                T item = new T();
                foreach (var field in type.ComponentType.Fields)
                {
                    if (!field.HasSimpleValue)
                    {
                        continue;
                    }

                    for (int j = 0; j < fields.Length; j++)
                    {
                        if (fields[j].Name == field.Name)
                        {
                            var val = field.GetValue(addr, true);
                            typeof(T).GetField(field.Name).SetValueDirect(__makeref(item), val);
                        }
                    }
                }
                list.Add(item);
            }

            return(list);
        }
예제 #9
0
        private List <ClrObjectModel> GetValues(ulong obj, ClrType type, string baseName, int offset, bool inner, List <ClrObjectModel> values)
        {
            if (type.Name == "System.String")
            {
                object value;
                try
                {
                    value = type.GetValue(obj);
                }
                catch (Exception ex)
                {
                    value = ex.Message;
                }
                values.Add(new ClrObjectModel {
                    Address = obj, BaseName = baseName, TypeName = type.Name, Value = value
                });
                values.AddRange(type.Fields.Select(field => new ClrObjectModel {
                    Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = field.GetValue(obj, inner).ToString()
                }));
            }
            else if (type.IsArray)
            {
                int len = type.GetArrayLength(obj);

                if (type.ComponentType == null)
                {
                    try
                    {
                        for (int i = 0; i < len; i++)
                        {
                            values.Add(new ClrObjectModel {
                                Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i)
                            });
                        }
                    }
                    catch { }
                }
                else if (type.ComponentType.HasSimpleValue)
                {
                    for (int i = 0; i < len; i++)
                    {
                        values.Add(new ClrObjectModel {
                            Address = obj, BaseName = baseName, TypeName = type.Name, Value = type.GetArrayElementValue(obj, i)
                        });
                    }
                }
                else
                {
                    for (int i = 0; i < len; i++)
                    {
                        ulong arrAddress = type.GetArrayElementAddress(obj, i);

                        foreach (var field in type.ComponentType.Fields)
                        {
                            string value;
                            if (field.HasSimpleValue)
                            {
                                value = field.GetValue(arrAddress, inner).ToString();   // an embedded struct
                            }
                            else
                            {
                                value = field.GetAddress(arrAddress, inner).ToString();
                            }

                            values.Add(new ClrObjectModel {
                                Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = value
                            });

                            if (field.ElementType == ClrElementType.Struct)
                            {
                                values.AddRange(GetValues(arrAddress, field.Type, baseName + field.Name, offset + field.Offset, true, new List <ClrObjectModel>()));
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (var field in type.Fields)
                {
                    ulong addr = field.GetAddress(obj, inner);

                    object value;
                    if (field.HasSimpleValue)
                    {
                        try
                        {
                            value = field.GetValue(obj, inner);
                        }
                        catch (Exception)
                        {
                            value = "{Unknown}";
                        }
                    }
                    else
                    {
                        value = addr;
                    }

                    string sValue = value?.ToString() ?? "{Null}";
                    values.Add(new ClrObjectModel {
                        Address = obj, BaseName = baseName, FieldName = field.Name, Offset = field.Offset + offset, TypeName = field.Type.Name, Value = sValue
                    });

                    if (field.ElementType == ClrElementType.Struct)
                    {
                        values.AddRange(GetValues(addr, field.Type, baseName + field.Name, offset + field.Offset, true, new List <ClrObjectModel>()));
                    }
                }
            }

            return(values);
        }
예제 #10
0
    public static void PrintDict(ClrRuntime runtime, string args)
    {
        bool  failed = false;
        ulong obj    = 0;

        try
        {
            obj    = Convert.ToUInt64(args, 16);
            failed = obj == 0;
        }
        catch (ArgumentException)
        {
            failed = true;
        }

        if (failed)
        {
            Console.WriteLine("Usage: !PrintDict <dictionary>");
            return;
        }

        ClrHeap heap = runtime.GetHeap();
        ClrType type = heap.GetObjectType(obj);

        if (type == null)
        {
            Console.WriteLine("Invalid object {0:X}", obj);
            return;
        }

        if (!type.Name.StartsWith("System.Collections.Generic.Dictionary"))
        {
            Console.WriteLine("Error: Expected object {0:X} to be a dictionary, instead it's of type '{1}'.");
            return;
        }

        // Get the entries field.
        ulong entries = type.GetFieldValue(obj, "entries");

        if (entries == 0)
        {
            return;
        }

        ClrType          entryArray     = heap.GetObjectType(entries);
        ClrType          arrayComponent = entryArray.ComponentType;
        ClrInstanceField hashCodeField  = arrayComponent.GetFieldByName("hashCode");
        ClrInstanceField keyField       = arrayComponent.GetFieldByName("key");
        ClrInstanceField valueField     = arrayComponent.GetFieldByName("value");

        Console.WriteLine("{0,8} {1,16} : {2}", "hash", "key", "value");
        int len = entryArray.GetArrayLength(entries);

        for (int i = 0; i < len; ++i)
        {
            ulong arrayElementAddr = entryArray.GetArrayElementAddress(entries, i);

            int    hashCode = (int)hashCodeField.GetValue(arrayElementAddr, true);
            object key      = keyField.GetValue(arrayElementAddr, true);
            object value    = valueField.GetValue(arrayElementAddr, true);

            key   = Format(heap, key);
            value = Format(heap, value);

            bool skip = key is ulong && (ulong)key == 0 && value is ulong && (ulong)value == 0;

            if (!skip)
            {
                Console.WriteLine("{0,8:X} {1,16} : {2}", hashCode, key, value);
            }
        }
    }
예제 #11
0
파일: Program.cs 프로젝트: stjeong/RefOwner
        private static Dictionary <string, HeapObjectCounter> GetObjectOwners(ClrRuntime runtime, HashSet <ulong> instances)
        {
            Dictionary <string, HeapObjectCounter> dict = new Dictionary <string, HeapObjectCounter>();

            if (!runtime.Heap.CanWalkHeap)
            {
                Console.WriteLine("Cannot walk the heap!");
            }
            else
            {
                foreach (ClrSegment seg in runtime.Heap.Segments)
                {
                    for (ulong obj = seg.FirstObject; obj != 0; obj = seg.NextObject(obj))
                    {
                        ClrType type = runtime.Heap.GetObjectType(obj);

                        if (type == null || type.IsFree == true)
                        {
                            continue;
                        }

                        string typeName = type.ToString();

                        int gen = runtime.Heap.GetGeneration(obj);
                        if (gen != 2)
                        {
                            continue;
                        }

                        if (type.IsArray == true)
                        {
                            int arrayLength = type.GetArrayLength(obj);
                            for (int i = 0; i < arrayLength; i++)
                            {
                                ulong elemAddress = type.GetArrayElementAddress(obj, i);

                                ClrType elemType = type.ComponentType;
                                if (elemType.IsValueClass == false)
                                {
                                    ulong elemRef = ReadMemory(runtime, elemAddress);
                                    if (instances.Contains(elemRef) == true)
                                    {
                                        if (dict.ContainsKey(typeName) == true)
                                        {
                                            dict[typeName].AddCount(obj);
                                        }
                                        else
                                        {
                                            dict.Add(typeName, new HeapObjectCounter(obj));
                                        }
                                    }
                                }
                                else
                                {
                                    AddItem(type, typeName, obj);
                                }
                            }
                        }
                        else
                        {
                            AddItem(type, typeName, obj);
                        }
                    }
                }
            }

            return(dict);

            void AddItem(ClrType type, string typeName, ulong objAddress)
            {
                foreach (ClrInstanceField field in type.Fields)
                {
                    ulong fieldAddress = GetFieldAddressValue(runtime, field, objAddress);

                    if (instances.Contains(fieldAddress) == true)
                    {
                        if (dict.ContainsKey(typeName) == true)
                        {
                            dict[typeName].AddCount(objAddress);
                        }
                        else
                        {
                            dict.Add(typeName, new HeapObjectCounter(objAddress));
                        }
                    }
                }
            }
        }
        public override IClrObjMappingModel ReadEntity(ClrObject obj, ModelMapperFactory factory)
        {
            var hashtableModel = new HashtableMappingModel
            {
                Obj = obj
            };

            ClrObject entriesField = obj.GetRefFld(entriesFldName);

            if (entriesField == null || entriesField.Type == null)
            {
                // Object contains this field, but value is null.
                // Most likely dictionary is either in the middle of construction, or destruction.
                // Anyway we can assume it is empty.
                return(hashtableModel);
            }

            ClrType type = entriesField.Type;

            ClrHeap heap = type.Heap;

            var componentType = type.ComponentType;

            if (componentType == null)
            {
                // TODO :Try reload type.
                return(null);
            }

            ClrInstanceField valueField = componentType.GetFieldByName("value");

            ClrInstanceField keyField = componentType.GetFieldByName("key");

            int len = type.GetArrayLength(entriesField.Address);

            ulong entriesFieldAddress = entriesField.Address;

            for (int i = 0; i < len; i++)
            {
                ulong addr = type.GetArrayElementAddress(entriesFieldAddress, i);

                if (addr == 0)
                {
                    continue;
                }
                try
                {
                    var key = keyField.GetValue(addr, true);
                    if (!(key is ulong))
                    {
                        continue;
                    }
                    var keyPointer = (ulong)key;
                    if (keyPointer == 0)
                    {
                        continue;
                    }

                    var val = valueField.GetValue(addr, true);

                    ulong valuePointer;
                    if (val is ulong)
                    {
                        valuePointer = (ulong)val;
                    }
                    else
                    {
                        valuePointer = 0;
                    }

                    var keyObj = new ClrObject(keyPointer, heap);
                    var valObj = new ClrObject(valuePointer, heap);

                    hashtableModel.Elements.Add(factory.BuildModel(keyObj),
                                                factory.BuildModel(valObj));
                }
                catch (Exception)
                {
                    Trace.TraceError("Count not read {0} object", obj.HexAddress);

                    // Do nothing for now
                }
            }

            return(hashtableModel);
        }
예제 #13
0
 /// <summary>
 ///     Returns the absolute address to the given array element.  You may then make a direct memory read out
 ///     of the process to get the value if you want.
 /// </summary>
 /// <param name="objRef">The object reference.</param>
 /// <param name="index">The index.</param>
 /// <returns>System.UInt64.</returns>
 public ulong GetArrayElementAddress(ulong objRef, int index) => ClrType.GetArrayElementAddress(objRef, index);
예제 #14
0
 public void GetArrayElementAddress(ulong objRef, int index, out ulong pAddr)
 {
     pAddr = m_type.GetArrayElementAddress(objRef, index);
 }