private IntPtr ExecuteFuntion(string module, string function, byte[] arguments, bool canWait = true) { SafeWaitHandle remoteThread = null; var argumentsAllocation = _memoryManager.Allocate( arguments.Length, MemoryProtectionType.ReadWrite, !canWait); if (argumentsAllocation.Address == IntPtr.Zero) { throw new Win32Exception("Failed to allocate memory in remote process."); } try { var processHandle = _process.SafeHandle; // Write the arguments buffer to our allocated address _memoryManager.WriteMemory(argumentsAllocation.Address.ToInt64(), arguments); // Execute the function call in a new thread remoteThread = ThreadHelper.CreateRemoteThread(processHandle, ThreadHelper.GetProcAddress(processHandle, module, function), argumentsAllocation.Address); if (canWait) { Interop.Kernel32.WaitForSingleObject( remoteThread, System.Threading.Timeout.Infinite); } return(argumentsAllocation.Address); } finally { remoteThread?.Dispose(); if (canWait) { _memoryManager.Deallocate(argumentsAllocation); } } }