示例#1
0
文件: Map.cs 项目: zhouzu/DInvoke
        /// <summary>
        /// Relocates a module in memory.
        /// </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 RelocateModule(Data.PE.PE_META_DATA PEINFO, IntPtr ModuleMemoryBase)
        {
            Data.PE.IMAGE_DATA_DIRECTORY idd = PEINFO.Is32Bit ? PEINFO.OptHeader32.BaseRelocationTable : PEINFO.OptHeader64.BaseRelocationTable;
            Int64 ImageDelta = PEINFO.Is32Bit ? (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader32.ImageBase) :
                               (Int64)((UInt64)ModuleMemoryBase - PEINFO.OptHeader64.ImageBase);

            // Ptr for the base reloc table
            IntPtr pRelocTable         = (IntPtr)((UInt64)ModuleMemoryBase + idd.VirtualAddress);
            Int32  nextRelocTableBlock = -1;

            // Loop reloc blocks
            while (nextRelocTableBlock != 0)
            {
                Data.PE.IMAGE_BASE_RELOCATION ibr = new Data.PE.IMAGE_BASE_RELOCATION();
                ibr = (Data.PE.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(pRelocTable, typeof(Data.PE.IMAGE_BASE_RELOCATION));

                Int64 RelocCount = ((ibr.SizeOfBlock - Marshal.SizeOf(ibr)) / 2);
                for (int i = 0; i < RelocCount; i++)
                {
                    // Calculate reloc entry ptr
                    IntPtr pRelocEntry = (IntPtr)((UInt64)pRelocTable + (UInt64)Marshal.SizeOf(ibr) + (UInt64)(i * 2));
                    UInt16 RelocValue  = (UInt16)Marshal.ReadInt16(pRelocEntry);

                    // Parse reloc value
                    // The type should only ever be 0x0, 0x3, 0xA
                    // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-types
                    UInt16 RelocType  = (UInt16)(RelocValue >> 12);
                    UInt16 RelocPatch = (UInt16)(RelocValue & 0xfff);

                    // Perform relocation
                    if (RelocType != 0) // IMAGE_REL_BASED_ABSOLUTE (0 -> skip reloc)
                    {
                        try
                        {
                            IntPtr pPatch = (IntPtr)((UInt64)ModuleMemoryBase + ibr.VirtualAdress + RelocPatch);
                            if (RelocType == 0x3) // IMAGE_REL_BASED_HIGHLOW (x86)
                            {
                                Int32 OriginalPtr = Marshal.ReadInt32(pPatch);
                                Marshal.WriteInt32(pPatch, (OriginalPtr + (Int32)ImageDelta));
                            }
                            else // IMAGE_REL_BASED_DIR64 (x64)
                            {
                                Int64 OriginalPtr = Marshal.ReadInt64(pPatch);
                                Marshal.WriteInt64(pPatch, (OriginalPtr + ImageDelta));
                            }
                        }
                        catch
                        {
                            throw new InvalidOperationException("Memory access violation.");
                        }
                    }
                }

                // Check for next block
                pRelocTable         = (IntPtr)((UInt64)pRelocTable + ibr.SizeOfBlock);
                nextRelocTableBlock = Marshal.ReadInt32(pRelocTable);
            }
        }
示例#2
0
        /// <summary>
        /// Relocates a module in memory.
        /// </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 RelocateModule(Data.PE.PE_META_DATA peMetaData, IntPtr moduleMemoryBase)
        {
            var idd        = peMetaData.Is32Bit ? peMetaData.OptHeader32.BaseRelocationTable : peMetaData.OptHeader64.BaseRelocationTable;
            var imageDelta = peMetaData.Is32Bit ? (long)((ulong)moduleMemoryBase - peMetaData.OptHeader32.ImageBase) :
                             (long)((ulong)moduleMemoryBase - peMetaData.OptHeader64.ImageBase);

            var pRelocTable         = (IntPtr)((ulong)moduleMemoryBase + idd.VirtualAddress);
            var nextRelocTableBlock = -1;

            while (nextRelocTableBlock != 0)
            {
                var ibr = new Data.PE.IMAGE_BASE_RELOCATION();
                ibr = (Data.PE.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(pRelocTable, typeof(Data.PE.IMAGE_BASE_RELOCATION));

                var relocCount = (ibr.SizeOfBlock - Marshal.SizeOf(ibr)) / 2;

                for (var i = 0; i < relocCount; i++)
                {
                    var pRelocEntry = (IntPtr)((ulong)pRelocTable + (ulong)Marshal.SizeOf(ibr) + (ulong)(i * 2));
                    var relocValue  = (ushort)Marshal.ReadInt16(pRelocEntry);

                    var relocType  = (ushort)(relocValue >> 12);
                    var relocPatch = (ushort)(relocValue & 0xfff);

                    if (relocType == 0)
                    {
                        continue;
                    }

                    try
                    {
                        var pPatch = (IntPtr)((ulong)moduleMemoryBase + ibr.VirtualAdress + relocPatch);
                        if (relocType == 0x3)
                        {
                            var originalPtr = Marshal.ReadInt32(pPatch);
                            Marshal.WriteInt32(pPatch, originalPtr + (int)imageDelta);
                        }
                        else
                        {
                            var originalPtr = Marshal.ReadInt64(pPatch);
                            Marshal.WriteInt64(pPatch, originalPtr + imageDelta);
                        }
                    }
                    catch
                    {
                        throw new InvalidOperationException("Memory access violation.");
                    }
                }

                pRelocTable         = (IntPtr)((ulong)pRelocTable + ibr.SizeOfBlock);
                nextRelocTableBlock = Marshal.ReadInt32(pRelocTable);
            }
        }