I'm a first traveler coding in WinApi, Hooks, COM objects. Then, I made a dll to inject (EasyHook) this in the target SIEMENS Step7 process and modify the software code at runtime: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.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 parmetro? Se na DOC o primeiro parmetro dessa funo  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 no existia. Por que essa instncia no 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);    }}
Hook COM Object and get data from SIEMENS Step 7 software to control PLC through events in their code modified at runtime
c#;com;winapi