private static void PatchRelocations(JLibrary.PortableExecutable.PortableExecutable image, IntPtr pAlloc)
        {
            IMAGE_DATA_DIRECTORY image_data_directory = image.NTHeader.OptionalHeader.DataDirectory[5];

            if (image_data_directory.Size > 0)
            {
                IMAGE_BASE_RELOCATION image_base_relocation;
                uint num        = 0;
                uint num2       = ((uint)pAlloc.ToInt32()) - image.NTHeader.OptionalHeader.ImageBase;
                uint ptrFromRVA = image.GetPtrFromRVA(image_data_directory.VirtualAddress);
                uint num4       = (uint)Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));
                while ((num < image_data_directory.Size) && image.Read <IMAGE_BASE_RELOCATION>((long)ptrFromRVA, SeekOrigin.Begin, out image_base_relocation))
                {
                    int  num5 = (int)((image_base_relocation.SizeOfBlock - num4) / 2);
                    uint num6 = image.GetPtrFromRVA(image_base_relocation.VirtualAddress);
                    for (int i = 0; i < num5; i++)
                    {
                        ushort num7;
                        if (image.Read <ushort>((ptrFromRVA + num4) + (i << 1), SeekOrigin.Begin, out num7) && (((num7 >> 12) & 3) != 0))
                        {
                            uint num8;
                            uint num10 = num6 + ((uint)(num7 & 0xfff));
                            if (!image.Read <uint>((long)num10, SeekOrigin.Begin, out num8))
                            {
                                throw image.GetLastError();
                            }
                            image.Write <uint>(-4L, SeekOrigin.Current, num8 + num2);
                        }
                    }
                    num        += image_base_relocation.SizeOfBlock;
                    ptrFromRVA += image_base_relocation.SizeOfBlock;
                }
            }
        }
Пример #2
0
 public ResourceDirectory(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root) : base(owner, entry, named, root)
 {
     if (!owner.Read <IMAGE_RESOURCE_DIRECTORY>((long)((ulong)(root + (entry.SubdirectoryRva ^ 2147483648u))), SeekOrigin.Begin, out this._base))
     {
         throw owner.GetLastError();
     }
 }
Пример #3
0
 public ResourceFile(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root) : base(owner, entry, named, root)
 {
     if (!owner.Read <IMAGE_RESOURCE_DATA_ENTRY>((long)((ulong)(this._root + entry.DataEntryRva)), SeekOrigin.Begin, out this._base))
     {
         throw owner.GetLastError();
     }
 }
 public ResourceDirectory(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root)
     : base(owner, entry, named, root)
 {
     if (!owner.Read(root + (entry.SubdirectoryRva ^ 0x80000000), System.IO.SeekOrigin.Begin, out this._base))
     {
         throw owner.GetLastError();
     }
 }
Пример #5
0
        public virtual IntPtr Inject(JLibrary.PortableExecutable.PortableExecutable image, int processId)
        {
            this.ClearErrors();
            IntPtr hProcess = WinAPI.OpenProcess(0x43a, false, processId);
            IntPtr ptr2     = this.Inject(image, hProcess);

            WinAPI.CloseHandle(hProcess);
            return(ptr2);
        }
        private static void PatchImports(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess, int processId)
        {
            string lpBuffer = string.Empty;
            string str2     = string.Empty;

            foreach (IMAGE_IMPORT_DESCRIPTOR image_import_descriptor in image.EnumImports())
            {
                if (image.ReadString((long)image.GetPtrFromRVA(image_import_descriptor.Name), SeekOrigin.Begin, out lpBuffer, -1, null))
                {
                    IMAGE_THUNK_DATA image_thunk_data;
                    IntPtr           zero = IntPtr.Zero;
                    zero = GetRemoteModuleHandle(lpBuffer, processId);
                    if (zero.IsNull())
                    {
                        throw new FileNotFoundException(string.Format("Unable to load dependent module '{0}'.", lpBuffer));
                    }
                    uint ptrFromRVA = image.GetPtrFromRVA(image_import_descriptor.FirstThunkPtr);
                    uint num2       = (uint)Marshal.SizeOf(typeof(IMAGE_THUNK_DATA));
                    while (image.Read <IMAGE_THUNK_DATA>((long)ptrFromRVA, SeekOrigin.Begin, out image_thunk_data) && (image_thunk_data.u1.AddressOfData > 0))
                    {
                        IntPtr hModule    = IntPtr.Zero;
                        object lpProcName = null;
                        if ((image_thunk_data.u1.Ordinal & 0x80000000) == 0)
                        {
                            if (!image.ReadString((long)(image.GetPtrFromRVA(image_thunk_data.u1.AddressOfData) + 2), SeekOrigin.Begin, out str2, -1, null))
                            {
                                throw image.GetLastError();
                            }
                            lpProcName = str2;
                        }
                        else
                        {
                            lpProcName = (ushort)(image_thunk_data.u1.Ordinal & 0xffff);
                        }
                        if (!(hModule = WinAPI.GetModuleHandleA(lpBuffer)).IsNull())
                        {
                            IntPtr ptr = lpProcName.GetType().Equals(typeof(string)) ? WinAPI.GetProcAddress(hModule, (string)lpProcName) : WinAPI.GetProcAddress(hModule, (uint)(((ushort)lpProcName) & 0xffff));
                            if (!ptr.IsNull())
                            {
                                hModule = zero.Add((long)ptr.Subtract(((long)hModule.ToInt32())).ToInt32());
                            }
                        }
                        else
                        {
                            hModule = WinAPI.GetProcAddressEx(hProcess, zero, lpProcName);
                        }
                        if (hModule.IsNull())
                        {
                            throw new EntryPointNotFoundException(string.Format("Unable to locate imported function '{0}' from module '{1}' in the remote process.", str2, lpBuffer));
                        }
                        image.Write <int>((long)ptrFromRVA, SeekOrigin.Begin, hModule.ToInt32());
                        ptrFromRVA += num2;
                    }
                }
            }
        }
