Esempio n. 1
0
        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);
                }
            }
        }
Esempio n. 2
0
        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();
        }