Beispiel #1
0
        private void LoadImportReferencesFromRelaPlt()
        {
            var rela_plt = loader.GetSectionInfoByName(".rela.plt");
            var plt      = loader.GetSectionInfoByName(".plt");

            if (rela_plt == null || plt == null)
            {
                return;
            }
            var relaRdr = loader.CreateReader(rela_plt.FileOffset);

            for (ulong i = 0; i < rela_plt.EntryCount(); ++i)
            {
                // Read the .rela.plt entry
                var rela = Elf64_Rela.Read(relaRdr);

                ulong sym     = rela.r_info >> 32;
                var   fileOff = rela_plt.LinkedSection !.FileOffset;
                if (fileOff == 0)
                {
                    continue;
                }
                var symStr = loader.Symbols[fileOff][(int)sym];

                var addr = plt.Address !+(uint)(i + 1) * plt.EntrySize;
                var st   = ElfLoader.GetSymbolType(symStr);
                if (st.HasValue)
                {
                    importReferences ![addr] = new NamedImportReference(addr, null, symStr.Name, st.Value);
Beispiel #2
0
        /// <summary>
        /// Generate GOT entries for the global (imported) symbols of the MIPS ELF binary
        /// </summary>
        /// <remarks>
        /// The Elf MIPS ABI specifies that the GOT entries for import symbols are located after
        /// the GOT entries for the local functions. In addition they are orderd in the same order
        /// as the corresponding symbols in the symbol table.
        /// </remarks>
        private void LocateGlobalGotEntries(Program program, SortedList <Address, ImageSymbol> symbols)
        {
            var dynamic     = loader.DynamicEntries;
            var uAddrSymtab = (uint)dynamic[ElfDynamicEntry.DT_SYMTAB].UValue;
            var allSymbols  = loader.DynamicSymbols;

            var cLocalSymbols  = (int)dynamic[ElfDynamicEntry.Mips.DT_MIPS_GOTSYM].SValue;
            var cTotalSymbols  = (int)dynamic[ElfDynamicEntry.Mips.DT_MIPS_SYMTABNO].SValue;
            var cGlobalSymbols = cTotalSymbols - cLocalSymbols;

            var numberoflocalPointers          = (int)dynamic[ElfDynamicEntry.Mips.DT_MIPS_LOCAL_GOTNO].SValue;
            var uAddrBeginningOfGot            = (uint)dynamic[ElfDynamicEntry.DT_PLTGOT].UValue;
            var uAddrBeginningOfGlobalPointers = uAddrBeginningOfGot + (uint)numberoflocalPointers * PointerByteSize;

            for (int i = 0; i < cGlobalSymbols; ++i)
            {
                var addrGot = Address.Ptr32(uAddrBeginningOfGlobalPointers + PointerByteSize * (uint)i);
                var iSymbol = cLocalSymbols + i;
                if (allSymbols.TryGetValue(iSymbol, out var symbol) &&
                    symbol.Type == ElfSymbolType.STT_FUNC)
                {
                    // This GOT entry is a known symbol!
                    ImageSymbol symGotEntry = loader.CreateGotSymbol(addrGot, symbol.Name);
                    symbols[addrGot] = symGotEntry;
                    Debug.Print("Found GOT entry at {0}, changing symbol at {1}", symGotEntry, addrGot);
                    var st = ElfLoader.GetSymbolType(symbol);
                    if (st.HasValue)
                    {
                        program.ImportReferences[addrGot] = new NamedImportReference(addrGot, null, symbol.Name, st.Value);
                    }
                }
            }
        }
Beispiel #3
0
        public override ElfSymbol RelocateEntry(Program program, ElfSymbol symbol, ElfSection referringSection, ElfRelocation rela)
        {
            var rt = (SuperHrt)(byte)rela.Info;

            if (rt == SuperHrt.R_SH_GLOB_DAT ||
                rt == SuperHrt.R_SH_JMP_SLOT)
            {
                var addrPfn = Address.Ptr32((uint)rela.Offset);
                Debug.Print("Import reference {0} - {1}", addrPfn, symbol.Name);
                var st = ElfLoader.GetSymbolType(symbol);
                if (st.HasValue)
                {
                    program.ImportReferences[addrPfn] = new NamedImportReference(addrPfn, null, symbol.Name, st.Value);
                }
                return(symbol);
            }
            return(symbol);
        }
Beispiel #4
0
        public override ElfSymbol RelocateEntry(Program program, ElfSymbol sym, ElfSection referringSection, ElfRelocation rela)
        {
            if (loader.Sections.Count <= sym.SectionIndex)
            {
                return(sym);
            }
            var rt = (SparcRt)(rela.Info & 0xFF);

            if (sym.SectionIndex == 0)
            {
                if (rt == SparcRt.R_SPARC_GLOB_DAT ||
                    rt == SparcRt.R_SPARC_JMP_SLOT)
                {
                    var addrPfn = Address.Ptr32((uint)rela.Offset);
                    Debug.Print("Import reference {0} - {1}", addrPfn, sym.Name);
                    var st = ElfLoader.GetSymbolType(sym);
                    if (st.HasValue)
                    {
                        importReferences[addrPfn] = new NamedImportReference(addrPfn, null, sym.Name, st.Value);
                    }
                    return(sym);
                }
            }

            var     symSection = loader.Sections[(int)sym.SectionIndex];
            uint    S          = (uint)sym.Value + symSection.Address.ToUInt32();
            int     A          = 0;
            int     sh         = 0;
            uint    mask       = ~0u;
            Address addr;

            if (referringSection != null)
            {
                addr = referringSection.Address + rela.Offset;
            }
            else
            {
                addr = Address.Ptr32((uint)rela.Offset);
            }
            uint P  = (uint)addr.ToLinear();
            uint PP = P;
            uint B  = 0;

            Debug.Print("  off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2} {5}",
                        rela.Offset,
                        (SparcRt)(rela.Info & 0xFF),
                        sym.Name,
                        rela.Addend,
                        (int)(rela.Info >> 8),
                        "section?");

            switch (rt)
            {
            case 0:
                return(sym);

            case SparcRt.R_SPARC_HI22:
                A  = (int)rela.Addend;
                sh = 10;
                P  = 0;
                break;

            case SparcRt.R_SPARC_LO10:
                A    = (int)rela.Addend;
                mask = 0x3FF;
                P    = 0;
                break;

            case SparcRt.R_SPARC_32:
                A    = (int)rela.Addend;
                mask = 0xFFFFFFFF;
                P    = 0;
                break;

            case SparcRt.R_SPARC_WDISP30:
                A  = (int)rela.Addend;
                P  = ~P + 1;
                sh = 2;
                break;

            case SparcRt.R_SPARC_RELATIVE:
                A = (int)rela.Addend;
                B = program.SegmentMap.BaseAddress.ToUInt32();
                break;

            case SparcRt.R_SPARC_COPY:
                Debug.Print("Relocation type {0} not handled yet.", rt);
                return(sym);

            default:
                throw new NotImplementedException(string.Format(
                                                      "SPARC ELF relocation type {0} not implemented yet.",
                                                      rt));
            }
            var arch = program.Architecture;
            var relR = program.CreateImageReader(arch, addr);
            var relW = program.CreateImageWriter(arch, addr);

            var w = relR.ReadBeUInt32();

            w += ((uint)(B + S + A + P) >> sh) & mask;
            relW.WriteBeUInt32(w);

            return(sym);
        }
Beispiel #5
0
        public override ElfSymbol RelocateEntry(Program program, ElfSymbol sym, ElfSection referringSection, ElfRelocation rela)
        {
            var rt = (x86_64Rt)(rela.Info & 0xFF);

            if (loader.Sections.Count <= sym.SectionIndex)
            {
                return(sym);
            }
            if (rt == x86_64Rt.R_X86_64_GLOB_DAT ||
                rt == x86_64Rt.R_X86_64_JUMP_SLOT)
            {
                var addrPfn = Address.Ptr64(rela.Offset);

                var st = ElfLoader.GetSymbolType(sym);
                if (!st.HasValue)
                {
                    return(sym);
                }
                importReferences.Add(addrPfn, new NamedImportReference(addrPfn, null, sym.Name, st.Value));
                var gotSym = loader.CreateGotSymbol(addrPfn, sym.Name);
                imageSymbols.Add(addrPfn, gotSym);
                return(sym);
            }
            if (sym.SectionIndex == 0)
            {
                return(sym);
            }
            var     symSection = loader.Sections[(int)sym.SectionIndex];
            ulong   S          = (ulong)sym.Value + symSection.Address.ToLinear();
            long    A          = 0;
            int     sh         = 0;
            uint    mask       = ~0u;
            Address addr;
            ulong   P;

            if (referringSection?.Address != null)
            {
                addr = referringSection.Address + rela.Offset;
                P    = addr.ToLinear();
            }
            else
            {
                addr = Address.Ptr64(rela.Offset);
                P    = 0;
            }
            var   arch = program.Architecture;
            var   relR = program.CreateImageReader(arch, addr);
            var   relW = program.CreateImageWriter(arch, addr);
            ulong PP   = P;

            switch (rt)
            {
            case x86_64Rt.R_X86_64_NONE: //  just ignore (common)
                break;

            case x86_64Rt.R_X86_64_COPY:
                break;

            default:
                Debug.Print("x86_64 ELF relocation type {0} not implemented yet.",
                            rt);
                break;
                //throw new NotImplementedException(string.Format(
                //    "x86_64 ELF relocation type {0} not implemented yet.",
                //    rt));
            }
            if (relR != null)
            {
                var w = relR.ReadUInt64();
                w += ((ulong)(S + (ulong)A + P) >> sh) & mask;
                relW.WriteUInt64(w);
            }
            return(sym);
        }
Beispiel #6
0
        public override (Address?, ElfSymbol?) RelocateEntry(Program program, ElfSymbol sym, ElfSection?referringSection, ElfRelocation rela)
        {
            if (loader.Sections.Count <= sym.SectionIndex)
            {
                return(null, null);
            }
            var rt = (SparcRt)(rela.Info & 0xFF);

            var addr = referringSection != null
                 ? referringSection.Address !+rela.Offset
                 : loader.CreateAddress(rela.Offset);

            if (sym.SectionIndex == 0)
            {
                if (rt == SparcRt.R_SPARC_GLOB_DAT ||
                    rt == SparcRt.R_SPARC_JMP_SLOT)
                {
                    var addrPfn = Address.Ptr32((uint)rela.Offset);
                    ElfImageLoader.trace.Verbose("Import reference {0} - {1}", addrPfn, sym.Name);
                    var st = ElfLoader.GetSymbolType(sym);
                    if (st.HasValue)
                    {
                        importReferences[addrPfn] = new NamedImportReference(addrPfn, null, sym.Name, st.Value);
                    }
                    return(addrPfn, null);
                }
            }

            var   symSection = loader.Sections[(int)sym.SectionIndex];
            ulong S          = 0;
            int   A          = 0;
            int   sh         = 0;
            uint  mask       = ~0u;

            if (referringSection != null)
            {
                addr = referringSection.Address !+rela.Offset;
            }
            else
            {
                addr = Address.Ptr64(rela.Offset);
            }
            ulong P  = addr.ToLinear();
            ulong PP = P;
            ulong B  = 0;

            ElfImageLoader.trace.Verbose("  off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2} {5}",
                                         rela.Offset,
                                         (SparcRt)(rela.Info & 0xFF),
                                         sym.Name,
                                         rela.Addend.HasValue ? rela.Addend.Value : 0,
                                         (int)(rela.Info >> 8),
                                         "section?");

            switch (rt)
            {
            case 0:
                return(null, null);

            case SparcRt.R_SPARC_HI22:
                A    = (int)rela.Addend !.Value;
                sh   = 10;
                P    = 0;
                mask = 0x3FFFFF;
                return(Relocate32(program, sym, addr, S, A, sh, mask, P, B));

            case SparcRt.R_SPARC_LM22:
                A    = (int)rela.Addend !.Value;
                S    = sym.Value;
                sh   = 10;
                P    = 0;
                mask = 0x3FFFFF;
                return(Relocate32(program, sym, addr, S, A, sh, mask, P, B));

            case SparcRt.R_SPARC_LO10:
                A    = (int)rela.Addend !.Value;
                S    = sym.Value;
                mask = 0x3FF;
                P    = 0;
                return(Relocate32(program, sym, addr, S, A, sh, mask, P, B));

            case SparcRt.R_SPARC_32:
                A    = (int)rela.Addend !.Value;
                S    = sym.Value;
                mask = 0xFFFFFFFF;
                P    = 0;
                return(Relocate32(program, sym, addr, S, A, sh, mask, P, B));

            case SparcRt.R_SPARC_WDISP30:
                A  = (int)rela.Addend !.Value;
                P  = ~P + 1;
                sh = 2;
                return(Relocate32(program, sym, addr, S, A, sh, mask, P, B));

            case SparcRt.R_SPARC_RELATIVE:
                A = (int)rela.Addend !.Value;
                B = program.SegmentMap.BaseAddress.ToLinear();
                P = 0;
                return(Relocate64(program, sym, addr, S, A, sh, mask, P, B));

            case SparcRt.R_SPARC_COPY:
                ElfImageLoader.trace.Warn("Relocation type {0} not handled yet.", rt);
                return(addr, null);

            default:
                ElfImageLoader.trace.Error(
                    "SPARC ELF relocation type {0} not implemented yet.",
                    rt);
                return(addr, null);
            }
        }
Beispiel #7
0
        public override (Address?, ElfSymbol?) RelocateEntry(Program program, ElfSymbol sym, ElfSection?referringSection, ElfRelocation rela)
        {
            if (loader.Sections.Count <= sym.SectionIndex)
            {
                return(null, null);
            }
            var rt = (SparcRt)(rela.Info & 0xFF);

            if (sym.SectionIndex == 0)
            {
                if (rt == SparcRt.R_SPARC_GLOB_DAT ||
                    rt == SparcRt.R_SPARC_JMP_SLOT)
                {
                    var addrPfn = Address.Ptr32((uint)rela.Offset);
                    Debug.Print("Import reference {0} - {1}", addrPfn, sym.Name);
                    var st = ElfLoader.GetSymbolType(sym);
                    if (st.HasValue)
                    {
                        importReferences[addrPfn] = new NamedImportReference(addrPfn, null, sym.Name, st.Value);
                    }
                    return(addrPfn, null);
                }
            }

            var     symSection = loader.Sections[(int)sym.SectionIndex];
            uint    S          = (uint)sym.Value + symSection.Address !.ToUInt32();
            int     A          = 0;
            int     sh         = 0;
            uint    mask       = ~0u;
            Address addr;

            if (referringSection != null)
            {
                addr = referringSection.Address !+rela.Offset;
            }
            else
            {
                addr = Address.Ptr32((uint)rela.Offset);
            }
            uint P  = (uint)addr.ToLinear();
            uint PP = P;
            uint B  = 0;

            Debug.Print("  off:{0:X8} type:{1,-16} add:{3,-20} {4,3} {2} {5}",
                        rela.Offset,
                        (SparcRt)(rela.Info & 0xFF),
                        sym.Name,
                        rela.Addend,
                        (int)(rela.Info >> 8),
                        "section?");

            switch (rt)
            {
            case 0:
                return(addr, null);

            case SparcRt.R_SPARC_HI22:
                A  = (int)rela.Addend;
                sh = 10;
                P  = 0;
                break;

            case SparcRt.R_SPARC_LO10:
                A    = (int)rela.Addend;
                mask = 0x3FF;
                P    = 0;
                break;

            case SparcRt.R_SPARC_32:
                A    = (int)rela.Addend;
                mask = 0xFFFFFFFF;
                P    = 0;
                break;

            case SparcRt.R_SPARC_WDISP30:
                A  = (int)re