Пример #7
0
 public override IntPtr Inject(PortableExecutable image, IntPtr hProcess)
 {
     ClearErrors();
     try
     {
         return MapModule(Utils.DeepClone(image), hProcess, true);
     }
     catch (Exception e)
     {
         SetLastError(e);
         return IntPtr.Zero;
     }
 }
 public override IntPtr Inject(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess)
 {
     this.ClearErrors();
     try
     {
         return(MapModule(Utils.DeepClone <JLibrary.PortableExecutable.PortableExecutable>(image), hProcess, true));
     }
     catch (Exception exception)
     {
         this.SetLastError(exception);
         return(IntPtr.Zero);
     }
 }
Пример #9
0
 public override IntPtr Inject(string dllPath, IntPtr hProcess)
 {
     ClearErrors();
     try
     {
         using (PortableExecutable img = new PortableExecutable(dllPath))
             return Inject(img, hProcess);
     }
     catch (Exception e)
     {
         SetLastError(e);
         return IntPtr.Zero;
     }
 }
        public ResourceWalker(PortableExecutable image)
        {
            IMAGE_DATA_DIRECTORY rsrcDir = image.NTHeader.OptionalHeader.DataDirectory[(int)DATA_DIRECTORIES.ResourceTable];
            IMAGE_RESOURCE_DIRECTORY rootDir;
            uint rootAddr = 0;

            if (rsrcDir.VirtualAddress > 0 && rsrcDir.Size > 0)
            {
                if (image.Read((rootAddr = image.GetPtrFromRVA(rsrcDir.VirtualAddress)), System.IO.SeekOrigin.Begin, out rootDir))
                    this.Root = new ResourceDirectory(image, new IMAGE_RESOURCE_DIRECTORY_ENTRY() { SubdirectoryRva = 0x80000000 }, false, rootAddr);
                else
                    throw image.GetLastError();
            }
        }
Пример #11
0
 private static void MapSections(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess, IntPtr pModule)
 {
     foreach (IMAGE_SECTION_HEADER image_section_header in image.EnumSectionHeaders())
     {
         byte[] buffer = new byte[image_section_header.SizeOfRawData];
         if (!image.Read((long)image_section_header.PointerToRawData, SeekOrigin.Begin, buffer))
         {
             throw image.GetLastError();
         }
         if ((image_section_header.Characteristics & 0x2000000) == 0)
         {
             uint num;
             WinAPI.WriteProcessMemory(hProcess, pModule.Add((long)image_section_header.VirtualAddress), buffer, buffer.Length, out num);
             IntPtr lpAddress = pModule.Add((long)image_section_header.VirtualAddress);
             WinAPI.VirtualProtectEx(hProcess, lpAddress, image_section_header.SizeOfRawData, image_section_header.Characteristics & 0xffffff, out num);
         }
     }
 }
        public override IntPtr Inject(PortableExecutable dll, IntPtr hProcess)
        {
            //same as above, write the temp file and defer to the other Inject methods.
            ClearErrors();
            string path = Utils.WriteTempData(dll.ToArray());
            IntPtr hModule = IntPtr.Zero;
            if (!string.IsNullOrEmpty(path))
            {
                hModule = Inject(path, hProcess);
                try
                {
                    System.IO.File.Delete(path);
                }
                catch { /* nom nom nom */ }

            }
            return hModule;
        }
Пример #13
0
        public void inject(int pID, Byte[] dllbytes)
        {
            InjectionMethod method = InjectionMethod.Create(InjectionMethodType.Standard); //InjectionMethodType.Standard //InjectionMethodType.ManualMap //InjectionMethodType.ThreadHijack
            IntPtr          zero   = IntPtr.Zero;

            using (PortableExecutable.PortableExecutable executable = new PortableExecutable.PortableExecutable(dllbytes))
            {
                zero = method.Inject(executable, pID);
            }
            if (zero != IntPtr.Zero)
            {
                //BAIL HERE - ERROR
            }
            else if (method.GetLastError() != null)
            {
                //ERROR OCCURED
            }
            //SUCCESS
        }
