Ejemplo n.º 1
0
    static bool PerformBaseRelocation(ref IMAGE_NT_HEADERS OrgNTHeaders, IntPtr pCode, IntPtr delta)
    {
        if (OrgNTHeaders.OptionalHeader.BaseRelocationTable.Size == 0)
        {
            return(delta == IntPtr.Zero);
        }

        for (IntPtr pRelocation = PtrAdd(pCode, OrgNTHeaders.OptionalHeader.BaseRelocationTable.VirtualAddress);;)
        {
            IMAGE_BASE_RELOCATION Relocation = PtrRead <IMAGE_BASE_RELOCATION>(pRelocation);
            if (Relocation.VirtualAdress == 0)
            {
                break;
            }

            IntPtr pDest    = PtrAdd(pCode, Relocation.VirtualAdress);
            IntPtr pRelInfo = PtrAdd(pRelocation, Sz.IMAGE_BASE_RELOCATION);
            uint   RelCount = ((Relocation.SizeOfBlock - Sz.IMAGE_BASE_RELOCATION) / 2);
            for (uint i = 0; i != RelCount; i++, pRelInfo = PtrAdd(pRelInfo, sizeof(ushort)))
            {
                ushort relInfo           = (ushort)Marshal.PtrToStructure(pRelInfo, typeof(ushort));
                BasedRelocationType type = (BasedRelocationType)(relInfo >> 12); // the upper 4 bits define the type of relocation
                int    offset            = (relInfo & 0xfff);                    // the lower 12 bits define the offset
                IntPtr pPatchAddr        = PtrAdd(pDest, offset);

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

                case BasedRelocationType.IMAGE_REL_BASED_HIGHLOW:
                    // change complete 32 bit address
                    int patchAddrHL = (int)Marshal.PtrToStructure(pPatchAddr, typeof(int));
                    patchAddrHL += (int)delta;
                    Marshal.StructureToPtr(patchAddrHL, pPatchAddr, false);
                    break;

                case BasedRelocationType.IMAGE_REL_BASED_DIR64:
                    long patchAddr64 = (long)Marshal.PtrToStructure(pPatchAddr, typeof(long));
                    patchAddr64 += (long)delta;
                    Marshal.StructureToPtr(patchAddr64, pPatchAddr, false);
                    break;
                }
            }

            // advance to next relocation block
            pRelocation = PtrAdd(pRelocation, Relocation.SizeOfBlock);
        }
        return(true);
    }
Ejemplo n.º 2
0
        private bool PerformBaseRelocation(PtrDiffT delta)
        {
            int imageSizeOfBaseRelocation   = Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));
            IMAGE_DATA_DIRECTORY *directory = &_headers->OptionalHeader.BaseRelocationTable;

            if (directory->Size == 0)
            {
                return(delta == 0);
            }

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

                    for (int i = 0; i < ((relocation->SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++, relInfo++)
                    {
                        // the upper 4 bits define the type of relocation
                        BasedRelocationType type = (BasedRelocationType)(*relInfo >> 12);
                        // the lower 12 bits define the offset
                        int offset = *relInfo & 0xfff;

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

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

                        case BasedRelocationType.IMAGE_REL_BASED_DIR64:
                            ulong *patchAddr64  = (ulong *)(dest + offset);
                            *      patchAddr64 += (ulong)delta;
                            break;

                        default:
                            break;
                        }
                    }
                    // advance to next relocation block
                    relocation = (IMAGE_BASE_RELOCATION *)(((byte *)relocation) + relocation->SizeOfBlock);
                }
            }
            return(true);
        }