Beispiel #1
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);
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        private DesktopBlockingObject CreateRWSObject(ulong obj, ClrType type)
        {
            if (type == null)
            {
                return(new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None));
            }

            ClrInstanceField field = type.GetFieldByName("writeLockOwnerId");

            if (field != null && field.ElementType == ClrElementType.Int32)
            {
                int       id     = (int)field.GetValue(obj);
                ClrThread thread = GetThreadById(id);
                if (thread != null)
                {
                    return(new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.WriterAcquired));
                }
            }

            field = type.GetFieldByName("upgradeLockOwnerId");
            if (field != null && field.ElementType == ClrElementType.Int32)
            {
                int       id     = (int)field.GetValue(obj);
                ClrThread thread = GetThreadById(id);
                if (thread != null)
                {
                    return(new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.WriterAcquired));
                }
            }

            field = type.GetFieldByName("rwc");
            if (field != null)
            {
                List <ClrThread> threads      = null;
                ulong            rwc          = (ulong)field.GetValue(obj);
                ClrType          rwcArrayType = _heap.GetObjectType(rwc);
                if (rwcArrayType != null && rwcArrayType.IsArray && rwcArrayType.ComponentType != null)
                {
                    ClrType          rwcType  = rwcArrayType.ComponentType;
                    ClrInstanceField threadId = rwcType.GetFieldByName("threadid");
                    ClrInstanceField next     = rwcType.GetFieldByName("next");
                    if (threadId != null && next != null)
                    {
                        int count = rwcArrayType.GetArrayLength(rwc);
                        for (int i = 0; i < count; ++i)
                        {
                            ulong entry = (ulong)rwcArrayType.GetArrayElementValue(rwc, i);
                            GetThreadEntry(ref threads, threadId, next, entry, false);
                        }
                    }
                }

                if (threads != null)
                {
                    return(new DesktopBlockingObject(obj, true, 0, BlockingReason.ReaderAcquired, threads.ToArray()));
                }
            }

            return(new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None));
        }
Beispiel #4
0
        public void GetArrayElementValue(ulong objRef, int index, out IMDValue ppValue)
        {
            object         value       = m_type.GetArrayElementValue(objRef, index);
            ClrElementType elementType = m_type.ArrayComponentType != null ? m_type.ArrayComponentType.ElementType : ClrElementType.Unknown;

            ppValue = new MDValue(value, elementType);
        }
Beispiel #5
0
        private static void PrintArray(ClrRuntime runtime)

        {
            var heap = runtime.Heap;

            var intArrays = from o in heap.EnumerateObjects()
                            let t = heap.GetObjectType(o)
                                    where t.IsArray && t.Name == "System.Int32[]"
                                    select new { Address = o, Type = t };

            foreach (var item in intArrays)
            {
                ClrType type = item.Type;
                ulong   obj  = item.Address;

                int len = type.GetArrayLength(obj);

                Console.WriteLine("Object: {0:X}", obj);
                Console.WriteLine("Length: {0}", len);
                Console.WriteLine("Elements:");

                for (int i = 0; i < len; i++)
                {
                    Console.WriteLine("{0,3} - {1}", i, type.GetArrayElementValue(obj, i));
                }
            }
        }
Beispiel #6
0
        public IClrObject ReadFromArrayIndex(ClrType arrayType, ulong baseAddress, int index)
        {
            if (arrayType.ComponentType.IsPrimitive || arrayType.ComponentType.IsString)
            {
                var value = arrayType.GetArrayElementValue(baseAddress, index);
                return(WrapPrimitiveValue(arrayType.ComponentType, value));
            }
            var address = (ulong)arrayType.GetArrayElementValue(baseAddress, index);

            if (address == 0)
            {
                return(null);
            }
            var actualType = arrayType.Heap.GetObjectType(address);

            return(ReadFromAddress(actualType, address));
        }
Beispiel #7
0
        static void ReadSimpleArray(ClrType type, ulong obj)
        {
            int len = type.GetArrayLength(obj);

            Console.WriteLine("Object: {0:X}", obj);
            Console.WriteLine("Length: {0}", len);
            Console.WriteLine("Elements:");

            for (int i = 0; i < len; i++)
            {
                Console.WriteLine("{0,3} - {1}", i, type.GetArrayElementValue(obj, i));
            }
        }
Beispiel #8
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);
        }
Beispiel #9
0
        public static List <ulong> GetArrayItems(ClrType type, ulong items)
        {
            int length = type.GetArrayLength(items);
            var ret    = new List <ulong>();

            for (int i = 0; i < length; i++)
            {
                var val = (ulong)type.GetArrayElementValue(items, i);

                if (val != 0)
                {
                    ret.Add(val);
                }
            }

            return(ret);
        }