Пример #14
0
        private static byte[] ExtractManifest(JLibrary.PortableExecutable.PortableExecutable image)
        {
            byte[]         data   = null;
            ResourceWalker walker = new ResourceWalker(image);

            ResourceWalker.ResourceDirectory directory = null;
            for (int i = 0; (i < walker.Root.Directories.Length) && (directory == null); i++)
            {
                if (walker.Root.Directories[i].Id == 0x18L)
                {
                    directory = walker.Root.Directories[i];
                }
            }
            if (((directory != null) && (directory.Directories.Length > 0)) && (IsManifestResource(directory.Directories[0].Id) && (directory.Directories[0].Files.Length == 1)))
            {
                data = directory.Directories[0].Files[0].GetData();
            }
            return(data);
        }
Пример #15
0
        public override IntPtr Inject(JLibrary.PortableExecutable.PortableExecutable dll, IntPtr hProcess)
        {
            this.ClearErrors();
            string str  = Utils.WriteTempData(dll.ToArray());
            IntPtr zero = IntPtr.Zero;

            if (!string.IsNullOrEmpty(str))
            {
                zero = this.Inject(str, hProcess);
                try
                {
                    File.Delete(str);
                }
                catch
                {
                }
            }
            return(zero);
        }
Пример #16
0
        public override IntPtr Inject(string dllPath, IntPtr hProcess)
        {
            IntPtr zero;

            this.ClearErrors();
            try
            {
                using (JLibrary.PortableExecutable.PortableExecutable executable = new JLibrary.PortableExecutable.PortableExecutable(dllPath))
                {
                    zero = this.Inject(executable, hProcess);
                }
            }
            catch (Exception exception)
            {
                this.SetLastError(exception);
                zero = IntPtr.Zero;
            }
            return(zero);
        }
            public ResourceObject(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root)
            {
                this._owner = owner;
                this._entry = entry;
                this.IsNamedResource = named;
                if (named)
                {
                    ushort len = 0;
                    if (owner.Read(root + (entry.NameRva & 0x7FFFFFFF), System.IO.SeekOrigin.Begin, out len))
                    {
                        byte[] unicodeBuffer = new byte[len << 1]; //each unicode character is 2 bytes wide
                        if (owner.Read(0, System.IO.SeekOrigin.Current, unicodeBuffer))
                            this._name = Encoding.Unicode.GetString(unicodeBuffer);
                    }

                    if (_name == null)
                        throw owner.GetLastError();
                }
                this._root = root;
            }
Пример #18
0
        public ResourceWalker(PortableExecutable image)
        {
            IMAGE_DATA_DIRECTORY iMAGE_DATA_DIRECTORY = image.NTHeader.OptionalHeader.DataDirectory[2];

            if (iMAGE_DATA_DIRECTORY.VirtualAddress <= 0u || iMAGE_DATA_DIRECTORY.Size <= 0u)
            {
                return;
            }
            uint ptrFromRVA;
            IMAGE_RESOURCE_DIRECTORY iMAGE_RESOURCE_DIRECTORY;

            if (image.Read <IMAGE_RESOURCE_DIRECTORY>((long)((ulong)(ptrFromRVA = image.GetPtrFromRVA(iMAGE_DATA_DIRECTORY.VirtualAddress))), SeekOrigin.Begin, out iMAGE_RESOURCE_DIRECTORY))
            {
                this.Root = new ResourceWalker.ResourceDirectory(image, new IMAGE_RESOURCE_DIRECTORY_ENTRY
                {
                    SubdirectoryRva = 2147483648u
                }, false, ptrFromRVA);
                return;
            }
            throw image.GetLastError();
        }
        public ResourceWalker(PortableExecutable image)
        {
            IMAGE_DATA_DIRECTORY     rsrcDir = image.NTHeader.OptionalHeader.DataDirectory[(int)DATA_DIRECTORIES.ResourceTable];
            IMAGE_RESOURCE_DIRECTORY rootDir;
            uint rootAddr = 0;

            if (rsrcDir.VirtualAddress > 0 && rsrcDir.Size > 0)
            {
                if (image.Read((rootAddr = image.GetPtrFromRVA(rsrcDir.VirtualAddress)), System.IO.SeekOrigin.Begin, out rootDir))
                {
                    this.Root = new ResourceDirectory(image, new IMAGE_RESOURCE_DIRECTORY_ENTRY()
                    {
                        SubdirectoryRva = 0x80000000
                    }, false, rootAddr);
                }
                else
                {
                    throw image.GetLastError();
                }
            }
        }
