public async ValueTask <Connection> InjectAsync(uint pid, MethodInfo entryPoint, CancellationToken cancellationToken) { var option = this.Option; var declaringType = entryPoint.DeclaringType; var assemblyLocation = declaringType.Assembly.Location; var typeName = declaringType.FullName; var methodName = entryPoint.Name; var process = NativeFunctions.OpenProcess(NativeFunctions.Consts.PROCESS_ALL_ACCESS, false, pid); if (process == IntPtr.Zero) { throw new MoguException($"Can not open process '{pid}'"); } var loadLibraryW = ProcessUtil.GetProcAddressFromProcessMemory(process, "kernel32", "LoadLibraryW"); if (loadLibraryW == IntPtr.Zero) { throw new MoguException($"Can not get 'LoadLibraryW' address"); } var pipeName = $"MoguPipe-{Guid.NewGuid()}"; var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut); try { var(nethostDllPath, moguhostDllPath) = GetNativeDllPath(process, assemblyLocation); // TODO: Get mutex for create MemoryMappedFile. var memorySize = 3 * 4 + (assemblyLocation.Length + typeName.Length + methodName.Length) * 2; using (var sharedMemory = MemoryMappedFile.CreateNew(GetMemoryMappedFileName(pid), memorySize)) using (var accessor = sharedMemory.CreateViewAccessor()) { int position = 0; accessor.Write(position, assemblyLocation, out position); accessor.Write(position, typeName, out position); accessor.Write(position, methodName, out position); accessor.Write(position, pipeName, out position); if (!(await InjectNativeDllAsync(process, nethostDllPath, loadLibraryW, false))) { throw new MoguException($"Can not inject nethost.dll to process({pid})"); } var waitForConnectionTask = pipe.WaitForConnectionAsync(cancellationToken); if (!(await InjectNativeDllAsync(process, moguhostDllPath, loadLibraryW, false))) { throw new MoguException($"Can not inject MoguHost.dll to process({pid})"); } await Task.WhenAny( waitForConnectionTask, Task.Delay(option.InjectDllTimeOut) ); cancellationToken.ThrowIfCancellationRequested(); if (!waitForConnectionTask.IsCompleted) { throw new MoguException("TimeOut inject dll"); } } } catch { pipe.Dispose(); throw; } finally { NativeFunctions.CloseHandle(process); } return(new Connection(pipe)); }
public void Dispose() { Write(this.originalHead); NativeFunctions.VirtualProtectEx(this.process, this.patchHeap, (UIntPtr)this.heapSize, this.heapOldProtect, out _); Marshal.FreeHGlobal(this.patchHeap); }