示例#1
0
        public override bool Unload(IntPtr hModule, IntPtr hProcess)
        {
            // Unloading a manually mapped file is fairly straightforward. There is no need to call FreeLibrary or anything
            // because the file was never actually injected using LoadLibrary and doesn't need to clear any PEB entries etc.
            // basically just call the Entry Point again with DLL_PROCESS_DETACH flag and not-null for the lpReserved parameter
            // and then VirtualFree the remote memory.
            ClearErrors();

            if (hModule.IsNull())
            {
                throw new ArgumentNullException("hModule", "Invalid module handle");
            }

            if (hProcess.IsNull() || hProcess.Compare(-1))
            {
                throw new ArgumentException("Invalid process handle.", "hProcess");
            }

            IntPtr pStub  = IntPtr.Zero;
            uint   nBytes = 0;

            try
            {
                uint entry = FindEntryPoint(hProcess, hModule);
                if (entry != 0)
                {
                    var stub = (byte[])DLLMAIN_STUB.Clone();
                    BitConverter.GetBytes(hModule.ToInt32()).CopyTo(stub, 0x0B);
                    BitConverter.GetBytes((uint)0).CopyTo(stub, 0x06);
                    BitConverter.GetBytes((uint)1000).CopyTo(stub, 0x01);

                    pStub = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)DLLMAIN_STUB.Length, 0x1000 | 0x2000, 0x40);
                    if (pStub.IsNull() || (!WinAPI.WriteProcessMemory(hProcess, pStub, stub, stub.Length, out nBytes) || nBytes != (uint)stub.Length))
                    {
                        throw new InvalidOperationException("Unable to write stub to the remote process.");
                    }

                    IntPtr hStubThread = WinAPI.CreateRemoteThread(hProcess, 0, 0, pStub, (uint)hModule.Add(entry).ToInt32(), 0, 0);
                    if (WinAPI.WaitForSingleObject(hStubThread, 5000) == 0x0L)
                    {
                        WinAPI.VirtualFreeEx(hProcess, pStub, 0, 0x8000);
                        WinAPI.CloseHandle(hStubThread);
                        return(WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000));
                    }
                    return(false);
                }
                else
                {
                    return(WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000));
                }
            }
            catch (Exception e)
            {
                SetLastError(e);
                return(false);
            }
        }
示例#2
0
        // Most efficient version, this will be the work horse.
        private static IntPtr MapModule(PortableExecutable image, IntPtr hProcess, bool preserveHeaders = false)
        {
            if (hProcess.IsNull() || hProcess.Compare(-1))
            {
                throw new ArgumentException("Invalid process handle.", "hProcess");
            }

            if (image == null)
            {
                throw new ArgumentException("Cannot map a non-existant PE Image.", "image");
            }

            int processId = WinAPI.GetProcessId(hProcess);

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

            IntPtr hModule = IntPtr.Zero;
            IntPtr pStub   = IntPtr.Zero;
            uint   nBytes  = 0;

            try
            {
                //allocate memory for the image to load into the remote process.
                hModule = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, image.NTHeader.OptionalHeader.SizeOfImage, 0x1000 | 0x2000, 0x04);
                if (hModule.IsNull())
                {
                    throw new InvalidOperationException("Unable to allocate memory in the remote process.");
                }

                PatchRelocations(image, hModule);
                LoadDependencies(image, hProcess, processId);
                PatchImports(image, hProcess, processId);

                if (preserveHeaders)
                {
                    long   szHeader = (image.DOSHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER)) + sizeof(uint) + image.NTHeader.FileHeader.SizeOfOptionalHeader);
                    byte[] header   = new byte[szHeader];
                    if (image.Read(0, SeekOrigin.Begin, header))
                    {
                        WinAPI.WriteProcessMemory(hProcess, hModule, header, header.Length, out nBytes);
                    }
                }

                MapSections(image, hProcess, hModule);

                // some modules don't have an entry point and are purely libraries, mapping them and keeping the handle is just fine
                // an unlikely scenario with forced injection, but you never know.
                if (image.NTHeader.OptionalHeader.AddressOfEntryPoint > 0)
                {
                    var stub = (byte[])DLLMAIN_STUB.Clone();
                    BitConverter.GetBytes(hModule.ToInt32()).CopyTo(stub, 0x0B);

                    pStub = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)DLLMAIN_STUB.Length, 0x1000 | 0x2000, 0x40);
                    if (pStub.IsNull() || (!WinAPI.WriteProcessMemory(hProcess, pStub, stub, stub.Length, out nBytes) || nBytes != (uint)stub.Length))
                    {
                        throw new InvalidOperationException("Unable to write stub to the remote process.");
                    }

                    IntPtr hStubThread = WinAPI.CreateRemoteThread(hProcess, 0, 0, pStub, (uint)(hModule.Add(image.NTHeader.OptionalHeader.AddressOfEntryPoint).ToInt32()), 0, 0);
                    if (WinAPI.WaitForSingleObject(hStubThread, 5000) == 0x0L)
                    {
                        WinAPI.GetExitCodeThread(hStubThread, out nBytes);
                        if (nBytes == 0)
                        {
                            WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000);
                            throw new Exception("Entry method of module reported a failure " + Marshal.GetLastWin32Error().ToString());
                        }
                        WinAPI.VirtualFreeEx(hProcess, pStub, 0, 0x8000);
                        WinAPI.CloseHandle(hStubThread);
                    }
                }
            }
            catch (Exception e)
            {
                if (!hModule.IsNull())
                {
                    WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000);
                }
                if (!pStub.IsNull())
                {
                    WinAPI.VirtualFreeEx(hProcess, hModule, 0, 0x8000);
                }

                hModule = IntPtr.Zero;
                throw e;
            }
            return(hModule);
        }