Пример #20
0
 public ResourceObject(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root)
 {
     this._owner          = owner;
     this._entry          = entry;
     this.IsNamedResource = named;
     if (named)
     {
         ushort num = 0;
         if (owner.Read <ushort>((long)((ulong)(root + (entry.NameRva & 2147483647u))), SeekOrigin.Begin, out num))
         {
             byte[] array = new byte[(int)num << 1];
             if (owner.Read(0L, SeekOrigin.Current, array))
             {
                 this._name = Encoding.Unicode.GetString(array);
             }
         }
         if (this._name == null)
         {
             throw owner.GetLastError();
         }
     }
     this._root = root;
 }
            public ResourceObject(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root)
            {
                this._owner          = owner;
                this._entry          = entry;
                this.IsNamedResource = named;
                if (named)
                {
                    ushort len = 0;
                    if (owner.Read(root + (entry.NameRva & 0x7FFFFFFF), System.IO.SeekOrigin.Begin, out len))
                    {
                        byte[] unicodeBuffer = new byte[len << 1]; //each unicode character is 2 bytes wide
                        if (owner.Read(0, System.IO.SeekOrigin.Current, unicodeBuffer))
                        {
                            this._name = Encoding.Unicode.GetString(unicodeBuffer);
                        }
                    }

                    if (_name == null)
                    {
                        throw owner.GetLastError();
                    }
                }
                this._root = root;
            }
 public ResourceDirectory(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root)
     : base(owner, entry, named, root)
 {
     if (!owner.Read(root + (entry.SubdirectoryRva ^ 0x80000000), System.IO.SeekOrigin.Begin, out this._base))
         throw owner.GetLastError();
 }
Пример #23
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; 
        }
 /// <summary>
 /// Inject an existing in-memory PortableExecutable image into a process using a valid existing process handle
 /// </summary>
 /// <param name="image">Any valid existing PortableExecutable instance</param>
 /// <param name="hProcess">Handle to the remote process</param>
 /// <returns>A valid module handle if the function is successful, or IntPtr.Zero otherwise</returns>
 public abstract IntPtr Inject(PortableExecutable image, IntPtr hProcess);
 /// <summary>
 /// Inject a collection of PortableExecutable images into a process using a unique process id as an identifier
 /// </summary>
 /// <param name="images">An array listing which PortableExecutable instances to inject</param>
 /// <param name="processId">Unique process identifier</param>
 /// <returns>An array of the same length as the 'images' parameter containing the module handles for each image, or null if the method failed. Call <see cref="GetLastError"/> for more information</returns>
 public virtual IntPtr[] InjectAll(PortableExecutable[] images, int processId)
 {
     ClearErrors();
     IntPtr hProcess = WinAPI.OpenProcess(0x043A, false, processId);
     IntPtr[] hModules = InjectAll(images, hProcess);
     WinAPI.CloseHandle(hProcess);
     return hModules;
 }
 /// <summary>
 /// Inject a collection of PortableExecutable images into a process using a valid existing process handle
 /// </summary>
 /// <param name="images">An array listing which PortableExecutable instances to inject</param>
 /// <param name="hProcess">Handle to the remote process</param>
 /// <returns>An array of the same length as the 'images' parameter containing the module handles for each image</returns>
 public abstract IntPtr[] InjectAll(PortableExecutable[] images, IntPtr hProcess);
 /// <summary>
 /// Inject an existing in-memory PortableExecutable image into a process using a unique process id as an identifier
 /// </summary>
 /// <param name="image">Any valid existing PortableExecutable instance</param>
 /// <param name="processId">Unique process identifier</param>
 /// <returns>A valid module handle if the function is successful, or IntPtr.Zero otherwise</returns>
 public virtual IntPtr Inject(PortableExecutable image, int processId)
 {
     ClearErrors();
     IntPtr hProcess = WinAPI.OpenProcess(0x043A, false, processId);
     IntPtr hModule = Inject(image, hProcess);
     WinAPI.CloseHandle(hProcess);
     return hModule;
 }
