예제 #1
0
파일: Program.cs 프로젝트: ypog07/dotnetex
 private void methodInsideAppDomain(IntPtr startingIntPtr)
 {
     foreach (var obj in GCEx.GetObjectsInSOH(EntityPtr.ToInstance <object>(startingIntPtr), mt => mt != 0))
     {
         Console.WriteLine(" - object: {0}, type: {1}, size: {2}", obj.Item, obj.Item.GetType().Name, GCEx.SizeOf(obj.Item));
     }
 }
예제 #2
0
        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);
            }
        }
예제 #3
0
        /// <summary>
        /// Allocates memory in unmanaged memory area and fills it
        /// with MethodTable pointer to initialize managed class instance
        /// </summary>
        /// <returns></returns>
        public static T AllocInUnmanaged <T>() where T : new()
        {
            var pointer = Marshal.AllocHGlobal(SizeOf <T>());
            var obj     = EntityPtr.ToInstance <T>(pointer);

            obj.SetType <T>();
            return(obj);
        }
예제 #4
0
        /// <summary>
        /// Enumerates all strings in heap
        /// </summary>
        /// <param name="heapsOffset">Heap starting point</param>
        /// <param name="lastHeapByte">Heap last byte</param>
        private static void EnumerateStrings(IntPtr heapsOffset, IntPtr lastHeapByte)
        {
            var count = 0;

            for (long pointer = heapsOffset.ToInt64(), end = lastHeapByte.ToInt64(); pointer < end; pointer++)
            {
                if (IsString(pointer))
                {
                    var str = EntityPtr.ToInstance <string>(new IntPtr(pointer));
                    Console.WriteLine(str);
                    count++;
                }
            }

            Console.WriteLine("Total count: {0}", count);
        }
예제 #5
0
        public static void Main()
        {
            unsafe
            {
                var data = stackalloc int[10];

                var person = EntityPtr.ToInstance <Person>((IntPtr)data);
                SetType <Person>(person);

                data[3] = 10;
                Console.WriteLine(
                    $"{person.X}, {person.Y}, \n Type: {person.GetType()} \n IsValueType: {person.GetType().IsValueType}");

                data[3] = 20;
                Console.WriteLine($"{person.X}, {person.Y}");

                Console.ReadLine();
            }
        }
예제 #6
0
        public unsafe UnmanagedHeap(int capacity)
        {
            _freeSize = capacity;

            // Getting type size and total pool size
            var objectSize = GCEx.SizeOf <TPoolItem>();

            _capacity  = capacity;
            _totalSize = objectSize * capacity + capacity * IntPtr.Size * 2;

            _startingPointer = Marshal.AllocHGlobal(_totalSize).ToPointer();
            var mTable = (MethodTableInfo *)typeof(TPoolItem).TypeHandle.Value.ToInt32();

            _freeObjects     = (IntPtr *)_startingPointer;
            _allObjects      = (IntPtr *)((long)_startingPointer + IntPtr.Size * capacity);
            _startingPointer = (void *)((long)_startingPointer + 2 * IntPtr.Size * capacity);

            var pFake = typeof(Stub).GetMethod("Construct", BindingFlags.Static | BindingFlags.Public);
            var pCtor = _ctor = typeof(TPoolItem).GetConstructor(new [] { typeof(int) });

            MethodUtil.ReplaceMethod(pCtor, pFake, skip: true);

            for (int i = 0; i < capacity; i++)
            {
                var handler = (IntPtr *)((long)_startingPointer + (objectSize * i));
                handler[1] = (IntPtr)mTable;
                var obj = EntityPtr.ToInstance <object>((IntPtr)handler);

                var reference = (TPoolItem)obj;
                reference.heap = this;

                _allObjects[i] = (IntPtr)(handler + 1);
            }

            Reset();
        }
예제 #7
0
        public int SizeOf()
        {
            var total = 0;
            int elementsize;

            fixed(EntityInfo *entity = &BasicInfo)
            {
                var arr         = EntityPtr.ToInstance <Array>(new IntPtr(entity));
                var elementType = arr.GetType().GetElementType();

                if (elementType.IsValueType)
                {
                    var typecode = Type.GetTypeCode(elementType);

                    switch (typecode)
                    {
                    case TypeCode.Byte:
                    case TypeCode.SByte:
                    case TypeCode.Boolean:
                        elementsize = 1;
                        break;

                    case TypeCode.Int16:
                    case TypeCode.UInt16:
                    case TypeCode.Char:
                        elementsize = 2;
                        break;

                    case TypeCode.Int32:
                    case TypeCode.UInt32:
                    case TypeCode.Single:
                        elementsize = 4;
                        break;

                    case TypeCode.Int64:
                    case TypeCode.UInt64:
                    case TypeCode.Double:
                        elementsize = 8;
                        break;

                    case TypeCode.Decimal:
                        elementsize = 12;
                        break;

                    default:
                        var info = (MethodTableInfo *)elementType.TypeHandle.Value;
                        elementsize = info->Size - sizeof(EntityInfo);
                        break;
                    }
                }
                else
                {
                    elementsize = IntPtr.Size;
                }

                // Header
                total += sizeof(EntityInfo);
                total += elementType.IsValueType ? 0 : 4; // MethodsTable for refTypes
                total += IsMultidimentional ? Dimensions * 8 : 4;
            }

            // Contents
            if (!IsMultidimentional)
            {
                total += (Lengthes) * elementsize;
            }
            else
            {
                var res = 1;
                for (int i = 1, len = Dimensions; i < len; i++)
                {
                    res *= GetLength(i);
                }

                total += res * elementsize;
            }

            // align size to IntPtr
            if ((total & 3) != 0)
                total += 4 - total % 4; }
예제 #8
0
 public void Register <TInterface>(string fullTypeName)
 {
     instances.Add(typeof(TInterface), EntityPtr.ToInstance <Object>(appdomain.CreateInstance(fullTypeName)));
 }
예제 #9
0
        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();
        }