/// <summary> /// Do our best to validate that the input memory address is actually a COM object /// </summary> /// <param name="comObjectPtr">the input memory address to check</param> /// <returns>false means definitely not a valid COM object. true means _probably_ a valid COM object</returns> public static bool ValidateComObject(IntPtr comObjectPtr) { // Is it a valid memory address, with at least one accessible vTable ptr if (!IsValidMemoryRange(comObjectPtr, IntPtr.Size)) { return(false); } var vTablePtr = RdMarshal.ReadIntPtr(comObjectPtr); // And for a COM object, we need a valid vtable, with at least 3 vTable entries (for IUnknown) if (!IsValidMemoryRange(vTablePtr, IntPtr.Size * 3)) { return(false); } var firstvTableEntry = RdMarshal.ReadIntPtr(vTablePtr); // And lets check the first vTable entry actually points to EXECUTABLE memory // (we could check all 3 initial IUnknown entries, but we want to be reasonably // efficient and we can never 100% guarantee our result anyway.) if (IsValidMemoryRange(firstvTableEntry, 1, checkIsExecutable: true)) { // As best as we can tell, it looks to be a valid COM object return(true); } else { // One of the validation checks failed. The COM object is definitely not a valid COM object. return(false); } }