Пример #28
0
        /*
         * Handles loading of all dependent modules. Iterates the IAT entries and attempts to load (using LoadLibrary) all 
         * of the necessary modules for the main module to function. The manifest is extracted and activation contexts used to
         * ensure correct loading of Side-By-Side dependencies.
         */
        private static bool LoadDependencies(PortableExecutable image, IntPtr hProcess, int processId)
        {
            List<string> neededDependencies = new List<string>();
            string curdep = string.Empty;
            bool success = false;

            foreach (var desc in image.EnumImports())
            {
                if (image.ReadString(image.GetPtrFromRVA(desc.Name), SeekOrigin.Begin, out curdep) && !string.IsNullOrEmpty(curdep))
                {
                    if (GetRemoteModuleHandle(curdep, processId).IsNull())
                        neededDependencies.Add(curdep);
                }
            }

            if (neededDependencies.Count > 0) //do we actually need to load any new modules?
            {
                byte[] bManifest = ExtractManifest(image);
                string pathManifest = string.Empty;

                if (bManifest == null) // no internal manifest, may be an external manifest or none at all?
                {
                    if (!string.IsNullOrEmpty(image.FileLocation) && File.Exists(Path.Combine(Path.GetDirectoryName(image.FileLocation), Path.GetFileName(image.FileLocation) + ".manifest")))
                    {
                        pathManifest = Path.Combine(Path.GetDirectoryName(image.FileLocation), Path.GetFileName(image.FileLocation) + ".manifest");
                    }
                    else // no internal or external manifest, presume no side-by-side dependencies.
                    {
                        var standard = InjectionMethod.Create(InjectionMethodType.Standard);
                        var results = standard.InjectAll(neededDependencies.ToArray(), hProcess);

                        foreach (var result in results)
                            if (result.IsNull())
                                return false; // failed to inject a dependecy, abort mission.

                        return true; // done loading dependencies.
                    }
                }
                else
                {
                    pathManifest = Utils.WriteTempData(bManifest);
                }

                if (string.IsNullOrEmpty(pathManifest))
                    return false;

                IntPtr pResolverStub = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)RESOLVER_STUB.Length, 0x1000 | 0x2000, 0x40);
                IntPtr pManifest = WinAPI.CreateRemotePointer(hProcess, Encoding.ASCII.GetBytes(pathManifest + "\0"), 0x04);
                IntPtr pModules = WinAPI.CreateRemotePointer(hProcess, Encoding.ASCII.GetBytes(string.Join("\0", neededDependencies.ToArray()) + "\0"), 0x04);

                if (!pResolverStub.IsNull())
                {
                    var resolverStub = (byte[])RESOLVER_STUB.Clone();
                    uint nBytes = 0;

                    // Call patching. Patch the empty function addresses with the runtime addresses.
                    BitConverter.GetBytes(FN_CREATEACTCTXA.Subtract(pResolverStub.Add(0x3F)).ToInt32()).CopyTo(resolverStub, 0x3B);
                    BitConverter.GetBytes(FN_ACTIVATEACTCTX.Subtract(pResolverStub.Add(0x58)).ToInt32()).CopyTo(resolverStub, 0x54);
                    BitConverter.GetBytes(FN_GETMODULEHANDLEA.Subtract(pResolverStub.Add(0x84)).ToInt32()).CopyTo(resolverStub, 0x80);
                    BitConverter.GetBytes(FN_LOADLIBRARYA.Subtract(pResolverStub.Add(0x92)).ToInt32()).CopyTo(resolverStub, 0x8E);
                    BitConverter.GetBytes(FN_DEACTIVATEACTCTX.Subtract(pResolverStub.Add(0xC8)).ToInt32()).CopyTo(resolverStub, 0xC4);
                    BitConverter.GetBytes(FN_RELEASEACTCTX.Subtract(pResolverStub.Add(0xD1)).ToInt32()).CopyTo(resolverStub, 0xCD);

                    // Parameter patching
                    BitConverter.GetBytes(pManifest.ToInt32()).CopyTo(resolverStub, 0x1F);
                    BitConverter.GetBytes(neededDependencies.Count).CopyTo(resolverStub, 0x28);
                    BitConverter.GetBytes(pModules.ToInt32()).CopyTo(resolverStub, 0x31);

                    if (WinAPI.WriteProcessMemory(hProcess, pResolverStub, resolverStub, resolverStub.Length, out nBytes) && nBytes == (uint)resolverStub.Length)
                    {
                        uint result = WinAPI.RunThread(hProcess, pResolverStub, 0, 5000);
                        success = (result != uint.MaxValue && result != 0);
                    }

                    // Cleanup
                    WinAPI.VirtualFreeEx(hProcess, pModules, 0, 0x8000);
                    WinAPI.VirtualFreeEx(hProcess, pManifest, 0, 0x8000);
                    WinAPI.VirtualFreeEx(hProcess, pResolverStub, 0, 0x8000);
                }
            }

            return success;
        }
Пример #29
0
 public override IntPtr[] InjectAll(PortableExecutable[] images, IntPtr hProcess)
 {
     ClearErrors();
     return Array.ConvertAll(images, pe => Inject(pe, hProcess));
 }
Пример #30
0
        private static void MapSections(PortableExecutable image, IntPtr hProcess, IntPtr pModule)
        {
            //very straightforward really. Just iterate through all the sections and map them to their desired virtual addresses in the remote process.
            //I'm not 100% sure about how well masking the section header characteristics and passing them off as memory protection constants goes. But
            //so far I haven't hit any issues. (i.e a section header with characteristics "IMAGE_SCN_TYPE_NO_PAD" will set "PAGE_WRITECOPY" memory protection.
            byte[] databuffer;
            uint n;

            foreach (var pSecHd in image.EnumSectionHeaders())
            {
                databuffer = new byte[pSecHd.SizeOfRawData];
                if (image.Read(pSecHd.PointerToRawData, SeekOrigin.Begin, databuffer))
                {
                    if ((pSecHd.Characteristics & 0x02000000) == 0) //can actually ignore this section (usually the reloc section)
                    {
                        WinAPI.WriteProcessMemory(hProcess, pModule.Add(pSecHd.VirtualAddress), databuffer, databuffer.Length, out n);
                        WinAPI.VirtualProtectEx(hProcess, pModule.Add(pSecHd.VirtualAddress), pSecHd.SizeOfRawData, pSecHd.Characteristics & 0x00FFFFFF, out n);
                    }
                }
                else
                {
                    throw image.GetLastError();
                }
            }
        }
