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 static ulong GetLastObjectInHierarchy(ClrHeap heap, ulong heapobject, string[] hierarchy, int currentIndex) { ClrType type = heap.GetObjectType(heapobject); ClrInstanceField field = type.GetFieldByName(hierarchy[currentIndex]); if (field == null) { Console.WriteLine($"ERROR: type '{type.Name}' does not have a field '{hierarchy[currentIndex]}'"); return(0L); } ulong fieldValue = (ulong)field.GetValue(heapobject, false, false); if (fieldValue == 0) { Console.WriteLine($"ERROR: the field value for '{hierarchy[currentIndex]}' was null on type '{type.Name}' "); return(0L); } currentIndex++; if (currentIndex == hierarchy.Length) { return(fieldValue); } return(GetLastObjectInHierarchy(heap, fieldValue, hierarchy, currentIndex)); }
public static object GetFieldValue(ClrHeap heap, ulong address, string fieldName) { var type = heap.GetObjectType(address); ClrInstanceField field = type.GetFieldByName(fieldName); return(field?.GetValue(address)); }
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 static ulong GetTaskStateFromAddress(ulong address) { var type = Runtime.Heap.GetObjectType(address); if ((type != null) && (type.Name.StartsWith("System.Threading.Task"))) { // try to get the m_stateFlags field value ClrInstanceField field = type.GetFieldByName("m_stateFlags"); if (field != null) { var val = field.GetValue(address); if (val != null) { try { return((ulong)(int)val); } catch (InvalidCastException) { } } } } return(0); }
public override ClrType GetRuntimeType(ulong obj) { if (!IsRuntimeType) { return(null); } ClrInstanceField field = GetFieldByName("m_handle"); if (field == null) { return(null); } ulong methodTable = 0; if (field.ElementType == ClrElementType.NativeInt) { methodTable = (ulong)(long)field.GetValue(obj); } else if (field.ElementType == ClrElementType.Struct) { ClrInstanceField ptrField = field.Type.GetFieldByName("m_ptr"); methodTable = (ulong)(long)ptrField.GetValue(field.GetAddress(obj, false), true); } return(DesktopHeap.GetTypeByMethodTable(methodTable, 0, obj)); }
private Dictionary <int, string> GetManagedThreadNames(ClrHeap heap) { var result = new Dictionary <int, string>(); if (heap == null || !heap.CanWalkHeap) { return(result); } var threadObjects = from obj in heap.EnumerateObjectAddresses() let type = heap.GetObjectType(obj) where type != null && type.Name == "System.Threading.Thread" select obj; ClrType threadType = heap.GetTypeByName("System.Threading.Thread"); ClrInstanceField nameField = threadType.GetFieldByName("m_Name"); ClrInstanceField managedIdField = threadType.GetFieldByName("m_ManagedThreadId"); foreach (var threadObject in threadObjects) { string name = (string)nameField.GetValue(threadObject); int id = (int)managedIdField.GetValue(threadObject); result[id] = name; } return(result); }
private void GetThreadEntry(ref List <ClrThread> threads, ClrInstanceField threadId, ClrInstanceField next, ulong curr, bool interior) { if (curr == 0) { return; } int id = (int)threadId.GetValue(curr, interior); ClrThread thread = GetThreadById(id); if (thread != null) { if (threads == null) { threads = new List <ClrThread>(); } threads.Add(thread); } curr = (ulong)next.GetValue(curr, interior); if (curr != 0) { GetThreadEntry(ref threads, threadId, next, curr, false); } }
public static string GetDisplayValue(this ClrInstanceField self, ClrObject clrObject) { if (self.IsObjectReference) { var obj = clrObject.GetObjectField(self.Name); if (obj.IsNull) { return("null"); } return($"0x{obj.Address:X} [{obj.Type.Name}:0x{obj.Type.MethodTable:X}]"); } else if (self.HasSimpleValue) { return(self.GetValue(clrObject.Address).ToString()); } else if (self.IsValueClass) { var vt = clrObject.GetValueClassField(self.Name); return($"0x{vt.Address:X} [struct {vt.Type.Name}:0x{vt.Type.MethodTable:X}]"); } else { return("<unknown value>"); } }
private bool FindThread(ulong start, ulong stop, out ulong threadAddr, out ClrThread target) { ClrHeap heap = _runtime.Heap; foreach (ulong obj in EnumerateObjectsOfType(start, stop, "System.Threading.Thread")) { ClrType type = heap.GetObjectType(obj); ClrInstanceField threadIdField = type.GetFieldByName("m_ManagedThreadId"); if (threadIdField != null && threadIdField.ElementType == ClrElementType.Int32) { int id = (int)threadIdField.GetValue(obj); ClrThread thread = GetThreadById(id); if (thread != null) { threadAddr = obj; target = thread; return(true); } } } threadAddr = 0; target = null; return(false); }
public static TimeSpan Read(ClrObject obj) { ClrInstanceField dateDataField = obj.Type.GetFieldByName("_ticks"); var rawDateTimeData = (long)dateDataField.GetValue(obj.Address, true); var ts = new TimeSpan(rawDateTimeData); return(ts); }
public static T GetObjectAs <T>(ClrHeap heap, ulong heapobject, string fieldName) { ClrType type = heap.GetObjectType(heapobject); ClrInstanceField field = type.GetFieldByName(fieldName); T fieldValue = (T)field.GetValue(heapobject); return(fieldValue); }
private DesktopBlockingObject CreateRWLObject(ulong obj, ClrType type) { if (type == null) { return(new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None)); } ClrInstanceField writerID = type.GetFieldByName("_dwWriterID"); if (writerID != null && writerID.ElementType == ClrElementType.Int32) { int id = (int)writerID.GetValue(obj); if (id > 0) { ClrThread thread = GetThreadById(id); if (thread != null) { return(new DesktopBlockingObject(obj, true, 0, thread, BlockingReason.ReaderAcquired)); } } } ClrInstanceField uLock = type.GetFieldByName("_dwULockID"); ClrInstanceField lLock = type.GetFieldByName("_dwLLockID"); if (uLock != null && uLock.ElementType == ClrElementType.Int32 && lLock != null && lLock.ElementType == ClrElementType.Int32) { int uId = (int)uLock.GetValue(obj); int lId = (int)lLock.GetValue(obj); List <ClrThread> threads = null; foreach (ClrThread thread in _runtime.Threads) { foreach (IRWLockData l in _runtime.EnumerateLockData(thread.Address)) { if (l.LLockID == lId && l.ULockID == uId && l.Level > 0) { if (threads == null) { threads = new List <ClrThread>(); } threads.Add(thread); break; } } } if (threads != null) { return(new DesktopBlockingObject(obj, true, 0, BlockingReason.ReaderAcquired, threads.ToArray())); } } return(new DesktopBlockingObject(obj, false, 0, null, BlockingReason.None)); }
public object GetFieldValue(ulong address, string fieldName) { var type = ManagedHeap.GetObjectType(address); ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) { return(null); } return(field.GetValue(address)); }
private object GetFieldValue(ClrHeap heap, ulong address, string fieldName) { var type = heap.GetObjectType(address); ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) { return(null); } return(field.GetValue(address)); }
public IClrObject ReadFromFieldValue(ClrInstanceField field, ulong address, bool ownerIsNested = false) { if (field.Type.IsValueClass) { throw new ArgumentException("Cannot read ClrValue from field value. Handle this case in the caller."); } if (field.Type.IsPrimitive || field.Type.IsString) { var value = field.GetValue(address, ownerIsNested); return(WrapPrimitiveValue(field.Type, value)); } var instanceAddress = (ulong)field.GetValue(address, ownerIsNested); if (instanceAddress == 0) { return(null); } var actualType = field.Type.Heap.GetObjectType(instanceAddress); return(ReadFromNotNullAddress(actualType, instanceAddress)); }
public static ulong GetLastObjectInHierarchy(ClrHeap heap, ulong heapobject, string[] hierarchy, int currentIndex) { ClrType type = heap.GetObjectType(heapobject); ClrInstanceField field = type.GetFieldByName(hierarchy[currentIndex]); ulong fieldValue = (ulong)field.GetValue(heapobject, false, false); currentIndex++; if (currentIndex == hierarchy.Length) { return(fieldValue); } return(GetLastObjectInHierarchy(heap, fieldValue, hierarchy, currentIndex)); }
static void ReadExceptionHResult(ClrType type, ulong obj) { ClrInstanceField field = type.GetFieldByName("_HResult"); Debug.Assert(field.ElementType == ClrElementType.Int32); int value = (int)field.GetValue(obj); Console.WriteLine(" Exception 0x{0:X} hresult: 0x{1:X}", obj, value); // get value detail var output = GetOutput(obj, field); Console.WriteLine(" " + output); }
public ClrInstanceField TestFieldNameAndValue <T>(ClrType type, ulong obj, string name, T value) { ClrInstanceField field = type.GetFieldByName(name); Assert.NotNull(field); Assert.Equal(name, field.Name); object v = field.GetValue(obj); Assert.NotNull(v); Assert.IsType <T>(v); Assert.Equal(value, (T)v); return(field); }
private bool GetFieldObject(ClrType type, ulong obj, string fieldName, out ClrType valueType, out ulong value) { value = 0; valueType = null; ClrInstanceField field = type.GetFieldByName(fieldName); if (field == null) return false; value = (ulong)field.GetValue(obj); if (value == 0) return false; valueType = _heap.GetObjectType(value); return valueType != null; }
private static bool ExtractRefObject(Pair p, ClrInstanceField field, ClrObject obj, out object reff) { reff = null; var reference = obj.GetObjectField(field.Name); if (reference.IsNull) { return(true); } if (reference.Type.IsString) { var value = GetStringContents(reference); reff = value; return(true); } if (reference.Type.IsPrimitive) { reff = field.GetValue(obj.Address); return(true); } if (Pair.Cache.TryGetValue(reference.Address, out reff)) { return(true); } Type type = null; if (!GetType(p, reference.Type, out type)) { return(false); } var par = Export(Yield(reference), type).Single(); reff = par.RuntimeObject; p.Warnings.AddRange(par.Warnings); p.Errors.AddRange(par.Errors); return(true); }
/// <summary> /// Reads date from <see cref="ClrObject" /> which points on <see cref="DateTime" />. /// </summary> /// <param name="obj">The object.</param> /// <returns></returns> public static DateTime FromObjToDate(ClrObject obj) { ClrAssert.ObjectNotNullTypeNotEmpty(obj); DateTime result; if (obj.Type.Name != typeof(DateTime).FullName) { result = DateTime.MinValue; } else { ClrInstanceField dateDataField = obj.Type.GetFieldByName("dateData"); var rawDateTimeData = (ulong)dateDataField.GetValue(obj.Address, true); result = TicksToDt(rawDateTimeData); } return(result); }
static (int length, string text) ReadString(ClrType type, ulong obj) { ClrInstanceField lengthField = type.GetFieldByName("_stringLength"); if (lengthField == null) { return(0, String.Empty); } var stringLength = (int)lengthField.GetValue(obj); if (stringLength <= 0) { return(stringLength, String.Empty); } var text = (string)type.GetValue(obj); return(stringLength, text); }
private bool GetStackTraceFromField(ClrType type, ulong obj, out ulong stackTrace) { stackTrace = 0; ClrInstanceField field = type.GetFieldByName("_stackTrace"); if (field == null) { return(false); } object tmp = field.GetValue(obj); if (tmp == null || !(tmp is ulong)) { return(false); } stackTrace = (ulong)tmp; return(true); }
private static KeyValuePair <ClrInstanceField, string> GetField(string fieldName, string typeName, ClrHeap Heap) { //helper function to get an instance field if (!Heap.CanWalkHeap) { return(new KeyValuePair <ClrInstanceField, string>(null, "[!] Unable to walk the heap")); } Console.WriteLine("[+] Walking the heap...."); foreach (ulong obj in Heap.EnumerateObjectAddresses()) { ClrType type = Heap.GetObjectType(obj); if (type == null || type.Name != typeName) { continue; } try { ClrInstanceField field = type.GetFieldByName(fieldName); #if DEBUG Console.WriteLine("[+] Found desired field: " + fieldName); #endif ulong a = field.GetAddress(obj); if (field.HasSimpleValue) { fieldValue = field.GetValue(obj); } fieldAddr = new IntPtr(long.Parse(a.ToString())); return(new KeyValuePair <ClrInstanceField, string>(field, "[+] Found field " + fieldName)); } catch (Exception e) { return(new KeyValuePair <ClrInstanceField, string>(null, e.ToString())); } } return(new KeyValuePair <ClrInstanceField, string>(null, "Unable to locate field: " + fieldName)); }
static void Main(string[] args) { int pid = 1234; DataTarget dt = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive); using (dt) { //pick first CLR version ClrInfo runtimeInfo = dt.ClrVersions[0]; ClrRuntime runtime = runtimeInfo.CreateRuntime(); ClrType type; //enumerate objects on managed heap foreach (ulong obj in runtime.Heap.EnumerateObjectAddresses()) { type = runtime.Heap.GetObjectType(obj); if (type == null) { continue; } if (type.Name == "MyProject.MyClass") { Console.WriteLine("Address 0x{0:X}: {1}", obj, type.Name); ClrInstanceField f = type.GetFieldByName("Foo"); object val = f.GetValue(obj); if (val != null) { Console.WriteLine(val.ToString()); } } } } Console.ReadKey(); }
protected string?BuildMethodNameFromDelegate(ulong action, ulong task = 0) { string?r = "[no action]"; if (action != 0) { var target = (ulong)fieldDelegateTarget.GetValue(action); if (target == 0) { r = "[no target]"; } else { r = BuildDelegateMethodName(heap.GetObjectType(target), action); if (r == "System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run") { var fieldStateMachine = heap.GetObjectType(target).GetFieldByName("m_stateMachine"); var stateMachine = (ulong)fieldStateMachine.GetValue(target); var typeStateMachine = heap.GetObjectType(stateMachine); r = typeStateMachine.Name; } else if (task != 0) { // get the task scheduler if any var scheduler = (ulong)fieldTaskScheduler.GetValue(task); if (scheduler != 0) { var schedulerTypeName = heap.GetObjectType(scheduler).ToString(); if (schedulerTypeName != "System.Threading.Tasks.ThreadPoolTaskScheduler") { r = $"{r} [{schedulerTypeName}]"; } } } } } return(r); }
public override IEnumerable <ObjectInfo> EnumerateTimerTasks() { if (fieldSQueue.IsInitialized(domain)) { var timeQueue = (ulong)fieldSQueue.GetValue(domain); for (ulong timer = (ulong)fieldTimers.GetValue(timeQueue); timer != 0; timer = (ulong)fieldNext.GetValue(timer)) { var state = (ulong)fieldState.GetValue(timer); if (state != 0) { var typeState = heap.GetObjectType(state); if (typeState == typeDelayPromise) { var continuation = (ulong)fieldTaskContinuationObject.GetValue(state); var target = (ulong)fieldDelegateTarget.GetValue(continuation); var stateMachine = (ulong)fieldStateMachine.GetValue(target); yield return(new ObjectInfo { Address = stateMachine, Type = heap.GetObjectType(stateMachine) }); } } } } }
internal static ClrFieldValue?Create(ClrInstanceField typeField, ClrInstance instance, bool interior) { if (typeField.Type.MetadataToken == 0 && typeField.Type.Name == "ERROR") { return(null); // TODO: not sure about this! //throw new NotSupportedException(); } Contract.AssertNotNull(instance.ObjectAddress); object?value = null; try { // This code could fail with NRE with no obvious reason. value = typeField.GetValue(instance.ObjectAddress.Value, interior); } catch (Exception) { } var type = typeField.Type; if (!type.IsIntrinsic() && value != null) { // instance.Heap.GetObjectType may return null. WHY? type = instance.Heap.GetObjectType((ulong)value) ?? type; } if (value == null) { value = instance.ObjectAddress.Value + (ulong)typeField.Offset; } return(new ClrFieldValue(typeField, new ClrInstance(instance.Heap, value, type, interior))); }
static string GetOutput(ulong obj, ClrInstanceField field) { // If we don't have a simple value, return the address of the field in hex. if (!field.HasSimpleValue) { return(field.GetAddress(obj).ToString("X")); } object value = field.GetValue(obj); if (value == null) { return("{error}"); // Memory corruption in the target process. } // Decide how to format the string based on the underlying type of the field. switch (field.ElementType) { case ClrElementType.String: // In this case, value is the actual string itself. return((string)value); case ClrElementType.Array: case ClrElementType.SZArray: case ClrElementType.Object: case ClrElementType.Class: case ClrElementType.FunctionPointer: case ClrElementType.NativeInt: case ClrElementType.NativeUInt: // These types are pointers. Print as hex. return(string.Format("{0:X}", value)); default: // Everything else will look fine by simply calling ToString. return(value.ToString()); } }
private void GetThreadEntry(ref List<ClrThread> threads, ClrInstanceField threadId, ClrInstanceField next, ulong curr, bool interior) { if (curr == 0) return; int id = (int)threadId.GetValue(curr, interior); ClrThread thread = GetThreadById(id); if (thread != null) { if (threads == null) threads = new List<ClrThread>(); threads.Add(thread); } curr = (ulong)next.GetValue(curr, interior); if (curr != 0) GetThreadEntry(ref threads, threadId, next, curr, false); }