상속: IDisposable
예제 #1
0
        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);
            }
        }
예제 #2
0
        protected RemoteMemoryRegion GetFunctionRegion(string moduleName, string functionName, byte[] replacementBytes)
        {
            var address = GetFunctionAddress(moduleName, functionName);

            return(RemoteMemoryRegion.Existing(
                       Process, address, (uint)replacementBytes.Length
                       ));
        }
예제 #3
0
        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));
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
 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;
 }