コード例 #1
0
        // Core injection method that actually does all the work.
        public override IntPtr Inject(string dllPath, IntPtr hProcess)
        {
            ClearErrors();
            if (hProcess.IsNull() || hProcess.Compare(-1))
            {
                throw new ArgumentOutOfRangeException("hProcess", "Invalid process handle specified.");
            }

            try
            {
                IntPtr hModule = IntPtr.Zero;

                // Find the LoadLibraryW function address in the remote process
                IntPtr fnLoadLibraryW = WinAPI.GetProcAddress(WinAPI.GetModuleHandleA("kernel32.dll"), "LoadLibraryW");
                if (fnLoadLibraryW.IsNull())
                {
                    throw new Exception("Unable to locate the LoadLibraryW entry point");
                }

                // Create a wchar_t * in the remote process which points to the unicode version of the dll path.
                IntPtr pLib = WinAPI.CreateRemotePointer(hProcess, Encoding.Unicode.GetBytes(dllPath + "\0"), 0x04);
                if (pLib.IsNull())
                {
                    throw new InvalidOperationException("Failed to allocate memory in the remote process");
                }

                try
                {
                    // Call LoadLibraryW in the remote process by using CreateRemoteThread.
                    uint hMod = WinAPI.RunThread(hProcess, fnLoadLibraryW, (uint)pLib.ToInt32(), 10000);
                    if (hMod == uint.MaxValue)
                    {
                        throw new Exception("Error occurred when calling function in the remote process");
                    }
                    else if (hMod == 0)
                    {
                        throw new Exception("Failed to load module into remote process. Error code: " + WinAPI.GetLastErrorEx(hProcess).ToString());
                    }
                    else
                    {
                        hModule = Win32Ptr.Create(hMod);
                    }
                }
                finally
                {
                    // Cleanup in all cases.
                    WinAPI.VirtualFreeEx(hProcess, pLib, 0, 0x8000);
                }
                return(hModule);
            }
            catch (Exception e)
            {
                SetLastError(e);
                return(IntPtr.Zero);
            }
        }
コード例 #2
0
ファイル: CRTInjection.cs プロジェクト: sortaloc/DCNC-Tools
        public override IntPtr Inject(string dllPath, IntPtr hProcess)
        {
            this.ClearErrors();
            if (hProcess.IsNull() || hProcess.Compare(-1L))
            {
                throw new ArgumentOutOfRangeException("hProcess", "Invalid process handle specified.");
            }
            IntPtr result;

            try
            {
                IntPtr intPtr      = IntPtr.Zero;
                IntPtr procAddress = WinAPI.GetProcAddress(WinAPI.GetModuleHandleA("kernel32.dll"), "LoadLibraryW");
                if (procAddress.IsNull())
                {
                    throw new Exception("Unable to locate the LoadLibraryW entry point");
                }
                IntPtr intPtr2 = WinAPI.CreateRemotePointer(hProcess, Encoding.Unicode.GetBytes(dllPath + "\0"), 4);
                if (intPtr2.IsNull())
                {
                    throw new InvalidOperationException("Failed to allocate memory in the remote process");
                }
                try
                {
                    uint num = WinAPI.RunThread(hProcess, procAddress, (uint)intPtr2.ToInt32(), 10000);
                    if (num == 4294967295u)
                    {
                        throw new Exception("Error occurred when calling function in the remote process");
                    }
                    if (num == 0u)
                    {
                        throw new Exception("Failed to load module into remote process. Error code: " + WinAPI.GetLastErrorEx(hProcess).ToString());
                    }
                    intPtr = Win32Ptr.Create((long)((ulong)num));
                }
                finally
                {
                    WinAPI.VirtualFreeEx(hProcess, intPtr2, 0, 32768);
                }
                result = intPtr;
            }
            catch (Exception lastError)
            {
                this.SetLastError(lastError);
                result = IntPtr.Zero;
            }
            return(result);
        }
