Exemple #1
0
        public void ImageBaseRelocationConstructorWorks_Test()
        {
            var ibr = new IMAGE_BASE_RELOCATION(RawStructures.RawImageBaseRelocation, 2, 12);

            Assert.Equal((uint)0x10000, ibr.VirtualAddress);
            Assert.Equal((uint)0xc, ibr.SizeOfBlock);
            Assert.Equal(2, ibr.TypeOffsets.Length);
            Assert.Equal(0x2211 >> 12, ibr.TypeOffsets[0].Type);
            Assert.Equal(0x2211 & 0xfff, ibr.TypeOffsets[0].Offset);
            Assert.Equal(0x4433 >> 12, ibr.TypeOffsets[1].Type);
            Assert.Equal(0x4433 & 0xfff, ibr.TypeOffsets[1].Offset);
        }
    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);
    }
Exemple #3
0
        public void PerformBaseRelocation(UInt32 delta)
        {
            IntPtr codeBase   = _module.codeBase;
            Int32  sizeOfBase = Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION));
            IMAGE_DATA_DIRECTORY directory = _module.headers.OptionalHeader.DataDirectory[5];
            Int32 cnt = 0;

            if (directory.Size > 0)
            {
                IMAGE_BASE_RELOCATION relocation = PointerHelpers.ToStruct <IMAGE_BASE_RELOCATION>(codeBase, directory.VirtualAddress);
                while (relocation.VirtualAddress > 0)
                {
                    unsafe
                    {
                        IntPtr  dest    = (IntPtr)(codeBase.ToInt32() + (int)relocation.VirtualAddress);
                        UInt16 *relInfo = (UInt16 *)(codeBase.ToInt32() + (int)directory.VirtualAddress + sizeOfBase);
                        UInt16  i;
                        for (i = 0; i < ((relocation.SizeOfBlock - Marshal.SizeOf(typeof(IMAGE_BASE_RELOCATION))) / 2); i++, relInfo++)
                        {
                            Int32 type   = *relInfo >> 12;
                            Int32 offset = (*relInfo & 0xfff);
                            switch (type)
                            {
                            case 0x00:
                                break;

                            case 0x03:
                                UInt32 *patchAddrHl  = (UInt32 *)((dest.ToInt32()) + (offset));
                                *       patchAddrHl += delta;
                                break;
                            }
                        }
                    }
                    cnt       += (Int32)relocation.SizeOfBlock;
                    relocation = PointerHelpers.ToStruct <IMAGE_BASE_RELOCATION>(codeBase, (UInt32)(directory.VirtualAddress + cnt));
                }
            }
        }
Exemple #4
0
 public void OffsetIsBiggerThanBuffer_Test()
 {
     var ibr = new IMAGE_BASE_RELOCATION(RawStructures.RawImageBaseRelocation, 1234, 12);
 }
Exemple #5
0
 public void SizeOfBlockIsBiggerThanRelocDirSize_Test()
 {
     var rawImageBaseRelocBroken = new byte[]
     { 0x00, 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x30, 0xC4, 0x30 };
     var ibr = new IMAGE_BASE_RELOCATION(rawImageBaseRelocBroken, 0, 0);
 }
        public void SerializeDirectoryInfo_Correct()
        {
            //arrange
            var   imageBaseRelocation = new ImageBaseRelocationSerializer(new TypeOffsetSerializer());
            var   buffer               = new byte[100];
            ulong bufferOffset         = 0;
            var   relocationOffsetList = new List <RelocationTypeOffset>()
            {
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1000
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1020
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1123
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1300
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1300
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1411
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1a1f
                },
                new RelocationTypeOffset()
                {
                    Type = 0x3, Offset = 0x1FFF
                },
            };

            //act
            imageBaseRelocation.Serialize(buffer, ref bufferOffset, relocationOffsetList);

            //assert
            try
            {
                var relocationDirectory = new IMAGE_BASE_RELOCATION(buffer, 0, (uint)relocationOffsetList.Count * 2 + 8);
                Assert.AreEqual((int)relocationDirectory.SizeOfBlock, 0x18);
                Assert.AreEqual((int)relocationDirectory.VirtualAddress, 0x1000);
                Assert.AreEqual(relocationDirectory.TypeOffsets.Length, 8);
                Assert.AreEqual(relocationDirectory.TypeOffsets[0].Type, 0x3);
                Assert.AreEqual(relocationDirectory.TypeOffsets[0].Offset, 0x000);
                Assert.AreEqual(relocationDirectory.TypeOffsets[1].Type, 0x3);
                Assert.AreEqual(relocationDirectory.TypeOffsets[1].Offset, 0x020);
                Assert.AreEqual(relocationDirectory.TypeOffsets[7].Type, 0x3);
                Assert.AreEqual(relocationDirectory.TypeOffsets[7].Offset, 0xFFF);
            }
            catch (Exception ex)
            {
                Assert.Fail("failed to serialize relocation directory: exception", ex.ToString());
            }
        }