/// <summary> /// Scan SuperMemo to find the methods matching the signatures provided by /// <paramref name="nativeData" />. Also sets up the WndProc detour. /// </summary> /// <param name="nativeData">The offsets and method signatures for the running SuperMemo version</param> private unsafe void InstallSM(NativeData nativeData) { _smProcess = new ProcessSharp(System.Diagnostics.Process.GetCurrentProcess(), MemoryType.Local); // WndProc _wndProcDelegate = new ManagedWndProc(WndProc); WndProcWrapper.SetCallback(Marshal.GetFunctionPointerForDelegate(_wndProcDelegate)); SMA.SetWndProcHookAddr(WndProcWrapper.GetWndProcNativeWrapperAddr()); // Native calls ScanSMMethods(nativeData); }
public bool InstallWndProcHook() { bool resumeThreads = false; IEnumerable <IRemoteThread> threads = null; try { while (TApplicationInstancePtr.Read <int>() == 0) { Thread.Sleep(100); } #pragma warning disable CS0618 // Type or member is obsolete var currentThreadId = AppDomain.GetCurrentThreadId(); #pragma warning restore CS0618 // Type or member is obsolete threads = SMProcess.ThreadFactory.RemoteThreads.Where(t => t.Id != currentThreadId); foreach (var remoteThread in threads) { remoteThread.Suspend(); } resumeThreads = true; var wrapperAddr = WndProcWrapper.GetWndProcNativeWrapperAddr(); SMNatives.TApplication.TApplicationOnMessagePtr.Write <int>(SMProcess.Memory, wrapperAddr); return(true); } catch (Exception ex) { SMInject.Instance.OnException(ex); return(false); } finally { if (resumeThreads) { foreach (var remoteThread in threads) { remoteThread.Resume(); } } } }
// // WndProc public int GetWndProcNativeWrapperAddr() { return(WndProcWrapper.GetWndProcNativeWrapperAddr()); }