コード例 #3
0
        public override IntPtr Inject(string dllPath, IntPtr hProcess)
        {
            this.ClearErrors();
            if (hProcess.IsNull() || hProcess.Compare(-1L))
            {
                throw new ArgumentOutOfRangeException("hProcess", "Invalid process handle specified.");
            }
            try
            {
                IntPtr zero        = IntPtr.Zero;
                IntPtr procAddress = WinAPI.GetProcAddress(WinAPI.GetModuleHandleA("kernel32.dll"), "LoadLibraryW");
                if (procAddress.IsNull())
                {
                    throw new Exception("Unable to locate the LoadLibraryW entry point");
                }
                IntPtr ptr = WinAPI.CreateRemotePointer(hProcess, Encoding.Unicode.GetBytes(dllPath + "\0"), 4);
                if (ptr.IsNull())
                {
                    throw new InvalidOperationException("Failed to allocate memory in the remote process");
                }
                try
                {
                    uint num = WinAPI.RunThread(hProcess, procAddress, (uint)ptr.ToInt32(), 0x2710);
                    switch (num)
                    {
                    case uint.MaxValue:
                        throw new Exception("Error occurred when calling function in the remote process");

                    case 0:
                        throw new Exception("Failed to load module into remote process. Error code: " + WinAPI.GetLastErrorEx(hProcess).ToString());
                    }
                    zero = Win32Ptr.Create((long)num);
                }
                finally
                {
                    WinAPI.VirtualFreeEx(hProcess, ptr, 0, 0x8000);
                }
                return(zero);
            }
            catch (Exception exception)
            {
                this.SetLastError(exception);
                return(IntPtr.Zero);
            }
        }
コード例 #4
0
        public override IntPtr[] InjectAll(string[] dllPaths, IntPtr hProcess)
        {
            Exception exception;

            this.ClearErrors();
            try
            {
                if (hProcess.IsNull() || hProcess.Compare(-1L))
                {
                    throw new ArgumentException("Invalid process handle.", "hProcess");
                }
                int processId = WinAPI.GetProcessId(hProcess);
                if (processId == 0)
                {
                    throw new ArgumentException("Provided handle doesn't have sufficient permissions to inject", "hProcess");
                }
                Process processById = Process.GetProcessById(processId);
                if (processById.Threads.Count == 0)
                {
                    throw new Exception("Target process has no targetable threads to hijack.");
                }
                ProcessThread thread = SelectOptimalThread(processById);
                IntPtr        ptr    = WinAPI.OpenThread(0x1a, false, thread.Id);
                if (ptr.IsNull() || ptr.Compare(-1L))
                {
                    throw new Exception("Unable to obtain a handle for the remote thread.");
                }
                IntPtr   zero      = IntPtr.Zero;
                IntPtr   lpAddress = IntPtr.Zero;
                IntPtr   ptr4      = this.CreateMultiLoadStub(dllPaths, hProcess, out zero, 1);
                IntPtr[] ptrArray  = null;
                if (!ptr4.IsNull())
                {
                    if (WinAPI.SuspendThread(ptr) == uint.MaxValue)
                    {
                        throw new Exception("Unable to suspend the remote thread");
                    }
                    try
                    {
                        uint           lpNumberOfBytesRead = 0;
                        WinAPI.CONTEXT pContext            = new WinAPI.CONTEXT
                        {
                            ContextFlags = 0x10001
                        };
                        if (!WinAPI.GetThreadContext(ptr, ref pContext))
                        {
                            throw new InvalidOperationException("Cannot get the remote thread's context");
                        }
                        byte[] array = REDIRECT_STUB;
                        IntPtr ptr5  = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)array.Length, 0x3000, 0x40);
                        if (ptr5.IsNull())
                        {
                            throw new InvalidOperationException("Unable to allocate memory in the remote process.");
                        }
                        BitConverter.GetBytes(ptr4.Subtract(ptr5.Add(((long)7L))).ToInt32()).CopyTo(array, 3);
                        BitConverter.GetBytes((uint)(pContext.Eip - ((uint)ptr5.Add(((long)array.Length)).ToInt32()))).CopyTo(array, (int)(array.Length - 4));
                        if (!(WinAPI.WriteProcessMemory(hProcess, ptr5, array, array.Length, out lpNumberOfBytesRead) && (lpNumberOfBytesRead == array.Length)))
                        {
                            throw new InvalidOperationException("Unable to write stub to the remote process.");
                        }
                        pContext.Eip = (uint)ptr5.ToInt32();
                        WinAPI.SetThreadContext(ptr, ref pContext);
                    }
                    catch (Exception exception1)
                    {
                        exception = exception1;
                        this.SetLastError(exception);
                        ptrArray = null;
                        WinAPI.VirtualFreeEx(hProcess, zero, 0, 0x8000);
                        WinAPI.VirtualFreeEx(hProcess, ptr4, 0, 0x8000);
                        WinAPI.VirtualFreeEx(hProcess, lpAddress, 0, 0x8000);
                    }
                    WinAPI.ResumeThread(ptr);
                    if (this.GetLastError() == null)
                    {
                        Thread.Sleep(100);
                        ptrArray = new IntPtr[dllPaths.Length];
                        byte[] buffer2 = WinAPI.ReadRemoteMemory(hProcess, zero, ((uint)dllPaths.Length) << 2);
                        if (buffer2 != null)
                        {
                            for (int i = 0; i < ptrArray.Length; i++)
                            {
                                ptrArray[i] = Win32Ptr.Create((long)BitConverter.ToInt32(buffer2, i << 2));
                            }
                        }
                    }
                    WinAPI.CloseHandle(ptr);
                }
                return(ptrArray);
            }
            catch (Exception exception2)
            {
                exception = exception2;
                this.SetLastError(exception);
                return(null);
            }
        }
