private static unsafe bool TryGetNextInSOH(object current, Predicate <long> checker, out object nextObject) { nextObject = null; try { var offset = (int)EntityPtr.ToPointer(current); var size = SizeOf(current); offset += size; var mt = (long)*(IntPtr *)(offset + IntPtr.Size); if (size == 0 || !checker(mt)) { return(false); } //if ((long)*(IntPtr*)(offset + IntPtr.Size) == 0) return false; current = EntityPtr.ToInstance <object>((IntPtr)offset); nextObject = current; return(true); } catch { return(false); } }
/// <summary> /// Gets managed heap address (only last ephemeral segment) /// </summary> public static void GetManagedHeap(out IntPtr heapsOffset, out IntPtr lastHeapByte) { var offset = EntityPtr.ToPointer(new object()); var memoryBasicInformation = new WinApi.MEMORY_BASIC_INFORMATION(); unsafe { WinApi.VirtualQuery(offset, ref memoryBasicInformation, (IntPtr)Marshal.SizeOf(memoryBasicInformation)); heapsOffset = (IntPtr)memoryBasicInformation.AllocationBase; lastHeapByte = (IntPtr)((long)offset + (long)memoryBasicInformation.RegionSize); } }
static void Main(string[] args) { var obj = new object(); var list = new List <int>(100); var objPtr = EntityPtr.ToPointer(obj); Console.ReadKey(); AppDomainRunner.Go(objPtr); Console.WriteLine("Still alive: {0}", obj); Console.ReadKey(); }
public static void Main() { var startObj = new Box(); var _ = new Box(); var __ = new Box(); var ___ = new Box(); var endObject = new BetterBox(); foreach (var obj in SohUtil.GetObjectsInSoh(startObj, endObject, mt => mt != 0)) { Console.WriteLine(" - object adress: {0}, type: {1}, size: {2}", EntityPtr.ToPointer(obj.Item), obj.Item.GetType().Name, ClrUtil.SizeOf(obj.Item) ); } Console.ReadLine(); }
private static unsafe void SetMethodTable(object obj, MethodTableInfo *methodTable) { var contents = (EntityInfo *)EntityPtr.ToPointer(obj); contents->MethodTable = methodTable; }
private IntPtr CreateInstanceImpl(string typename) { return(EntityPtr.ToPointer(assembly.CreateInstance(typename))); }
public static unsafe int SizeOf(object obj) { var x = SizeOf((EntityInfo *)EntityPtr.ToPointer(obj)); return(x); }
/// <summary> /// Sets private GC object's field SyncBlockIndex, which is actually index in private GC table. /// </summary> /// <param name="obj">Object with SyncBlockIndex to be changed</param> /// <param name="syncBlockIndex">New value of SyncBlockIndex</param> public static unsafe void SetSyncBlockIndex(object obj, int syncBlockIndex) { var contents = (EntityInfo *)(EntityPtr.ToPointer(obj)); contents->SyncBlockIndex = syncBlockIndex; }
/// <summary> /// Gets private GC object's fields SyncBlockIndex and EEClass struct pointer /// </summary> public static unsafe int GetSyncBlockIndex(object obj) { var contents = (EntityInfo *)EntityPtr.ToPointer(obj); return(contents->SyncBlockIndex); }
public static unsafe EntityInfo *GetEntityInfo(object obj) { return((EntityInfo *)EntityPtr.ToPointer(obj)); }
private static unsafe void Main() { var objects = new Dictionary <Type, int>(7000); // Get current heap ranges IntPtr managedStart, managedEnd; Console.ReadKey(); MemAccessor.GetManagedHeap(out managedStart, out managedEnd); // for each byte in virtual memory block, we trying to find strings var stopwatch = Stopwatch.StartNew(); for (IntPtr *ptr = (IntPtr *)managedStart, end = (IntPtr *)managedEnd; ptr < end; ptr++) { if (IsCorrectMethodsTable(*ptr)) { // checking next object. int size; try { size = GCEx.SizeOf((EntityInfo *)(ptr - 1)) >> 2; } catch (OverflowException) { continue; } if (ptr + size > (long *)managedEnd) { continue; } { var found = EntityPtr.ToInstance <object>((IntPtr)(ptr - 1)); RegisterObject(objects, found); var lastInChain = found; foreach (var item in GCEx.GetObjectsInSOH(found, hmt => IsCorrectMethodsTable((IntPtr)hmt))) { RegisterObject(objects, item.Item); if (!item.IsArrayItem) { lastInChain = item.Item; } } long lastRecognized = (long)EntityPtr.ToPointer(lastInChain); ptr = (IntPtr *)(lastRecognized + lastInChain.SizeOf()); } } } var timeToTakeSnapshot = stopwatch.ElapsedMilliseconds; foreach (var type in objects.Keys.OrderByDescending(key => objects[key])) { Console.WriteLine("{0:00000} : {1}", objects[type], type.FullName); } Console.WriteLine("Objects total: {0}. Time taken: {1}", objects.Values.Sum(), timeToTakeSnapshot); Console.ReadKey(); }