Beispiel #10
0
        public void ForEach(ulong arrayAddress, Action <ulong> action)
        {
            ClrType type   = ManagedHeap.GetObjectType(arrayAddress);
            int     length = type.GetArrayLength(arrayAddress);

            for (int element = 0; element < length; element++)
            {
                var   val            = type.GetArrayElementValue(arrayAddress, element);
                ulong elementAddress = (ulong)val;
                if (elementAddress == 0)
                {
                    continue;
                }

                action(elementAddress);
            }
        }
Beispiel #11
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);
        }
Beispiel #12
0
        private IEnumerable <ulong> EnumerateManagedThreadpoolObjects()
        {
            _heap = _runtime.GetHeap();

            ClrModule mscorlib = GetMscorlib();

            if (mscorlib != null)
            {
                ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals");
                if (queueType != null)
                {
                    ClrStaticField workQueueField = queueType.GetStaticFieldByName("workQueue");
                    if (workQueueField != null)
                    {
                        foreach (var appDomain in _runtime.AppDomains)
                        {
                            object  workQueueValue = workQueueField.GetValue(appDomain);
                            ulong   workQueue      = workQueueValue == null ? 0L : (ulong)workQueueValue;
                            ClrType workQueueType  = _heap.GetObjectType(workQueue);

                            if (workQueue == 0 || workQueueType == null)
                            {
                                continue;
                            }

                            ulong   queueHead;
                            ClrType queueHeadType;
                            do
                            {
                                if (!GetFieldObject(workQueueType, workQueue, "queueHead", out queueHeadType, out queueHead))
                                {
                                    break;
                                }

                                ulong   nodes;
                                ClrType nodesType;
                                if (GetFieldObject(queueHeadType, queueHead, "nodes", out nodesType, out nodes) && nodesType.IsArray)
                                {
                                    int len = nodesType.GetArrayLength(nodes);
                                    for (int i = 0; i < len; ++i)
                                    {
                                        ulong addr = (ulong)nodesType.GetArrayElementValue(nodes, i);
                                        if (addr != 0)
                                        {
                                            yield return(addr);
                                        }
                                    }
                                }

                                if (!GetFieldObject(queueHeadType, queueHead, "Next", out queueHeadType, out queueHead))
                                {
                                    break;
                                }
                            } while (queueHead != 0);
                        }
                    }
                }


                queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolWorkQueue");
                if (queueType != null)
                {
                    ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues");
                    if (threadQueuesField != null)
                    {
                        foreach (ClrAppDomain domain in _runtime.AppDomains)
                        {
                            ulong?threadQueue = (ulong?)threadQueuesField.GetValue(domain);
                            if (!threadQueue.HasValue || threadQueue.Value == 0)
                            {
                                continue;
                            }

                            ClrType threadQueueType = _heap.GetObjectType(threadQueue.Value);
                            if (threadQueueType == null)
                            {
                                continue;
                            }

                            ulong   outerArray     = 0;
                            ClrType outerArrayType = null;
                            if (!GetFieldObject(threadQueueType, threadQueue.Value, "m_array", out outerArrayType, out outerArray) || !outerArrayType.IsArray)
                            {
                                continue;
                            }

                            int outerLen = outerArrayType.GetArrayLength(outerArray);
                            for (int i = 0; i < outerLen; ++i)
                            {
                                ulong entry = (ulong)outerArrayType.GetArrayElementValue(outerArray, i);
                                if (entry == 0)
                                {
                                    continue;
                                }

                                ClrType entryType = _heap.GetObjectType(entry);
                                if (entryType == null)
                                {
                                    continue;
                                }

                                ulong   array;
                                ClrType arrayType;
                                if (!GetFieldObject(entryType, entry, "m_array", out arrayType, out array) || !arrayType.IsArray)
                                {
                                    continue;
                                }

                                int len = arrayType.GetArrayLength(array);
                                for (int j = 0; j < len; ++j)
                                {
                                    ulong addr = (ulong)arrayType.GetArrayElementValue(array, i);
                                    if (addr != 0)
                                    {
                                        yield return(addr);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #13
0
 /// <summary>
 ///     Returns the array element value at the given index.  Returns 'null' if the array element is of type
 ///     VALUE_CLASS.
 /// </summary>
 /// <param name="objRef">The object reference.</param>
 /// <param name="index">The index.</param>
 /// <returns>System.Object.</returns>
 public object GetArrayElementValue(ulong objRef, int index) => ClrType.GetArrayElementValue(objRef, index);