public static IntPtr getObjectMethodTable(IntPtr objectIN, byte[] methodFinderIN) { IntPtr p = assemblyHelpers.VirtualAlloc(methodFinderIN); IntPtr methodTable = IntPtr.Zero; getMethodTableDel fireShellcode = (getMethodTableDel)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(p, typeof(getMethodTableDel)); try { uint lpflOldProtect = 0; assemblyHelpers.VirtualProtect(objectIN, (uint)IntPtr.Size, (uint)0x40, out lpflOldProtect); methodTable = fireShellcode(objectIN); } catch (System.Exception ex) { System.Windows.Forms.MessageBox.Show("Failed to get MethodTable " + ex.Message); assemblyHelpers.VirtualFree(p, 0, 0x8000); return(IntPtr.Zero); } assemblyHelpers.VirtualFree(p, 0, 0x8000); return(methodTable); }
/*Scan through heap and compare first four bytes of all objects to the method table pointer... * requires more or less a brute force approach :( (for now) */ public static List <IntPtr> getAllObjects(IntPtr firstObjectPointer, IntPtr methodTable, byte[] typeOfASM, byte[] entryIN) { List <IntPtr> matchedObjects = new List <IntPtr>(); int counter = 1; int i = 0; int err = 0; uint lpflOldProtect = 0; IntPtr testObjectLocation = IntPtr.Zero; IntPtr testMethodTable = IntPtr.Zero; IntPtr test3rdEntry = IntPtr.Zero; IntPtr size = IntPtr.Zero; object WORK = null; IntPtr getMethodTablefuncPtr = assemblyHelpers.VirtualAlloc(typeOfASM); getMethodTableDel fireShellcode = (getMethodTableDel)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(getMethodTablefuncPtr, typeof(getMethodTableDel)); IntPtr get3rdEntry = assemblyHelpers.VirtualAlloc(entryIN); getMethodTableDel getSecondRef = (getMethodTableDel)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(get3rdEntry, typeof(getMethodTableDel)); IntPtr thirdTable = getSecondRef(firstObjectPointer); // System.Windows.Forms.MessageBox.Show("Third entry at " + thirdTable.ToString("X")); //count down first until out of the heap while (true) { try { i = counter * IntPtr.Size; counter++; testObjectLocation = new IntPtr(firstObjectPointer.ToInt64() - i); //get a byte value to test on for an object // assemblyHelpers.VirtualProtect(testObjectLocation, (uint)IntPtr.Size, (uint)0x04, out lpflOldProtect); testMethodTable = fireShellcode(testObjectLocation); if (testMethodTable == methodTable) { test3rdEntry = getSecondRef(testObjectLocation); if (test3rdEntry == thirdTable) { Console.WriteLine("Object is at " + testObjectLocation.ToString("X")); if (IntPtr.Size == 4) { WORK = GetInstance(testObjectLocation); } else if (IntPtr.Size == 8) { WORK = GetInstance64(testObjectLocation); } matchedObjects.Add(testObjectLocation); Console.WriteLine("Object is at " + testObjectLocation.ToString("X")); err = 0; } } } catch (Exception ex) { if (ex.Message.Contains("Attempted to read or write protected memory") || ex.Message.Contains("AccessViolationException")) { err++; if (err > 20) { break; } } } } System.Windows.Forms.MessageBox.Show(testObjectLocation.ToString("X")); counter = 1; err = 0; //count down first until out of the heap while (true) { try { i = counter * IntPtr.Size; counter++; testObjectLocation = new IntPtr(firstObjectPointer.ToInt64() + i); //get a byte value to test on for an object assemblyHelpers.VirtualProtect(testObjectLocation, (uint)IntPtr.Size, (uint)0x04, out lpflOldProtect); testMethodTable = fireShellcode(testObjectLocation); if (testMethodTable == methodTable) { test3rdEntry = getSecondRef(testObjectLocation); if (test3rdEntry == thirdTable) { Console.WriteLine("Object is at " + testObjectLocation.ToString("X")); if (IntPtr.Size == 4) { WORK = GetInstance(testObjectLocation); } else if (IntPtr.Size == 8) { WORK = GetInstance64(testObjectLocation); } matchedObjects.Add(testObjectLocation); Console.WriteLine("Object is at " + testObjectLocation.ToString("X")); err = 0; } } } catch (Exception ex) { if (ex.Message.Contains("Attempted to read or write protected memory") || ex.Message.Contains("AccessViolationException")) { err++; if (err > 20) { break; } } } } // System.Windows.Forms.MessageBox.Show(testObjectLocation.ToString("X")); assemblyHelpers.VirtualFree(getMethodTablefuncPtr, 0, 0x8000); return(matchedObjects); }