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); } } }
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); }
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)); }
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); }
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)); } } }
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)); }
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)); } }
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); }
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); }
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); } }
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); }
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); } } } } } } } }
/// <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);