protected override void WndProc(ref Message m) { if (m.Msg == WM_RPC_MESSAGE) { byte[] messageData = null; UInt32 messageID = 0; if ((m.WParam != IntPtr.Zero) && (m.LParam != IntPtr.Zero)) { using (var region = RemoteMemoryRegion.Existing(_Process, m.WParam, (uint)m.LParam.ToInt64())) messageData = ReadRemoteData(region, out messageID); } Future <byte[]> fResult; Monitor.Enter(_AwaitingResponses); if (_AwaitingResponses.TryGetValue(messageID, out fResult)) { _AwaitingResponses.Remove(messageID); Monitor.Exit(_AwaitingResponses); fResult.SetResult(messageData, null); } else { Debug.Assert(messageID == 0); Monitor.Exit(_AwaitingResponses); _Messages.Enqueue(messageData); } } else { base.WndProc(ref m); } }
protected RemoteMemoryRegion GetFunctionRegion(string moduleName, string functionName, byte[] replacementBytes) { var address = GetFunctionAddress(moduleName, functionName); return(RemoteMemoryRegion.Existing( Process, address, (uint)replacementBytes.Length )); }
protected unsafe byte[] ReadRemoteData(RemoteMemoryRegion region, out UInt32 messageId) { using (var handle = region.OpenHandle(ProcessAccessFlags.VMRead)) { messageId = BitConverter.ToUInt32( region.ReadBytes(handle, 0, 4), 0 ); return(region.ReadBytes(handle, 4, region.Size - 4)); } }
public static RemoteMemoryRegion Allocate(Process process, SafeProcessHandle handle, UInt32 size) { var result = new RemoteMemoryRegion { Process = process, Size = size }; result.Address = Win32.VirtualAllocEx( handle.DangerousGetHandle(), IntPtr.Zero, size, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ReadWrite ); if (result.Address == IntPtr.Zero) { var error = Win32.GetLastError(); throw new Exception(String.Format("Allocation failed: Error {0:x8}", error)); } return(result); }
public unsafe Future <byte[]> Send(RPCMessage message, bool wantResponse) { if (_Process == null) { throw new Exception("No remote process"); } if (RemoteThreadId == 0) { throw new Exception("No remote thread"); } UInt32 messageSize = (UInt32)Marshal.SizeOf(typeof(TransportRPCMessage)); UInt32 moduleNameSize = TransportStringSize(message.ModuleName); UInt32 functionNameSize = TransportStringSize(message.FunctionName); UInt32 textSize = TransportStringSize(message.Text); Future <byte[]> result = null; UInt32 messageID = 0; if (wantResponse) { messageID = GetMessageID(); result = new Future <byte[]>(); _AwaitingResponses[messageID] = result; } using (var handle = Win32.OpenProcessHandle(ProcessAccessFlags.VMWrite | ProcessAccessFlags.VMOperation, false, _Process.Id)) { RemoteMemoryRegion region; var regionSize = messageSize + moduleNameSize + textSize + functionNameSize; var buffer = new byte[regionSize]; // leaked on purpose region = RemoteMemoryRegion.Allocate( _Process, handle, regionSize ); object transportMessage = new TransportRPCMessage { Type = message.Type, MessageId = messageID, Text = WriteTransportString(message.Text, buffer, messageSize, region.Address), FunctionName = WriteTransportString(message.FunctionName, buffer, messageSize + textSize, region.Address), ModuleName = WriteTransportString(message.ModuleName, buffer, messageSize + textSize + functionNameSize, region.Address) }; fixed(byte *pBuffer = buffer) { Marshal.StructureToPtr(transportMessage, new IntPtr(pBuffer), false); try { region.Write(handle, 0, regionSize, pBuffer); } catch { try { region.Dispose(); } catch { } throw; } } if (!Win32.PostThreadMessage(RemoteThreadId, WM_RPC_MESSAGE, region.Address, region.Size)) { var error = Win32.GetLastError(); region.Dispose(); throw new Exception(String.Format("Error posting thread message: {0:x8}", error)); } } return(result); }
public static RemoteMemoryRegion Allocate(Process process, SafeProcessHandle handle, UInt32 size) { var result = new RemoteMemoryRegion { Process = process, Size = size }; result.Address = Win32.VirtualAllocEx( handle.DangerousGetHandle(), IntPtr.Zero, size, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ReadWrite ); if (result.Address == IntPtr.Zero) { var error = Win32.GetLastError(); throw new Exception(String.Format("Allocation failed: Error {0:x8}", error)); } return result; }