Пример #31
0
        private static void PatchRelocations(PortableExecutable image, IntPtr pAlloc)
        {
            // Base relocations are essentially Microsofts ingenious way of preserving portability in images.
            // for all absolute address calls/jmps/references...etc, an entry is made into the base relocation
            // table telling the loader exactly where an "absolute" address is being used. This allows the loader
            // to iterate through the relocations and patch these absolute values to ensure they are correct when
            // the image is loaded somewhere that isn't its preferred base address.
            IMAGE_DATA_DIRECTORY relocDir = image.NTHeader.OptionalHeader.DataDirectory[(int)DATA_DIRECTORIES.BaseRelocTable];
            if (relocDir.Size > 0) //check if there are in fact any relocations.
            {
                uint n = 0;
                uint delta = (uint)(pAlloc.ToInt32() - image.NTHeader.OptionalHeader.ImageBase); //The difference in loaded/preferred addresses.
                uint pReloc = image.GetPtrFromRVA(relocDir.VirtualAddress);
                uint szReloc = (uint)Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));
                IMAGE_BASE_RELOCATION reloc;

                while (n < relocDir.Size && image.Read(pReloc, SeekOrigin.Begin, out reloc))
                {
                    // A relocation block consists of an IMAGE_BASE_RELOCATION, and an array of WORDs.
                    // To calculate the number of relocations (represented by WORDs), just do some simple math.
                    int nrelocs = (int)((reloc.SizeOfBlock - szReloc) / sizeof(ushort));
                    uint pageVa = image.GetPtrFromRVA(reloc.VirtualAddress); //The Page RVA for this set of relocations (usually a 4K boundary).
                    ushort vreloc;
                    uint old;

                    for (int i = 0; i < nrelocs; i++)
                    {
                        // There are only 2 types of relocations on Intel machines: ABSOLUTE (padding, nothing needs to be done) and HIGHLOW (0x03)
                        // Highlow means that all 32 bits of the "delta" value need to be added to the relocation value.
                        if (image.Read(pReloc + szReloc + (i << 1), SeekOrigin.Begin, out vreloc) && (vreloc >> 12 & 3) != 0)
                        {
                            uint vp = (uint)(pageVa + (vreloc & 0x0FFF));
                            if (image.Read<uint>(vp, SeekOrigin.Begin, out old))
                                image.Write<uint>(-4, SeekOrigin.Current, (uint)(old + delta));
                            else
                                throw image.GetLastError(); //unlikely, but I hate crashing targets because something in the PE was messed up.
                        }
                    }
                    n += reloc.SizeOfBlock;
                    pReloc += reloc.SizeOfBlock;
                }
            }
        }
 public ResourceFile(PortableExecutable owner, IMAGE_RESOURCE_DIRECTORY_ENTRY entry, bool named, uint root)
     : base(owner, entry, named, root)
 {
     if (!owner.Read(_root + entry.DataEntryRva, System.IO.SeekOrigin.Begin, out this._base))
         throw owner.GetLastError();
 }
Пример #33
0
        private static IntPtr MapModule(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess, bool preserveHeaders = false)
        {
            if (hProcess.IsNull() || hProcess.Compare(-1L))
            {
                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 zero = IntPtr.Zero;
            IntPtr ptr  = IntPtr.Zero;
            uint   lpNumberOfBytesRead = 0;

            try
            {
                zero = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, image.NTHeader.OptionalHeader.SizeOfImage, 0x3000, 4);
                if (zero.IsNull())
                {
                    throw new InvalidOperationException("Unable to allocate memory in the remote process.");
                }
                PatchRelocations(image, zero);
                LoadDependencies(image, hProcess, processId);
                PatchImports(image, hProcess, processId);
                if (preserveHeaders)
                {
                    long   num3   = (long)(((image.DOSHeader.e_lfanew + Marshal.SizeOf(typeof(IMAGE_FILE_HEADER))) + ((long)4L)) + image.NTHeader.FileHeader.SizeOfOptionalHeader);
                    byte[] buffer = new byte[num3];
                    if (image.Read(0L, SeekOrigin.Begin, buffer))
                    {
                        WinAPI.WriteProcessMemory(hProcess, zero, buffer, buffer.Length, out lpNumberOfBytesRead);
                    }
                }
                MapSections(image, hProcess, zero);
                if (image.NTHeader.OptionalHeader.AddressOfEntryPoint <= 0)
                {
                    return(zero);
                }
                byte[] array = (byte[])DLLMAIN_STUB.Clone();
                BitConverter.GetBytes(zero.ToInt32()).CopyTo(array, 11);
                ptr = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)DLLMAIN_STUB.Length, 0x3000, 0x40);
                if (ptr.IsNull() || (!WinAPI.WriteProcessMemory(hProcess, ptr, array, array.Length, out lpNumberOfBytesRead) || (lpNumberOfBytesRead != array.Length)))
                {
                    throw new InvalidOperationException("Unable to write stub to the remote process.");
                }
                IntPtr hObject = WinAPI.CreateRemoteThread(hProcess, 0, 0, ptr, (uint)zero.Add(((long)image.NTHeader.OptionalHeader.AddressOfEntryPoint)).ToInt32(), 0, 0);
                if (WinAPI.WaitForSingleObject(hObject, 0x1388) != 0L)
                {
                    return(zero);
                }
                WinAPI.GetExitCodeThread(hObject, out lpNumberOfBytesRead);
                if (lpNumberOfBytesRead == 0)
                {
                    WinAPI.VirtualFreeEx(hProcess, zero, 0, 0x8000);
                    throw new Exception("Entry method of module reported a failure " + Marshal.GetLastWin32Error().ToString());
                }
                WinAPI.VirtualFreeEx(hProcess, ptr, 0, 0x8000);
                WinAPI.CloseHandle(hObject);
            }
            catch (Exception exception)
            {
                if (!zero.IsNull())
                {
                    WinAPI.VirtualFreeEx(hProcess, zero, 0, 0x8000);
                }
                if (!ptr.IsNull())
                {
                    WinAPI.VirtualFreeEx(hProcess, zero, 0, 0x8000);
                }
                zero = IntPtr.Zero;
                throw exception;
            }
            return(zero);
        }