コード例 #5
0
 public override IntPtr[] InjectAll(string[] dllPaths, IntPtr hProcess)
 {
     this.ClearErrors();
     IntPtr[] result;
     try
     {
         if (hProcess.IsNull() || hProcess.Compare(-1L))
         {
             throw new ArgumentException("Invalid process handle.", "hProcess");
         }
         int processId = WinAPI.GetProcessId(hProcess);
         if (processId == 0)
         {
             throw new ArgumentException("Provided handle doesn't have sufficient permissions to inject", "hProcess");
         }
         Process processById = Process.GetProcessById(processId);
         if (processById.Threads.Count == 0)
         {
             throw new Exception("Target process has no targetable threads to hijack.");
         }
         ProcessThread processThread = ThreadHijack.SelectOptimalThread(processById);
         IntPtr        intPtr        = WinAPI.OpenThread(26u, false, processThread.Id);
         if (intPtr.IsNull() || intPtr.Compare(-1L))
         {
             throw new Exception("Unable to obtain a handle for the remote thread.");
         }
         IntPtr   zero    = IntPtr.Zero;
         IntPtr   zero2   = IntPtr.Zero;
         IntPtr   intPtr2 = this.CreateMultiLoadStub(dllPaths, hProcess, out zero, 1u);
         IntPtr[] array   = null;
         if (!intPtr2.IsNull())
         {
             if (WinAPI.SuspendThread(intPtr) == 4294967295u)
             {
                 throw new Exception("Unable to suspend the remote thread");
             }
             try
             {
                 uint           num     = 0u;
                 WinAPI.CONTEXT cONTEXT = default(WinAPI.CONTEXT);
                 cONTEXT.ContextFlags = 65537u;
                 if (!WinAPI.GetThreadContext(intPtr, ref cONTEXT))
                 {
                     throw new InvalidOperationException("Cannot get the remote thread's context");
                 }
                 byte[] rEDIRECT_STUB = ThreadHijack.REDIRECT_STUB;
                 IntPtr intPtr3       = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)rEDIRECT_STUB.Length, 12288, 64);
                 if (intPtr3.IsNull())
                 {
                     throw new InvalidOperationException("Unable to allocate memory in the remote process.");
                 }
                 BitConverter.GetBytes(intPtr2.Subtract(intPtr3.Add(7L)).ToInt32()).CopyTo(rEDIRECT_STUB, 3);
                 BitConverter.GetBytes((uint)((ulong)cONTEXT.Eip - (ulong)((long)intPtr3.Add((long)rEDIRECT_STUB.Length).ToInt32()))).CopyTo(rEDIRECT_STUB, rEDIRECT_STUB.Length - 4);
                 if (!WinAPI.WriteProcessMemory(hProcess, intPtr3, rEDIRECT_STUB, rEDIRECT_STUB.Length, out num) || num != (uint)rEDIRECT_STUB.Length)
                 {
                     throw new InvalidOperationException("Unable to write stub to the remote process.");
                 }
                 cONTEXT.Eip = (uint)intPtr3.ToInt32();
                 WinAPI.SetThreadContext(intPtr, ref cONTEXT);
             }
             catch (Exception lastError)
             {
                 this.SetLastError(lastError);
                 array = null;
                 WinAPI.VirtualFreeEx(hProcess, zero, 0, 32768);
                 WinAPI.VirtualFreeEx(hProcess, intPtr2, 0, 32768);
                 WinAPI.VirtualFreeEx(hProcess, zero2, 0, 32768);
             }
             WinAPI.ResumeThread(intPtr);
             if (this.GetLastError() == null)
             {
                 Thread.Sleep(100);
                 array = new IntPtr[dllPaths.Length];
                 byte[] array2 = WinAPI.ReadRemoteMemory(hProcess, zero, (uint)((uint)dllPaths.Length << 2));
                 if (array2 != null)
                 {
                     for (int i = 0; i < array.Length; i++)
                     {
                         array[i] = Win32Ptr.Create((long)BitConverter.ToInt32(array2, i << 2));
                     }
                 }
             }
             WinAPI.CloseHandle(intPtr);
         }
         result = array;
     }
     catch (Exception lastError2)
     {
         this.SetLastError(lastError2);
         result = null;
     }
     return(result);
 }
