Example #1
0
        /// <summary>
        /// Rewrite IAT for manually mapped module.
        /// </summary>
        /// <author>Ruben Boonen (@FuzzySec)</author>
        /// <param name="peMetaData">Module meta data struct (PE.PE_META_DATA).</param>
        /// <param name="moduleMemoryBase">Base address of the module in memory.</param>
        /// <returns>void</returns>
        public static void RewriteModuleIAT(Data.PE.PE_META_DATA peMetaData, IntPtr moduleMemoryBase)
        {
            var idd = peMetaData.Is32Bit ? peMetaData.OptHeader32.ImportTable : peMetaData.OptHeader64.ImportTable;

            if (idd.VirtualAddress == 0)
            {
                return;
            }

            var pImportTable = (IntPtr)((ulong)moduleMemoryBase + idd.VirtualAddress);

            var osVersion = new Data.Native.OSVERSIONINFOEX();

            Native.RtlGetVersion(ref osVersion);

            var apiSetDict = new Dictionary <string, string>();

            if (osVersion.MajorVersion >= 10)
            {
                apiSetDict = Generic.GetApiSetMapping();
            }

            var counter = 0;
            var iid     = new Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR();

            iid = (Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
                (IntPtr)((ulong)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
                typeof(Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
                );

            while (iid.Name != 0)
            {
                var dllName = string.Empty;

                try
                {
                    dllName = Marshal.PtrToStringAnsi((IntPtr)((ulong)moduleMemoryBase + iid.Name));
                }
                catch
                {
                    // ignore
                }

                if (dllName == string.Empty)
                {
                    throw new InvalidOperationException("Failed to read DLL name.");
                }


                var lookupKey = dllName !.Substring(0, dllName.Length - 6) + ".dll";

                if (osVersion.MajorVersion >= 10 && (dllName.StartsWith("api-") || dllName.StartsWith("ext-")) &&
                    apiSetDict.ContainsKey(lookupKey) && apiSetDict[lookupKey].Length > 0)
                {
                    dllName = apiSetDict[lookupKey];
                }

                var hModule = Generic.GetLoadedModuleAddress(dllName);

                if (hModule == IntPtr.Zero)
                {
                    hModule = Generic.LoadModuleFromDisk(dllName);

                    if (hModule == IntPtr.Zero)
                    {
                        throw new FileNotFoundException(dllName + ", unable to find the specified file.");
                    }
                }

                if (peMetaData.Is32Bit)
                {
                    var oft_itd = new Data.PE.IMAGE_THUNK_DATA32();
                    for (var i = 0;; i++)
                    {
                        oft_itd = (Data.PE.IMAGE_THUNK_DATA32)Marshal.PtrToStructure(
                            (IntPtr)((ulong)moduleMemoryBase + iid.OriginalFirstThunk + (uint)(i * sizeof(uint))),
                            typeof(Data.PE.IMAGE_THUNK_DATA32));

                        var ft_itd = (IntPtr)((ulong)moduleMemoryBase + iid.FirstThunk + (ulong)(i * sizeof(uint)));

                        if (oft_itd.AddressOfData == 0)
                        {
                            break;
                        }

                        if (oft_itd.AddressOfData < 0x80000000)
                        {
                            var pImpByName = (IntPtr)((ulong)moduleMemoryBase + oft_itd.AddressOfData + sizeof(ushort));
                            var pFunc      = IntPtr.Zero;

                            pFunc = Generic.GetNativeExportAddress(hModule,
                                                                   Marshal.PtrToStringAnsi(pImpByName));

                            Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
                        }
                        else
                        {
                            ulong fOrdinal = oft_itd.AddressOfData & 0xFFFF;

                            var pFunc = IntPtr.Zero;
                            pFunc = Generic.GetNativeExportAddress(hModule, (short)fOrdinal);

                            Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
                        }
                    }
                }
                else
                {
                    var oft_itd = new Data.PE.IMAGE_THUNK_DATA64();

                    for (var i = 0;; i++)
                    {
                        oft_itd = (Data.PE.IMAGE_THUNK_DATA64)Marshal.PtrToStructure(
                            (IntPtr)((ulong)moduleMemoryBase + iid.OriginalFirstThunk + (ulong)(i * sizeof(ulong))),
                            typeof(Data.PE.IMAGE_THUNK_DATA64));

                        var ft_itd = (IntPtr)((ulong)moduleMemoryBase + iid.FirstThunk + (ulong)(i * sizeof(ulong)));

                        if (oft_itd.AddressOfData == 0)
                        {
                            break;
                        }

                        if (oft_itd.AddressOfData < 0x8000000000000000) // !IMAGE_ORDINAL_FLAG64
                        {
                            var pImpByName = (IntPtr)((ulong)moduleMemoryBase + oft_itd.AddressOfData + sizeof(ushort));
                            var pFunc      = IntPtr.Zero;

                            pFunc = Generic.GetNativeExportAddress(hModule,
                                                                   Marshal.PtrToStringAnsi(pImpByName));

                            Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
                        }
                        else
                        {
                            var fOrdinal = oft_itd.AddressOfData & 0xFFFF;

                            var pFunc = IntPtr.Zero;
                            pFunc = Generic.GetNativeExportAddress(hModule, (short)fOrdinal);

                            Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
                        }
                    }
                }

                counter++;

                iid = (Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
                    (IntPtr)((ulong)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
                    typeof(Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
                    );
            }
        }
Example #2
0
        /// <summary>
        /// Rewrite IAT for manually mapped module.
        /// </summary>
        /// <author>Ruben Boonen (@FuzzySec)</author>
        /// <param name="PEINFO">Module meta data struct (PE.PE_META_DATA).</param>
        /// <param name="ModuleMemoryBase">Base address of the module in memory.</param>
        /// <returns>void</returns>
        public static void RewriteModuleIAT(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
        {
            Data.PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.ImportTable : PEINFO.OptHeader64.ImportTable;

            // Check if there is no import table
            if (idd.VirtualAddress == 0)
            {
                // Return so that the rest of the module mapping process may continue.
                return;
            }

            // Ptr for the base import directory
            IntPtr pImportTable = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress);

            // Get API Set mapping dictionary if on Win10+
            Data.Native.OSVERSIONINFOEX OSVersion = new Data.Native.OSVERSIONINFOEX();
            DynamicInvoke.Native.RtlGetVersion(ref OSVersion);
            Dictionary <string, string> ApiSetDict = new Dictionary <string, string>();

            if (OSVersion.MajorVersion >= 10)
            {
                ApiSetDict = DynamicInvoke.Generic.GetApiSetMapping();
            }

            // Loop IID's
            int counter = 0;

            Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR iid = new Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR();
            iid = (Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
                (IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
                typeof(Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
                );
            while (iid.Name != 0)
            {
                // Get DLL
                string DllName = string.Empty;
                try
                {
                    DllName = Marshal.PtrToStringAnsi((IntPtr)((UInt64)ModuleMemoryBase + iid.Name));
                }
                catch { }

                // Loop imports
                if (DllName == string.Empty)
                {
                    throw new InvalidOperationException("Failed to read DLL name.");
                }
                else
                {
                    // API Set DLL?
                    if (OSVersion.MajorVersion >= 10 && (DllName.StartsWith("api-") || DllName.StartsWith("ext-")) &&
                        ApiSetDict.ContainsKey(DllName) && ApiSetDict[DllName].Length > 0)
                    {
                        // Not all API set DLL's have a registered host mapping
                        DllName = ApiSetDict[DllName];
                    }

                    // Check and / or load DLL
                    IntPtr hModule = DynamicInvoke.Generic.GetLoadedModuleAddress(DllName);
                    if (hModule == IntPtr.Zero)
                    {
                        hModule = DynamicInvoke.Generic.LoadModuleFromDisk(DllName);
                        if (hModule == IntPtr.Zero)
                        {
                            throw new FileNotFoundException(DllName + ", unable to find the specified file.");
                        }
                    }

                    // Loop thunks
                    if (PEINFO.Is32Bit)
                    {
                        Data.PE.IMAGE_THUNK_DATA32 oft_itd = new Data.PE.IMAGE_THUNK_DATA32();
                        for (int i = 0; true; i++)
                        {
                            oft_itd = (Data.PE.IMAGE_THUNK_DATA32)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt32)(i * (sizeof(UInt32)))), typeof(Data.PE.IMAGE_THUNK_DATA32));
                            IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt32))));
                            if (oft_itd.AddressOfData == 0)
                            {
                                break;
                            }

                            if (oft_itd.AddressOfData < 0x80000000) // !IMAGE_ORDINAL_FLAG32
                            {
                                IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16));
                                IntPtr pFunc      = IntPtr.Zero;
                                pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName));

                                // Write ProcAddress
                                Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
                            }
                            else
                            {
                                ulong  fOrdinal = oft_itd.AddressOfData & 0xFFFF;
                                IntPtr pFunc    = IntPtr.Zero;
                                pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, (short)fOrdinal);

                                // Write ProcAddress
                                Marshal.WriteInt32(ft_itd, pFunc.ToInt32());
                            }
                        }
                    }
                    else
                    {
                        Data.PE.IMAGE_THUNK_DATA64 oft_itd = new Data.PE.IMAGE_THUNK_DATA64();
                        for (int i = 0; true; i++)
                        {
                            oft_itd = (Data.PE.IMAGE_THUNK_DATA64)Marshal.PtrToStructure((IntPtr)((UInt64)ModuleMemoryBase + iid.OriginalFirstThunk + (UInt64)(i * (sizeof(UInt64)))), typeof(Data.PE.IMAGE_THUNK_DATA64));
                            IntPtr ft_itd = (IntPtr)((UInt64)ModuleMemoryBase + iid.FirstThunk + (UInt64)(i * (sizeof(UInt64))));
                            if (oft_itd.AddressOfData == 0)
                            {
                                break;
                            }

                            if (oft_itd.AddressOfData < 0x8000000000000000) // !IMAGE_ORDINAL_FLAG64
                            {
                                IntPtr pImpByName = (IntPtr)((UInt64)ModuleMemoryBase + oft_itd.AddressOfData + sizeof(UInt16));
                                IntPtr pFunc      = IntPtr.Zero;
                                pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, Marshal.PtrToStringAnsi(pImpByName));

                                // Write pointer
                                Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
                            }
                            else
                            {
                                ulong  fOrdinal = oft_itd.AddressOfData & 0xFFFF;
                                IntPtr pFunc    = IntPtr.Zero;
                                pFunc = DynamicInvoke.Generic.GetNativeExportAddress(hModule, (short)fOrdinal);

                                // Write pointer
                                Marshal.WriteInt64(ft_itd, pFunc.ToInt64());
                            }
                        }
                    }
                    counter++;
                    iid = (Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)Marshal.PtrToStructure(
                        (IntPtr)((UInt64)pImportTable + (uint)(Marshal.SizeOf(iid) * counter)),
                        typeof(Data.Win32.Kernel32.IMAGE_IMPORT_DESCRIPTOR)
                        );
                }
            }
        }