Пример #1
0
        /// <summary>
        /// 重定位表的处理
        /// </summary>
        /// <param name="pPEHeader"></param>
        private unsafe void ReLocation(IMAGE_NT_HEADERS *pPEHeader)
        {
#if _WIN64
            Int64 iDelta = (Int64)((Int64)this.mModuleHandle - (Int64)pPEHeader->OptionalHeader.ImageBase);
#else
            Int32 iDelta = (Int32)this.mModuleHandle - (Int32)pPEHeader->OptionalHeader.ImageBase;
#endif
            if (iDelta == 0)
            {
                return;
            }

#if _WIN64
            IMAGE_BASE_RELOCATION *pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)((Int64)this.mModuleHandle +
                                                                                    (Int64)pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress));
            while (pRelocation->VirtualAddress > 0 && pRelocation->SizeOfBlock > 0)
            {
                UInt16 *pLocData       = (UInt16 *)((IntPtr)pRelocation + sizeof(IMAGE_BASE_RELOCATION));
                var     iNumberOfReloc = (pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
                for (Int32 i = 0; i < iNumberOfReloc; i++)
                {
                    if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_HIGHLOW)
                    {
                        UInt32 *lpPoint  = (UInt32 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF)));
                        *       lpPoint += (UInt32)iDelta;
                    }
                    else if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_DIR64)
                    {
                        UInt64 *lpPoint  = (UInt64 *)((IntPtr)((Int64)this.mModuleHandle + (Int64)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF)));
                        *       lpPoint += (UInt64)iDelta;
                    }
                }
                pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)((Int64)((IntPtr)pRelocation) + (Int64)pRelocation->SizeOfBlock));
            }
#else
            IMAGE_BASE_RELOCATION *pRelocation = (IMAGE_BASE_RELOCATION *)(this.mModuleHandle +
                                                                           (Int32)pPEHeader->OptionalHeader.GetDirectory(IMAGE_DIRECTORY_ENTRY.IMAGE_DIRECTORY_ENTRY_BASERELOC).VirtualAddress);
            while (pRelocation->VirtualAddress > 0 && pRelocation->SizeOfBlock > 0)
            {
                UInt16 *pLocData       = (UInt16 *)((IntPtr)pRelocation + sizeof(IMAGE_BASE_RELOCATION));
                var     iNumberOfReloc = (pRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2;
                for (Int32 i = 0; i < iNumberOfReloc; i++)
                {
                    if ((pLocData[i] & 0xFFFF) / 0x1000 == Win32API.IMAGE_REL_BASED_HIGHLOW)
                    {
                        UInt32 *lpPoint  = (UInt32 *)(this.mModuleHandle + (Int32)pRelocation->VirtualAddress + (pLocData[i] & 0xFFF));
                        *       lpPoint += (UInt32)iDelta;
                    }
                }
                pRelocation = (IMAGE_BASE_RELOCATION *)((IntPtr)pRelocation + (Int32)pRelocation->SizeOfBlock);
            }
#endif
        }
Пример #2
0
        private void PerformBaseRelocation(uint delta)
        {
            if (delta == 0)
            {
                return;
            }

            int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));

            IMAGE_DATA_DIRECTORY *directory = &this.headers->OptionalHeader.BaseRelocationTable;

            if (directory->Size > 0)
            {
                IMAGE_BASE_RELOCATION *relocation = (IMAGE_BASE_RELOCATION *)(this.codeBase + directory->VirtualAddress);
                while (relocation->VirtualAdress > 0)
                {
                    byte *  dest    = this.codeBase + relocation->VirtualAdress;
                    ushort *relInfo = (ushort *)((byte *)relocation + imageSizeOfBaseRelocation);

                    for (int i = 0; i < ((relocation->SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++, relInfo++)
                    {
                        uint *patchAddrHL;
                        BasedRelocationType type;
                        int offset;

                        // the upper 4 bits define the type of relocation
                        type = (BasedRelocationType)(*relInfo >> 12);
                        // the lower 12 bits define the offset
                        offset = *relInfo & 0xfff;

                        switch (type)
                        {
                        case BasedRelocationType.IMAGE_REL_BASED_ABSOLUTE:
                            break;

                        case BasedRelocationType.IMAGE_REL_BASED_HIGHLOW:
                            patchAddrHL = (uint *)(dest + offset);
                            *patchAddrHL += delta;
                            break;

                        default:
                            break;
                        }
                    }

                    // advance to next relocation block
                    relocation = (IMAGE_BASE_RELOCATION *)(((byte *)relocation) + relocation->SizeOfBlock);
                }
            }
        }
Пример #3
0
            private void PerformBaseRelocation(Image image, long delta)
            {
                IMAGE_DATA_DIRECTORY directory = Environment.Is64BitProcess
                                        ? image.OptionalHeader64->BaseRelocationTable
                                        : image.OptionalHeader32->BaseRelocationTable;

                if (directory.Size == 0)
                {
                    return;
                }

                IMAGE_BASE_RELOCATION *relocation = (IMAGE_BASE_RELOCATION *)(image.BasePtr + directory.VirtualAddress);

                while (relocation->VirtualAddress > 0)
                {
                    ApplyRelocationBlock(image, delta, relocation);
                    relocation = (IMAGE_BASE_RELOCATION *)((byte *)relocation + relocation->BlockSizeInclusive);
                }
            }
Пример #4
0
            private void ApplyRelocationBlock(Image image, long delta, IMAGE_BASE_RELOCATION *relocation)
            {
                byte *  dest           = image.BasePtr + relocation->VirtualAddress;
                ushort *relocationInfo = (ushort *)((byte *)relocation + sizeof(IMAGE_BASE_RELOCATION));

                for (int i = 0; i < (relocation->BlockSizeInclusive - sizeof(IMAGE_BASE_RELOCATION)) / 2; i++, relocationInfo++)
                {
                    RelocationType type   = (RelocationType)(*relocationInfo >> 12);
                    int            offset = *relocationInfo & 0xFFF;

                    switch (type)
                    {
                    case RelocationType.Absolute:
                        // Skip relocation;
                        break;

                    case RelocationType.HighLow:
                        // Change complete 32-bit address.
                        int *patchAddressHighLow = (int *)(dest + offset);
                        if ((byte *)patchAddressHighLow < image.BasePtr || (byte *)patchAddressHighLow > image.BasePtr + image.Size)
                        {
                            throw new LoadFailedException("This DLL is damaged; relocation table references an illegal 32-bit offset.");
                        }
                        *patchAddressHighLow += (int)delta;
                        break;

                    case RelocationType.Dir64:
                        // Change complete 64-bit address.
                        long *patchAddress64 = (long *)(dest + offset);
                        if ((byte *)patchAddress64 < image.BasePtr || (byte *)patchAddress64 > image.BasePtr + image.Size)
                        {
                            throw new LoadFailedException("This DLL is damaged; relocation table references an illegal 64-bit offset.");
                        }
                        *patchAddress64 += delta;
                        break;

                    default:
                        throw new LoadFailedException(string.Format("This DLL requires unsupported address-relocation type {0} ({1})", type, (int)type));
                    }
                }
            }