Пример #34
0
        private static bool LoadDependencies(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess, int processId)
        {
            List <string> list     = new List <string>();
            string        lpBuffer = string.Empty;
            bool          flag     = false;

            foreach (IMAGE_IMPORT_DESCRIPTOR image_import_descriptor in image.EnumImports())
            {
                if ((image.ReadString((long)image.GetPtrFromRVA(image_import_descriptor.Name), SeekOrigin.Begin, out lpBuffer, -1, null) && !string.IsNullOrEmpty(lpBuffer)) && GetRemoteModuleHandle(lpBuffer, processId).IsNull())
                {
                    list.Add(lpBuffer);
                }
            }
            if (list.Count > 0)
            {
                byte[] data = ExtractManifest(image);
                string str2 = string.Empty;
                if (data == null)
                {
                    if (string.IsNullOrEmpty(image.FileLocation) || !File.Exists(Path.Combine(Path.GetDirectoryName(image.FileLocation), Path.GetFileName(image.FileLocation) + ".manifest")))
                    {
                        IntPtr[] ptrArray = InjectionMethod.Create(InjectionMethodType.Standard).InjectAll(list.ToArray(), hProcess);
                        foreach (IntPtr ptr in ptrArray)
                        {
                            if (ptr.IsNull())
                            {
                                return(false);
                            }
                        }
                        return(true);
                    }
                    str2 = Path.Combine(Path.GetDirectoryName(image.FileLocation), Path.GetFileName(image.FileLocation) + ".manifest");
                }
                else
                {
                    str2 = Utils.WriteTempData(data);
                }
                if (string.IsNullOrEmpty(str2))
                {
                    return(false);
                }
                IntPtr ptr2      = WinAPI.VirtualAllocEx(hProcess, IntPtr.Zero, (uint)RESOLVER_STUB.Length, 0x3000, 0x40);
                IntPtr lpAddress = WinAPI.CreateRemotePointer(hProcess, Encoding.ASCII.GetBytes(str2 + "\0"), 4);
                IntPtr ptr4      = WinAPI.CreateRemotePointer(hProcess, Encoding.ASCII.GetBytes(string.Join("\0", list.ToArray()) + "\0"), 4);
                if (!ptr2.IsNull())
                {
                    byte[] array = (byte[])RESOLVER_STUB.Clone();
                    uint   lpNumberOfBytesRead = 0;
                    BitConverter.GetBytes(FN_CREATEACTCTXA.Subtract(ptr2.Add(((long)0x3fL))).ToInt32()).CopyTo(array, 0x3b);
                    BitConverter.GetBytes(FN_ACTIVATEACTCTX.Subtract(ptr2.Add(((long)0x58L))).ToInt32()).CopyTo(array, 0x54);
                    BitConverter.GetBytes(FN_GETMODULEHANDLEA.Subtract(ptr2.Add(((long)0x84L))).ToInt32()).CopyTo(array, 0x80);
                    BitConverter.GetBytes(FN_LOADLIBRARYA.Subtract(ptr2.Add(((long)0x92L))).ToInt32()).CopyTo(array, 0x8e);
                    BitConverter.GetBytes(FN_DEACTIVATEACTCTX.Subtract(ptr2.Add(((long)200L))).ToInt32()).CopyTo(array, 0xc4);
                    BitConverter.GetBytes(FN_RELEASEACTCTX.Subtract(ptr2.Add(((long)0xd1L))).ToInt32()).CopyTo(array, 0xcd);
                    BitConverter.GetBytes(lpAddress.ToInt32()).CopyTo(array, 0x1f);
                    BitConverter.GetBytes(list.Count).CopyTo(array, 40);
                    BitConverter.GetBytes(ptr4.ToInt32()).CopyTo(array, 0x31);
                    if (WinAPI.WriteProcessMemory(hProcess, ptr2, array, array.Length, out lpNumberOfBytesRead) && (lpNumberOfBytesRead == array.Length))
                    {
                        uint num2 = WinAPI.RunThread(hProcess, ptr2, 0, 0x1388);
                        flag = (num2 != uint.MaxValue) && (num2 != 0);
                    }
                    WinAPI.VirtualFreeEx(hProcess, ptr4, 0, 0x8000);
                    WinAPI.VirtualFreeEx(hProcess, lpAddress, 0, 0x8000);
                    WinAPI.VirtualFreeEx(hProcess, ptr2, 0, 0x8000);
                }
            }
            return(flag);
        }
 public override IntPtr[] InjectAll(PortableExecutable[] dlls, IntPtr hProcess)
 {
     ClearErrors();
     return InjectAll(Array.ConvertAll<PortableExecutable, string>(dlls, pe => Utils.WriteTempData(pe.ToArray())), hProcess);
 }
