public static InjectedModule InjectLibrary(this Process proc, string modulePath, string moduleName = null) { if (!File.Exists(modulePath)) { throw new FileNotFoundException("Unable to find the specified module", modulePath); } modulePath = Path.GetFullPath(modulePath); if (string.IsNullOrEmpty(moduleName)) { moduleName = Path.GetFileName(modulePath) ?? modulePath; } var manager = ProcessMemoryManager.ForProcess(proc); if (manager.InjectedModules.ContainsKey(moduleName)) { throw new ArgumentException("Module with this name has already been injected", "moduleName"); } // unmanaged resources that need to be freed var pLibRemote = IntPtr.Zero; var hThread = IntPtr.Zero; var pLibFullPath = Marshal.StringToHGlobalUni(modulePath); try { var sizeUni = Encoding.Unicode.GetByteCount(modulePath); // Handle to Kernel32.dll and LoadLibraryW var hKernel32 = Imports.GetModuleHandle("Kernel32"); if (hKernel32 == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } var hLoadLib = Imports.GetProcAddress(hKernel32, "LoadLibraryW"); if (hLoadLib == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // allocate memory to the local process for libFullPath pLibRemote = Imports.VirtualAllocEx(proc.GetHandle(), IntPtr.Zero, (uint)sizeUni, AllocationType.Commit, MemoryProtection.ReadWrite); if (pLibRemote == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } int bytesWritten; if (!Imports.WriteProcessMemory(proc.GetHandle(), pLibRemote, pLibFullPath, (uint)sizeUni, out bytesWritten) || bytesWritten != sizeUni) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // load dll via call to LoadLibrary using CreateRemoteThread hThread = Imports.CreateRemoteThread(proc.GetHandle(), IntPtr.Zero, 0, hLoadLib, pLibRemote, 0, IntPtr.Zero); if (hThread == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (Imports.WaitForSingleObject(hThread, (uint)ThreadWaitValue.Infinite) != (uint)ThreadWaitValue.Object0) { throw new Win32Exception(Marshal.GetLastWin32Error()); } IntPtr hLibModule = IntPtr.Zero; // get address of loaded module foreach (ProcessModule mod in proc.Modules) { if (mod.FileName == modulePath) { hLibModule = mod.BaseAddress; break; } } if (hLibModule == IntPtr.Zero) { throw new Exception("Module is not injected anymore and/or got unloaded."); } var module = new InjectedModule(hLibModule, moduleName, modulePath, proc); manager.InjectedModules[moduleName] = module; return(new InjectedModule(hLibModule, moduleName, modulePath, proc)); } finally { Marshal.FreeHGlobal(pLibFullPath); if (hThread != IntPtr.Zero) { Imports.CloseHandle(hThread); } if (pLibRemote != IntPtr.Zero) { Imports.VirtualFreeEx(proc.GetHandle(), pLibRemote, 0, AllocationType.Release); } } }
static void Main(string[] args) { Console.WriteLine("Welcome to CsharpInjector demo for DllExport library"); Console.WriteLine("Just a small reminder - you cannot inject to every process using this injector"); Console.WriteLine("Be sure to inject only to processes that match process configuration you use for this project (x86, x64)"); Console.Write("Put in name (without .exe) or id of the process you want to inject in: "); string read = Console.ReadLine(); RemoteProcessHandle processHandle; if (int.TryParse(read, out int processId)) { processHandle = Injector.GetRemoteProcess(processId); } else { processHandle = Injector.GetRemoteProcess(read); } if (processHandle == null) { Console.WriteLine("Process not found."); Console.Read(); return; } string dllPath = "CppLibrary.dll"; if (!File.Exists(dllPath)) { Console.WriteLine("Dll to inject not found."); } InjectedModule injectedModule = processHandle.Inject(dllPath); Console.WriteLine("Module injected"); Console.WriteLine("Calling Main function to alloc console"); FunctionResult result = injectedModule.ExecuteFunction("Main"); int mainResult = result.To <int>(); Console.WriteLine($"Result from main: {mainResult} (should be 1)"); Console.WriteLine($"Sleeping for 1 second"); Thread.Sleep(1000); // Execute addition function and get its params Console.WriteLine("Calling Addition with params of 10 and 5; Expected result: 15"); result = injectedModule.ExecuteFunction("Add", new AddParams { First = 5, Second = 10 }); int additionResult = result.To <int>(); Console.WriteLine("Result: " + additionResult); injectedModule.ExecuteFunction("MyFunction", new MyFunctionParams { Param = "Injected string!", Number = 1000 }); injectedModule.Process.Close(); Console.ReadLine(); }