コード例 #6
0
        public override IntPtr[] InjectAll(string[] dllPaths, IntPtr hProcess)
        {
            ClearErrors();
            try
            {
                if (hProcess.IsNull() || hProcess.Compare(-1))
                {
                    throw new ArgumentException("Invalid process handle.", "hProcess");
                }

                int processId = WinAPI.GetProcessId(hProcess);
                if (processId == 0)
                {
                    throw new ArgumentException("Provided handle doesn't have sufficient permissions to inject", "hProcess");
                }

                Process target = Process.GetProcessById(processId);
                if (target.Threads.Count == 0)
                {
                    throw new Exception("Target process has no targetable threads to hijack.");
                }

                //open a handle to the remote thread to allow for thread operations.
                ProcessThread thread  = SelectOptimalThread(target);
                IntPtr        hThread = WinAPI.OpenThread(0x001A, false, thread.Id);

                if (hThread.IsNull() || hThread.Compare(-1))
                {
                    throw new Exception("Unable to obtain a handle for the remote thread.");
                }

                IntPtr pModules  = IntPtr.Zero;
                IntPtr pRedirect = IntPtr.Zero;
                // use the generic multiload stub to load the paths.
                // call this stub from the REDIRECT_STUB.
                IntPtr   pStub   = CreateMultiLoadStub(dllPaths, hProcess, out pModules, 1);
                IntPtr[] modules = null;

                if (!pStub.IsNull())
                {
                    if (WinAPI.SuspendThread(hThread) == uint.MaxValue)
                    {
                        throw new Exception("Unable to suspend the remote thread");
                    }
                    //enter a new try/catch block to ensure the suspended thread is resumed, no matter if we fail somewhere else.
                    try
                    {
                        uint           nbytes = 0;
                        WinAPI.CONTEXT ctx    = default(WinAPI.CONTEXT);
                        ctx.ContextFlags = 0x10001U; // CONTEXT_CONTROL flag. So that we get back the EIP value of the suspended thread.
                        if (!WinAPI.GetThreadContext(hThread, ref ctx))
                        {
                            throw new InvalidOperationException("Cannot get the remote thread's context");
                        }

                        byte[] stub   = REDIRECT_STUB;
                        IntPtr pAlloc = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)stub.Length, 0x1000 | 0x2000, 0x40);
                        if (pAlloc.IsNull())
                        {
                            throw new InvalidOperationException("Unable to allocate memory in the remote process.");
                        }

                        //patch the EIP value and the Stub address for the redirection stub before commiting it to the remote process.
                        BitConverter.GetBytes(pStub.Subtract(pAlloc.Add(7)).ToInt32()).CopyTo(stub, 3);
                        BitConverter.GetBytes((uint)(ctx.Eip - pAlloc.Add(stub.Length).ToInt32())).CopyTo(stub, stub.Length - 4);

                        if (!WinAPI.WriteProcessMemory(hProcess, pAlloc, stub, stub.Length, out nbytes) || nbytes != (uint)stub.Length)
                        {
                            throw new InvalidOperationException("Unable to write stub to the remote process.");
                        }

                        ctx.Eip = (uint)pAlloc.ToInt32(); // Set the entry point for the thread to the redirection stub and resume the thread.
                        WinAPI.SetThreadContext(hThread, ref ctx);
                    }
                    catch (Exception e)
                    {
                        SetLastError(e);
                        modules = null;
                        WinAPI.VirtualFreeEx(hProcess, pModules, 0, 0x8000);
                        WinAPI.VirtualFreeEx(hProcess, pStub, 0, 0x8000);
                        WinAPI.VirtualFreeEx(hProcess, pRedirect, 0, 0x8000);
                    }

                    WinAPI.ResumeThread(hThread);
                    if (GetLastError() == null)
                    {
                        System.Threading.Thread.Sleep(100);
                        modules = new IntPtr[dllPaths.Length];
                        byte[] rawHandles = WinAPI.ReadRemoteMemory(hProcess, pModules, (uint)dllPaths.Length << 2);

                        if (rawHandles != null)
                        {
                            for (int i = 0; i < modules.Length; i++)
                            {
                                modules[i] = Win32Ptr.Create(BitConverter.ToInt32(rawHandles, i << 2));
                            }
                        }
                    }
                    // deliberately didn't clean up the remote memory here. Unfortunately there's no solid way
                    // to ensure the function stub has been scheduled by the operating system. It may not even happen for
                    // ages, or something else may block the thread. When the stub eventually is executes and returns, the reset
                    // of the stub needs to still be there in order for the function to successfully return, otherwise the process just crashes
                    // and we lose the distinct possibility that the injection was successful.
                    WinAPI.CloseHandle(hThread);
                }
                return(modules);
            }
            catch (Exception e)
            {
                SetLastError(e);
                return(null);
            }
        }