Пример #36
0
 public abstract IntPtr Inject(JLibrary.PortableExecutable.PortableExecutable image, IntPtr hProcess);
Пример #37
0
        private static void PatchImports(PortableExecutable image, IntPtr hProcess, int processId)
        {
            string module = string.Empty;
            string fname = string.Empty;

            foreach (var desc in image.EnumImports())
            {
                if (image.ReadString(image.GetPtrFromRVA(desc.Name), SeekOrigin.Begin, out module))
                {
                    IntPtr pModule = IntPtr.Zero;
                    IntPtr tModule = IntPtr.Zero;
                    //Thanks to FastLoadDependencies, all dependent modules *should* be loaded into the remote process already.
                    pModule = GetRemoteModuleHandle(module, processId);

                    if (pModule.IsNull())
                        throw new FileNotFoundException(string.Format("Unable to load dependent module '{0}'.", module));

                    //now have a supposedly valid module handle remote process, all that remains to be done is patch the info.
                    uint pThunk = image.GetPtrFromRVA(desc.FirstThunkPtr); //despite the fact FirstThunk and OriginalFirstThunk are identical within an unmapped PE, only FirstThunk is looked up after mapping.
                    uint szThunk = (uint)Marshal.SizeOf(typeof(IMAGE_THUNK_DATA));
                    IMAGE_THUNK_DATA thunk;

                    while (image.Read(pThunk, SeekOrigin.Begin, out thunk) && thunk.u1.AddressOfData > 0) //final thunk is signified by a null-filled IMAGE_THUNK_DATA structure.
                    {
                        IntPtr remote = IntPtr.Zero;
                        object procVal = null;
                        if ((thunk.u1.Ordinal & 0x80000000) == 0) //import by name
                        {
                            if (image.ReadString(image.GetPtrFromRVA(thunk.u1.AddressOfData) + 2, SeekOrigin.Begin, out fname)) //get the function name.
                                procVal = fname;
                            else
                                throw image.GetLastError(); //error occurred during memory iteration, this is only a safeguard and shouldn't really ever occur, but the universe loves proving me wrong.
                        }
                        else //import by ordinal.
                        {
                            procVal = (ushort)(thunk.u1.Ordinal & 0xFFFF);
                        }

                        // the following section of code simply aims to reduce overhead. A check is first performed to see if the current module
                        // is loaded in the current process first, if so it simply uses relative addresses to calculate the function address in the remote
                        // process. If the module isn't found in our process, a call to GetProcAddressEx is used to find the remote address. Of course, you
                        // could simply guarantee the first case by calling LoadLibrary internally, but I find that can have unwanted side effects.
                        if (!(remote = WinAPI.GetModuleHandleA(module)).IsNull())
                        {
                            IntPtr local = procVal.GetType().Equals(typeof(string)) 
                                            ? WinAPI.GetProcAddress(remote, (string)procVal) 
                                            : WinAPI.GetProcAddress(remote, (uint)((ushort)procVal) & 0x0000FFFF);
                            if (!local.IsNull())
                                remote = pModule.Add(local.Subtract(remote.ToInt32()).ToInt32());
                        }
                        else
                        {
                            remote = WinAPI.GetProcAddressEx(hProcess, pModule, procVal);
                        }
                        
                        if (remote.IsNull()) //alas, couldn't find the function.
                            throw new EntryPointNotFoundException(string.Format("Unable to locate imported function '{0}' from module '{1}' in the remote process.", fname, module));

                        image.Write<int>(pThunk, SeekOrigin.Begin, remote.ToInt32()); //overwrite the thunk and continue on our merry way.
                        pThunk += szThunk;
                    }
                }
            }
        }
Пример #38
0
        /**
         * Extract an application manifest from
         * an executable file's resources.
         * Returns null if no manifest was found in the executable.
         */
        private static byte[] ExtractManifest(PortableExecutable image)
        {
            byte[] manifest = null;
            ResourceWalker walker = new ResourceWalker(image);
            ResourceWalker.ResourceDirectory manifestDir = null;
            for (int i = 0; i < walker.Root.Directories.Length && manifestDir == null; i++)
                if (walker.Root.Directories[i].Id == Constants.RT_MANIFEST)
                    manifestDir = walker.Root.Directories[i];

            if (manifestDir != null && manifestDir.Directories.Length > 0)
                if (IsManifestResource(manifestDir.Directories[0].Id) && manifestDir.Directories[0].Files.Length == 1)
                    manifest = manifestDir.Directories[0].Files[0].GetData();

            return manifest;
        }