Skip to main content
Rollback to Revision 2
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
using EasyHook;
using Octtos.S7ussapx.Injected.COM.Interfaces;
using Octtos.S7ussapx.Injected.Step7.COM.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace Octtos.S7ussapx.Injected
{
    public class Main : IEntryPoint
    {
        private ClientCallbackHandler _callbackHandler;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        unsafe delegate int IDispatchInvokeDelegate(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags,
            ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult,
            ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr);

        #region CoGetClassObject ole32.dll

        private LocalHook _coGetClassObjectHook;

        private LocalHook _S7StatusOCXIClassFacttoryCreateInstanceHook;
        private LocalHook _S7VarServer50IClassFacttoryCreateInstanceHook2;

        private bool _s7StatusOCXCOMHookCreated = false;
        private bool _s7VarServer50COMHookCreated = false;

        private IntPtr _S7StatusOCXIClassFacttoryCreateInstanceMethodPtr;
        private IntPtr _S7VarServer50IClassFacttoryCreateInstanceMethodPtr;

        private delegate uint CoGetClassObjectDelegate(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid, out IntPtr ppv);

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv);

        private static unsafe uint CoGetClassObject_Hook(ref Guid clsid, int dwClsContext, IntPtr pServerInfo, ref Guid iid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;
            var classObjectInstance = CoGetClassObject(ref clsid, dwClsContext, pServerInfo, ref iid);

            ppv = Marshal.GetIUnknownForObject(classObjectInstance);

            var iclassFactory = classObjectInstance as IClassFactory;

            if (!me._s7StatusOCXCOMHookCreated)
            { 
                if (iclassFactory != null && clsid == typeof(IS7StatusOcx).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7StatusOCXIClassFacttoryCreateInstanceHook = LocalHook.Create(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7StatusOCXCreateInstance_Hook), me);
                    me._S7StatusOCXIClassFacttoryCreateInstanceHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7StatusOCXCOMHookCreated = true;
                }
            }

            if (!me._s7VarServer50COMHookCreated)
            {
                if (iclassFactory != null && clsid == typeof(IS7VarServer50).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7VarServer50IClassFacttoryCreateInstanceHook2 = LocalHook.Create(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7VarServer50CreateInstance_Hook), me);
                    me._S7VarServer50IClassFacttoryCreateInstanceHook2.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7VarServer50COMHookCreated = true;
                }
            }

            Marshal.ReleaseComObject(classObjectInstance);

            return 0;
        }

        #endregion

        #region S7StatusOCX IClassFactory.Create ole32.dll

        private IS7StatusOcxDispatch _currentInstance;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate2(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object obj);

        private static unsafe int S7StatusOCXCreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            me._currentInstance = (IS7StatusOcxDispatch)objInstance;

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            return hr;
        }

        #endregion

        #region S7VarServer50 IClassFactory.Create ole32.dll

        private LocalHook _s7VarServer5IDispatchHook;

        private IntPtr _s7VarServer50IDispatchInvokeMethodPtr;

        private bool _S7VarServer50CreateInstanceHookCreated = false;

        private IDictionary<IntPtr, IS7StatusOcxDispatch> _s7StatusOCXDispatchInstances = new Dictionary<IntPtr, IS7StatusOcxDispatch>();

        private static unsafe int S7VarServer50CreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            if (objInstance is IS7VarServer50Dispatch)
            {
                Guid iidIDispatch = typeof(IDispatch).GUID;
                IntPtr ppv3;
                Marshal.QueryInterface(ppv2, ref iidIDispatch, out ppv3);

                if (me._s7StatusOCXDispatchInstances.ContainsKey(ppv3))
                {
                    me._s7StatusOCXDispatchInstances[ppv3] = me._currentInstance;
                }
                else { 
                    me._s7StatusOCXDispatchInstances.Add(ppv3, me._currentInstance);
                }

                me._currentInstance = null;
                

                if (!me._S7VarServer50CreateInstanceHookCreated)
                {
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(typeof(IDispatch).GetMethod("Invoke"));

                    int** comVTable = *(int***)ppv3.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._s7VarServer50IDispatchInvokeMethodPtr = new IntPtr(hMethod);

                    me._s7VarServer5IDispatchHook = LocalHook.Create(me._s7VarServer50IDispatchInvokeMethodPtr, new IDispatchInvokeDelegate(S7VarServer50IDispatch_Invoke_Hook), me);
                    me._s7VarServer5IDispatchHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._S7VarServer50CreateInstanceHookCreated = true;
                }
            }

            return hr;
        }

        //Por que esse IDispatch tem IntPtr pThis como primeiro parâmetro? Se na DOC o primeiro parâmetro dessa função é o dispIdMember?!
        //http://msdn.microsoft.com/en-us/library/aa912367.aspx
        unsafe static int S7VarServer50IDispatch_Invoke_Hook(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            switch (dispIdMember)
            {
                case 14:
                    me._callbackHandler.WriteLine("CreateForceJob() called");
                    break;
                case 15:
                    me._callbackHandler.WriteLine("StartForceJob() called");

                    IS7StatusOcxDispatch instance;
                    
                    if (me._s7StatusOCXDispatchInstances.TryGetValue(pthis, out instance))
                    {
                        string varList;
                        instance.GetVariableList(out varList, false);

                        var bytes = Encoding.Unicode.GetBytes(varList);
                        var str = Encoding.Default.GetString(bytes);
                        me._callbackHandler.WriteLine(str);
                    }
                    else
                    {
                        me._callbackHandler.WriteLine("ERROR!!! Tentou pegar uma instancia que não existia. Por que essa instância não existe?");
                    }

                    break;
                default:
                    break;
            }

            var baseMethod = (IDispatchInvokeDelegate)Marshal.GetDelegateForFunctionPointer(me._s7VarServer50IDispatchInvokeMethodPtr, typeof(IDispatchInvokeDelegate));
            return baseMethod(pthis, dispIdMember, ref riid, lcid, wFlags, ref pDispParams, ppvResult, ref pExcepInfo, pArgErr);
        }

        #endregion

        public Main(RemoteHooking.IContext ctx, string channelId)
        {
            _callbackHandler = RemoteHooking.IpcConnectClient<ClientCallbackHandler>(channelId);
        }

        public unsafe void Run(RemoteHooking.IContext ctx, string arg1)
        {
            try
            {
                _coGetClassObjectHook = LocalHook.Create(LocalHook.GetProcAddress("ole32.dll", "CoGetClassObject"),
                    new CoGetClassObjectDelegate(CoGetClassObject_Hook), this);
                _coGetClassObjectHook.ThreadACL.SetExclusiveACL(new int[0]);

                RemoteHooking.WakeUpProcess();
                _callbackHandler.InjectStart();

                while (true)
                {
                    _callbackHandler.SetIsAlive(true);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        private static extern object CoGetClassObject(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid);
    }
}
using EasyHook;
using Octtos.S7ussapx.Injected.COM.Interfaces;
using Octtos.S7ussapx.Injected.Step7.COM.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace Octtos.S7ussapx.Injected
{
    public class Main : IEntryPoint
    {
        private ClientCallbackHandler _callbackHandler;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        unsafe delegate int IDispatchInvokeDelegate(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags,
            ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult,
            ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr);

        #region CoGetClassObject ole32.dll

        private LocalHook _coGetClassObjectHook;

        private LocalHook _S7StatusOCXIClassFacttoryCreateInstanceHook;
        private LocalHook _S7VarServer50IClassFacttoryCreateInstanceHook2;

        private bool _s7StatusOCXCOMHookCreated = false;
        private bool _s7VarServer50COMHookCreated = false;

        private IntPtr _S7StatusOCXIClassFacttoryCreateInstanceMethodPtr;
        private IntPtr _S7VarServer50IClassFacttoryCreateInstanceMethodPtr;

        private delegate uint CoGetClassObjectDelegate(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid, out IntPtr ppv);

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv);

        private static unsafe uint CoGetClassObject_Hook(ref Guid clsid, int dwClsContext, IntPtr pServerInfo, ref Guid iid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;
            var classObjectInstance = CoGetClassObject(ref clsid, dwClsContext, pServerInfo, ref iid);

            ppv = Marshal.GetIUnknownForObject(classObjectInstance);

            var iclassFactory = classObjectInstance as IClassFactory;

            if (!me._s7StatusOCXCOMHookCreated)
            { 
                if (iclassFactory != null && clsid == typeof(IS7StatusOcx).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7StatusOCXIClassFacttoryCreateInstanceHook = LocalHook.Create(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7StatusOCXCreateInstance_Hook), me);
                    me._S7StatusOCXIClassFacttoryCreateInstanceHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7StatusOCXCOMHookCreated = true;
                }
            }

            if (!me._s7VarServer50COMHookCreated)
            {
                if (iclassFactory != null && clsid == typeof(IS7VarServer50).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7VarServer50IClassFacttoryCreateInstanceHook2 = LocalHook.Create(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7VarServer50CreateInstance_Hook), me);
                    me._S7VarServer50IClassFacttoryCreateInstanceHook2.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7VarServer50COMHookCreated = true;
                }
            }

            Marshal.ReleaseComObject(classObjectInstance);

            return 0;
        }

        #endregion

        #region S7StatusOCX IClassFactory.Create ole32.dll

        private IS7StatusOcxDispatch _currentInstance;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate2(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object obj);

        private static unsafe int S7StatusOCXCreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            me._currentInstance = (IS7StatusOcxDispatch)objInstance;

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            return hr;
        }

        #endregion

        #region S7VarServer50 IClassFactory.Create ole32.dll

        private LocalHook _s7VarServer5IDispatchHook;

        private IntPtr _s7VarServer50IDispatchInvokeMethodPtr;

        private bool _S7VarServer50CreateInstanceHookCreated = false;

        private IDictionary<IntPtr, IS7StatusOcxDispatch> _s7StatusOCXDispatchInstances = new Dictionary<IntPtr, IS7StatusOcxDispatch>();

        private static unsafe int S7VarServer50CreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            if (objInstance is IS7VarServer50Dispatch)
            {
                Guid iidIDispatch = typeof(IDispatch).GUID;
                IntPtr ppv3;
                Marshal.QueryInterface(ppv2, ref iidIDispatch, out ppv3);

                if (me._s7StatusOCXDispatchInstances.ContainsKey(ppv3))
                {
                    me._s7StatusOCXDispatchInstances[ppv3] = me._currentInstance;
                }
                else { 
                    me._s7StatusOCXDispatchInstances.Add(ppv3, me._currentInstance);
                }

                me._currentInstance = null;
                

                if (!me._S7VarServer50CreateInstanceHookCreated)
                {
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(typeof(IDispatch).GetMethod("Invoke"));

                    int** comVTable = *(int***)ppv3.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._s7VarServer50IDispatchInvokeMethodPtr = new IntPtr(hMethod);

                    me._s7VarServer5IDispatchHook = LocalHook.Create(me._s7VarServer50IDispatchInvokeMethodPtr, new IDispatchInvokeDelegate(S7VarServer50IDispatch_Invoke_Hook), me);
                    me._s7VarServer5IDispatchHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._S7VarServer50CreateInstanceHookCreated = true;
                }
            }

            return hr;
        }

        //Por que esse IDispatch tem IntPtr pThis como primeiro parâmetro? Se na DOC o primeiro parâmetro dessa função é o dispIdMember?!
        //http://msdn.microsoft.com/en-us/library/aa912367.aspx
        unsafe static int S7VarServer50IDispatch_Invoke_Hook(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            switch (dispIdMember)
            {
                case 14:
                    me._callbackHandler.WriteLine("CreateForceJob() called");
                    break;
                case 15:
                    me._callbackHandler.WriteLine("StartForceJob() called");

                    IS7StatusOcxDispatch instance;
                    
                    if (me._s7StatusOCXDispatchInstances.TryGetValue(pthis, out instance))
                    {
                        string varList;
                        instance.GetVariableList(out varList, false);

                        var bytes = Encoding.Unicode.GetBytes(varList);
                        var str = Encoding.Default.GetString(bytes);
                        me._callbackHandler.WriteLine(str);
                    }
                    else
                    {
                        me._callbackHandler.WriteLine("ERROR!!! Tentou pegar uma instancia que não existia. Por que essa instância não existe?");
                    }

                    break;
                default:
                    break;
            }

            var baseMethod = (IDispatchInvokeDelegate)Marshal.GetDelegateForFunctionPointer(me._s7VarServer50IDispatchInvokeMethodPtr, typeof(IDispatchInvokeDelegate));
            return baseMethod(pthis, dispIdMember, ref riid, lcid, wFlags, ref pDispParams, ppvResult, ref pExcepInfo, pArgErr);
        }

        #endregion

        public Main(RemoteHooking.IContext ctx, string channelId)
        {
            _callbackHandler = RemoteHooking.IpcConnectClient<ClientCallbackHandler>(channelId);
        }

        public unsafe void Run(RemoteHooking.IContext ctx, string arg1)
        {
            try
            {
                _coGetClassObjectHook = LocalHook.Create(LocalHook.GetProcAddress("ole32.dll", "CoGetClassObject"),
                    new CoGetClassObjectDelegate(CoGetClassObject_Hook), this);
                _coGetClassObjectHook.ThreadACL.SetExclusiveACL(new int[0]);

                RemoteHooking.WakeUpProcess();
                _callbackHandler.InjectStart();

                while (true)
                {
                    _callbackHandler.SetIsAlive(true);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        private static extern object CoGetClassObject(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid);
    }
}
deleted 12383 characters in body
Source Link
using EasyHook;
using Octtos.S7ussapx.Injected.COM.Interfaces;
using Octtos.S7ussapx.Injected.Step7.COM.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace Octtos.S7ussapx.Injected
{
    public class Main : IEntryPoint
    {
        private ClientCallbackHandler _callbackHandler;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        unsafe delegate int IDispatchInvokeDelegate(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags,
            ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult,
            ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr);

        #region CoGetClassObject ole32.dll

        private LocalHook _coGetClassObjectHook;

        private LocalHook _S7StatusOCXIClassFacttoryCreateInstanceHook;
        private LocalHook _S7VarServer50IClassFacttoryCreateInstanceHook2;

        private bool _s7StatusOCXCOMHookCreated = false;
        private bool _s7VarServer50COMHookCreated = false;

        private IntPtr _S7StatusOCXIClassFacttoryCreateInstanceMethodPtr;
        private IntPtr _S7VarServer50IClassFacttoryCreateInstanceMethodPtr;

        private delegate uint CoGetClassObjectDelegate(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid, out IntPtr ppv);

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv);

        private static unsafe uint CoGetClassObject_Hook(ref Guid clsid, int dwClsContext, IntPtr pServerInfo, ref Guid iid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;
            var classObjectInstance = CoGetClassObject(ref clsid, dwClsContext, pServerInfo, ref iid);

            ppv = Marshal.GetIUnknownForObject(classObjectInstance);

            var iclassFactory = classObjectInstance as IClassFactory;

            if (!me._s7StatusOCXCOMHookCreated)
            { 
                if (iclassFactory != null && clsid == typeof(IS7StatusOcx).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7StatusOCXIClassFacttoryCreateInstanceHook = LocalHook.Create(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7StatusOCXCreateInstance_Hook), me);
                    me._S7StatusOCXIClassFacttoryCreateInstanceHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7StatusOCXCOMHookCreated = true;
                }
            }

            if (!me._s7VarServer50COMHookCreated)
            {
                if (iclassFactory != null && clsid == typeof(IS7VarServer50).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7VarServer50IClassFacttoryCreateInstanceHook2 = LocalHook.Create(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7VarServer50CreateInstance_Hook), me);
                    me._S7VarServer50IClassFacttoryCreateInstanceHook2.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7VarServer50COMHookCreated = true;
                }
            }

            Marshal.ReleaseComObject(classObjectInstance);

            return 0;
        }

        #endregion

        #region S7StatusOCX IClassFactory.Create ole32.dll

        private IS7StatusOcxDispatch _currentInstance;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate2(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object obj);

        private static unsafe int S7StatusOCXCreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            me._currentInstance = (IS7StatusOcxDispatch)objInstance;

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            return hr;
        }

        #endregion

        #region S7VarServer50 IClassFactory.Create ole32.dll

        private LocalHook _s7VarServer5IDispatchHook;

        private IntPtr _s7VarServer50IDispatchInvokeMethodPtr;

        private bool _S7VarServer50CreateInstanceHookCreated = false;

        private IDictionary<IntPtr, IS7StatusOcxDispatch> _s7StatusOCXDispatchInstances = new Dictionary<IntPtr, IS7StatusOcxDispatch>();

        private static unsafe int S7VarServer50CreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            if (objInstance is IS7VarServer50Dispatch)
            {
                Guid iidIDispatch = typeof(IDispatch).GUID;
                IntPtr ppv3;
                Marshal.QueryInterface(ppv2, ref iidIDispatch, out ppv3);

                if (me._s7StatusOCXDispatchInstances.ContainsKey(ppv3))
                {
                    me._s7StatusOCXDispatchInstances[ppv3] = me._currentInstance;
                }
                else { 
                    me._s7StatusOCXDispatchInstances.Add(ppv3, me._currentInstance);
                }

                me._currentInstance = null;
                

                if (!me._S7VarServer50CreateInstanceHookCreated)
                {
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(typeof(IDispatch).GetMethod("Invoke"));

                    int** comVTable = *(int***)ppv3.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._s7VarServer50IDispatchInvokeMethodPtr = new IntPtr(hMethod);

                    me._s7VarServer5IDispatchHook = LocalHook.Create(me._s7VarServer50IDispatchInvokeMethodPtr, new IDispatchInvokeDelegate(S7VarServer50IDispatch_Invoke_Hook), me);
                    me._s7VarServer5IDispatchHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._S7VarServer50CreateInstanceHookCreated = true;
                }
            }

            return hr;
        }

        //Por que esse IDispatch tem IntPtr pThis como primeiro parâmetro? Se na DOC o primeiro parâmetro dessa função é o dispIdMember?!
        //http://msdn.microsoft.com/en-us/library/aa912367.aspx
        unsafe static int S7VarServer50IDispatch_Invoke_Hook(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            switch (dispIdMember)
            {
                case 14:
                    me._callbackHandler.WriteLine("CreateForceJob() called");
                    break;
                case 15:
                    me._callbackHandler.WriteLine("StartForceJob() called");

                    IS7StatusOcxDispatch instance;
                    
                    if (me._s7StatusOCXDispatchInstances.TryGetValue(pthis, out instance))
                    {
                        string varList;
                        instance.GetVariableList(out varList, false);

                        var bytes = Encoding.Unicode.GetBytes(varList);
                        var str = Encoding.Default.GetString(bytes);
                        me._callbackHandler.WriteLine(str);
                    }
                    else
                    {
                        me._callbackHandler.WriteLine("ERROR!!! Tentou pegar uma instancia que não existia. Por que essa instância não existe?");
                    }

                    break;
                default:
                    break;
            }

            var baseMethod = (IDispatchInvokeDelegate)Marshal.GetDelegateForFunctionPointer(me._s7VarServer50IDispatchInvokeMethodPtr, typeof(IDispatchInvokeDelegate));
            return baseMethod(pthis, dispIdMember, ref riid, lcid, wFlags, ref pDispParams, ppvResult, ref pExcepInfo, pArgErr);
        }

        #endregion

        public Main(RemoteHooking.IContext ctx, string channelId)
        {
            _callbackHandler = RemoteHooking.IpcConnectClient<ClientCallbackHandler>(channelId);
        }

        public unsafe void Run(RemoteHooking.IContext ctx, string arg1)
        {
            try
            {
                _coGetClassObjectHook = LocalHook.Create(LocalHook.GetProcAddress("ole32.dll", "CoGetClassObject"),
                    new CoGetClassObjectDelegate(CoGetClassObject_Hook), this);
                _coGetClassObjectHook.ThreadACL.SetExclusiveACL(new int[0]);

                RemoteHooking.WakeUpProcess();
                _callbackHandler.InjectStart();

                while (true)
                {
                    _callbackHandler.SetIsAlive(true);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        private static extern object CoGetClassObject(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid);
    }
}
using EasyHook;
using Octtos.S7ussapx.Injected.COM.Interfaces;
using Octtos.S7ussapx.Injected.Step7.COM.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace Octtos.S7ussapx.Injected
{
    public class Main : IEntryPoint
    {
        private ClientCallbackHandler _callbackHandler;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        unsafe delegate int IDispatchInvokeDelegate(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags,
            ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult,
            ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr);

        #region CoGetClassObject ole32.dll

        private LocalHook _coGetClassObjectHook;

        private LocalHook _S7StatusOCXIClassFacttoryCreateInstanceHook;
        private LocalHook _S7VarServer50IClassFacttoryCreateInstanceHook2;

        private bool _s7StatusOCXCOMHookCreated = false;
        private bool _s7VarServer50COMHookCreated = false;

        private IntPtr _S7StatusOCXIClassFacttoryCreateInstanceMethodPtr;
        private IntPtr _S7VarServer50IClassFacttoryCreateInstanceMethodPtr;

        private delegate uint CoGetClassObjectDelegate(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid, out IntPtr ppv);

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv);

        private static unsafe uint CoGetClassObject_Hook(ref Guid clsid, int dwClsContext, IntPtr pServerInfo, ref Guid iid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;
            var classObjectInstance = CoGetClassObject(ref clsid, dwClsContext, pServerInfo, ref iid);

            ppv = Marshal.GetIUnknownForObject(classObjectInstance);

            var iclassFactory = classObjectInstance as IClassFactory;

            if (!me._s7StatusOCXCOMHookCreated)
            { 
                if (iclassFactory != null && clsid == typeof(IS7StatusOcx).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7StatusOCXIClassFacttoryCreateInstanceHook = LocalHook.Create(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7StatusOCXCreateInstance_Hook), me);
                    me._S7StatusOCXIClassFacttoryCreateInstanceHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7StatusOCXCOMHookCreated = true;
                }
            }

            if (!me._s7VarServer50COMHookCreated)
            {
                if (iclassFactory != null && clsid == typeof(IS7VarServer50).GUID)
                {
                    var method = typeof(IClassFactory).GetMethod("CreateInstance");
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(method);

                    int** comVTable = *(int***)ppv.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr = new IntPtr(hMethod);

                    me._S7VarServer50IClassFacttoryCreateInstanceHook2 = LocalHook.Create(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, new IClassFactoryCreateInstanceDelegate(S7VarServer50CreateInstance_Hook), me);
                    me._S7VarServer50IClassFacttoryCreateInstanceHook2.ThreadACL.SetExclusiveACL(new int[0]);

                    me._s7VarServer50COMHookCreated = true;
                }
            }

            Marshal.ReleaseComObject(classObjectInstance);

            return 0;
        }

        #endregion

        #region S7StatusOCX IClassFactory.Create ole32.dll

        private IS7StatusOcxDispatch _currentInstance;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate int IClassFactoryCreateInstanceDelegate2(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object obj);

        private static unsafe int S7StatusOCXCreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7StatusOCXIClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            me._currentInstance = (IS7StatusOcxDispatch)objInstance;

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            return hr;
        }

        #endregion

        #region S7VarServer50 IClassFactory.Create ole32.dll

        private LocalHook _s7VarServer5IDispatchHook;

        private IntPtr _s7VarServer50IDispatchInvokeMethodPtr;

        private bool _S7VarServer50CreateInstanceHookCreated = false;

        private IDictionary<IntPtr, IS7StatusOcxDispatch> _s7StatusOCXDispatchInstances = new Dictionary<IntPtr, IS7StatusOcxDispatch>();

        private static unsafe int S7VarServer50CreateInstance_Hook(IntPtr pThis, IntPtr pUnkOuter, ref Guid riid, out IntPtr ppv)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            var baseMethod = (IClassFactoryCreateInstanceDelegate2)Marshal.GetDelegateForFunctionPointer(me._S7VarServer50IClassFacttoryCreateInstanceMethodPtr, typeof(IClassFactoryCreateInstanceDelegate2));

            object objInstance;
            var hr = baseMethod(pThis, pUnkOuter, ref riid, out objInstance);

            var ppv2 = Marshal.GetIUnknownForObject(objInstance);

            Marshal.QueryInterface(ppv2, ref riid, out ppv);

            if (objInstance is IS7VarServer50Dispatch)
            {
                Guid iidIDispatch = typeof(IDispatch).GUID;
                IntPtr ppv3;
                Marshal.QueryInterface(ppv2, ref iidIDispatch, out ppv3);

                if (me._s7StatusOCXDispatchInstances.ContainsKey(ppv3))
                {
                    me._s7StatusOCXDispatchInstances[ppv3] = me._currentInstance;
                }
                else { 
                    me._s7StatusOCXDispatchInstances.Add(ppv3, me._currentInstance);
                }

                me._currentInstance = null;
                

                if (!me._S7VarServer50CreateInstanceHookCreated)
                {
                    var methodVTableIdx = Marshal.GetComSlotForMethodInfo(typeof(IDispatch).GetMethod("Invoke"));

                    int** comVTable = *(int***)ppv3.ToPointer();
                    int* hMethod = comVTable[methodVTableIdx];
                    me._s7VarServer50IDispatchInvokeMethodPtr = new IntPtr(hMethod);

                    me._s7VarServer5IDispatchHook = LocalHook.Create(me._s7VarServer50IDispatchInvokeMethodPtr, new IDispatchInvokeDelegate(S7VarServer50IDispatch_Invoke_Hook), me);
                    me._s7VarServer5IDispatchHook.ThreadACL.SetExclusiveACL(new int[0]);

                    me._S7VarServer50CreateInstanceHookCreated = true;
                }
            }

            return hr;
        }

        //Por que esse IDispatch tem IntPtr pThis como primeiro parâmetro? Se na DOC o primeiro parâmetro dessa função é o dispIdMember?!
        //http://msdn.microsoft.com/en-us/library/aa912367.aspx
        unsafe static int S7VarServer50IDispatch_Invoke_Hook(IntPtr pthis, int dispIdMember, ref Guid riid, uint lcid, ushort wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, void* ppvResult, ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, IntPtr[] pArgErr)
        {
            var me = (Main)HookRuntimeInfo.Callback;

            switch (dispIdMember)
            {
                case 14:
                    me._callbackHandler.WriteLine("CreateForceJob() called");
                    break;
                case 15:
                    me._callbackHandler.WriteLine("StartForceJob() called");

                    IS7StatusOcxDispatch instance;
                    
                    if (me._s7StatusOCXDispatchInstances.TryGetValue(pthis, out instance))
                    {
                        string varList;
                        instance.GetVariableList(out varList, false);

                        var bytes = Encoding.Unicode.GetBytes(varList);
                        var str = Encoding.Default.GetString(bytes);
                        me._callbackHandler.WriteLine(str);
                    }
                    else
                    {
                        me._callbackHandler.WriteLine("ERROR!!! Tentou pegar uma instancia que não existia. Por que essa instância não existe?");
                    }

                    break;
                default:
                    break;
            }

            var baseMethod = (IDispatchInvokeDelegate)Marshal.GetDelegateForFunctionPointer(me._s7VarServer50IDispatchInvokeMethodPtr, typeof(IDispatchInvokeDelegate));
            return baseMethod(pthis, dispIdMember, ref riid, lcid, wFlags, ref pDispParams, ppvResult, ref pExcepInfo, pArgErr);
        }

        #endregion

        public Main(RemoteHooking.IContext ctx, string channelId)
        {
            _callbackHandler = RemoteHooking.IpcConnectClient<ClientCallbackHandler>(channelId);
        }

        public unsafe void Run(RemoteHooking.IContext ctx, string arg1)
        {
            try
            {
                _coGetClassObjectHook = LocalHook.Create(LocalHook.GetProcAddress("ole32.dll", "CoGetClassObject"),
                    new CoGetClassObjectDelegate(CoGetClassObject_Hook), this);
                _coGetClassObjectHook.ThreadACL.SetExclusiveACL(new int[0]);

                RemoteHooking.WakeUpProcess();
                _callbackHandler.InjectStart();

                while (true)
                {
                    _callbackHandler.SetIsAlive(true);
                    Thread.Sleep(TimeSpan.FromSeconds(2));
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        private static extern object CoGetClassObject(ref Guid rclsid, int dwClsContext, IntPtr pServerInfo, ref Guid riid);
    }
}
deleted 13 characters in body; edited tags
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Maybe I want some opinion about this kind of practices, hooking, injection, file system driver, kernel hook, modify .exe vtable before init, interprocess-comunicationcommunication, etc.

This code getgets the DataSourceDataSource from a Grid GUI(COM Object) when the user do a determined "Force" action through menu. That's the code:

Maybe I want some opinion about this kind of practices, hooking, injection, file system driver, kernel hook, modify .exe vtable before init, interprocess-comunication, etc.

This code get the DataSource from a Grid GUI(COM Object) when the user do a determined "Force" action through menu. That's the code:

Maybe I want some opinion about this kind of practices, hooking, injection, file system driver, kernel hook, modify .exe vtable before init, interprocess-communication, etc.

This code gets the DataSource from a Grid GUI(COM Object) when the user do a determined "Force" action through menu.

Source Link
Loading