示例#1
0
        public unsafe void DeLocateBuff32(byte[] bytes, uint Delta, uint RVA, Reloc[] relocs)
        {
            // round down to page alignment
            var xVA = RVA & ~4095u;

            byte* basep;

            if (relocs == null)
                return;
                
            fixed(byte* bp = bytes)
            {
                for (int i = 0; i < relocs.Length; i++)
                {
                    if (relocs[i].PageRVA == xVA)
                    {
                        // ANY OVERHANG FROM (LAST-VA == VA-4096), use, otherwise ignore
                        if (OverHang != 0 && (xVA - 4096) == OverHang)
                        {
                            var _3bp = bp;
    
                            // have only written 1 byte in the previous page
                            switch (OvrOffset)
                            {
                                case 1:
                                    if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                    CarryOne = b < ((Delta & 0x0000FF00) >> 8) ? true : false;
                                    *_3bp = (byte)(b - ((Delta & 0xFF00) >> 8));
                                    _3bp++;
                                    if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                    CarryOne = b < ((Delta & 0x00FF0000) >> 16) ? true : false;
                                    *_3bp = (byte)(b - ((Delta & 0x00FF0000) >> 16));
                                    _3bp++;
                                    if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                    CarryOne = b < ((Delta & 0xFF000000) >> 24) ? true : false;
                                    *_3bp = (byte)(b - ((Delta & 0xFF000000) >> 24));
                                    break;
                                case 2:
                                    if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                    CarryOne = b < ((Delta & 0x00FF0000) >> 16) ? true : false;
                                    *_3bp = (byte)(b - ((Delta & 0x00FF0000) >> 16));
                                    _3bp++;
                                    if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                    CarryOne = b < ((Delta & 0xFF000000) >> 24) ? true : false;
                                    *_3bp = (byte)(b - ((Delta & 0xFF000000) >> 24));
                                    break;
                                case 3:
                                    if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                    CarryOne = b < ((Delta & 0xFF000000) >> 24) ? true : false;
                                    *_3bp = (byte)(b - ((Delta & 0xFF000000) >> 24));
                                    break;
                                default:
                                    break;
                            }
                            // reset overhang
                            OverHang = 0;
                            CarryOne = false;
                        }
    
                        for (int j = 0; j < relocs[i].Area.Length; j++)
                        {
                            // their can be a trailing null entry sometimes
                            if (relocs[i].Area[j] == 0)
                                continue;
    
                            // 4KB max limit
                            var offset = (relocs[i].Area[j]) & 0xFFFu;
    
                            // trim offset if we are unaligned reading
                            if (RVA != xVA)
                            {
                                var Unaligned = RVA - xVA;
    
                                // this reloc entry is for an earlier/unaligned page
                                if (offset < Unaligned)
                                    continue;
    
                                offset -= Unaligned;
                            }
    
                            // reset to base pointer every fixup
                            basep = bp;
    
                            // get byte offset
                            basep += offset;
    
                            // WRITE 4
                            if (offset < 4093)
                            {
                                // get int* to byte offset
                                var intp = (uint*)basep;
    
                                var curr = *intp;
    
                                // this has got to be an error
                                //if(curr == 0)
                                //Console::WriteLine("B00G");
    
                                *intp = curr - Delta;
                                OvrOffset = 0;
    
                            }
                            else {
                                var _3bp = basep;
    
                                OverHang = xVA;
                                OvrOffset = (int)(4096 - offset);
    
                                switch (offset)
                                {
                                    // WRITE 3
                                    case 4093:
                                    {
                                        b = *_3bp;
                                        CarryOne = b < (Delta & 0x000000FF) ? true : false;
                                        *_3bp = (byte)(b - (Delta & 0x000000FF));
                                        _3bp++;
                                        if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                        CarryOne = b < ((Delta & 0x0000FF00) >> 8) ? true : false;
                                        *_3bp = (byte)(b - ((Delta & 0x0000FF00) >> 8));
                                        _3bp++;
                                        if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                        CarryOne = b < ((Delta & 0x00FF0000) >> 16) ? true : false;
                                        *_3bp = (byte)(b - ((Delta & 0x00FF0000) >> 16));
                                        break;
                                    }                                // WRITE 2
                                    case 4094:
                                    {
                                        b = *_3bp;
                                        CarryOne = b < (Delta & 0x000000FF) ? true : false;
                                        *_3bp = (byte)(b - (Delta & 0x000000FF));
                                        _3bp++;
                                        if (CarryOne) b = (byte)(*_3bp - 1); else b = *_3bp;
                                        CarryOne = b < ((Delta & 0x0000FF00) >> 8) ? true : false;
                                        *_3bp = (byte)(b - ((Delta & 0x0000FF00) >> 8));
                                        _3bp++;
                                        break;
                                    }                                // WRITE 1
                                    case 4095:
                                    {
                                        b = *_3bp;
                                        CarryOne = b < (Delta & 0x000000FF) ? true : false;
                                        *_3bp = (byte)(b - ((Delta & 0x000000FF)));
                                        break;
                                    }
                                    default:
                                        break;
                                }
                            }
                        }
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// This routine takes a binary .reloc and emit's List of type Reloc
        /// 
        /// There are theoretically some .reloc entries we do not support, I've not seen too many for recent binaries.
        /// 
        /// If we wanted to support more, adding more translations here would be fine.
        /// </summary>
        /// <param name="FileBuff"></param>
        /// <returns></returns>
        public static List<Reloc> ProcessRelocs(byte[] FileBuff)
        {
            var rv = new List<Reloc>();

            using (var ms = new MemoryStream(FileBuff))
            using (var reReader = new BinaryReader(ms))
            {
                var pageRVA = reReader.ReadUInt32();
                var blockSize = reReader.ReadInt32();
                var BlockPos = ms.Position;

                var Count = (blockSize - 8) / 2;

                while (blockSize != 0)
                {
                    var rl = new Reloc { PageRVA = pageRVA, BlockSize = blockSize, Area = new ushort[Count] };
                    for (int i = 0; i < Count; i++)
                        rl.Area[i] = reReader.ReadUInt16();

                    rv.Add(rl);

                    pageRVA = reReader.ReadUInt32();
                    if (pageRVA == 0)
                        break;
                    blockSize = reReader.ReadInt32();
                    if (blockSize == 0)
                        break;

                    Count = (blockSize - 8) / 2;
                }
            }
            return rv;
        }