Exemplo n.º 1
0
def applyRelocs(elf, vw, addbase=False, baseaddr=0):
    # process relocations / strings (relocs use Dynamic Symbols)
    arch = arch_names.get(elf.e_machine)
    relocs = elf.getRelocs()
    logger.debug("reloc len: %d", len(relocs))
    for r in relocs:
        rtype = Elf.getRelocType(r.r_info)
        rlva = r.r_offset
        if addbase:
            rlva += baseaddr
        try:
            # If it has a name, it's an externally
            # resolved "import" entry, otherwise, just a regular reloc
            name = r.getName()
            dmglname = demangle(name)
            logger.debug('relocs: 0x%x: %r  (%r)', rlva, dmglname, name)
            if arch in ('i386', 'amd64'):
                if name:
                    if rtype == Elf.R_X86_64_IRELATIVE:
                        # before making import, let's fix up the pointer as a BASEPTR Relocation
                        ptr = r.r_addend
                        vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)
                        logger.info('Reloc: R_X86_64_IRELATIVE 0x%x', rlva)

                    if rtype in (Elf.R_386_JMP_SLOT, Elf.R_X86_64_GLOB_DAT, Elf.R_X86_64_IRELATIVE):
                        logger.info('Reloc: making Import 0x%x (name: %s/%s) ', rlva, name, dmglname)
                        vw.makeImport(rlva, "*", dmglname)
                        vw.setComment(rlva, name)

                    elif rtype in (Elf.R_386_32, Elf.R_386_COPY):
                        pass

                    else:
                        logger.warn('unknown reloc type: %d %s (at %s)', rtype, name, hex(rlva))
                        logger.info(r.tree())
                       
                else:
                    symidx = Elf.getRelocSymTabIndex(r.r_info)
                    sym = elf.getDynSymbol(symidx)
                    ptr = sym.st_value

                    if rtype == Elf.R_386_RELATIVE: # R_X86_64_RELATIVE is the same number
                        ptr = vw.readMemoryPtr(rlva)
                        logger.info('R_386_RELATIVE: adding Relocation 0x%x -> 0x%x (name: %s) ', rlva, ptr, dmglname)
                        vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)

                    elif rtype == Elf.R_X86_64_IRELATIVE:
                        # first make it a relocation that is based on the imagebase
                        ptr = r.r_addend
                        logger.info('R_X86_64_IRELATIVE: adding Relocation 0x%x -> 0x%x (name: %r %r) ', rlva, ptr, name, dmglname)
                        vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)

                        # next get the target and find a name, since the reloc itself doesn't have one
                        tgt = vw.readMemoryPtr(rlva)
                        tgtname = vw.getName(tgt)
                        if tgtname is not None:
                            logger.info('   name(0x%x): %r', tgt, tgtname)
                            fn, symname = tgtname.split('.', 1)
                            logger.info('Reloc: making Import 0x%x (name: %s.%s) ', rlva, fn, symname)
                            vw.makeImport(rlva, fn, symname)

                    else:
                        logger.warn('unknown reloc type: %d %s (at %s)', rtype, name, hex(rlva))
                        logger.info(r.tree())


            if arch in ('arm', 'thumb', 'thumb16'):
                if rtype == Elf.R_ARM_JUMP_SLOT:
                    symidx = Elf.getRelocSymTabIndex(r.r_info)
                    sym = elf.getDynSymbol(symidx)
                    ptr = sym.st_value

                    #quick check to make sure we don't provide this symbol
                    if ptr:
                        logger.info('R_ARM_JUMP_SLOT: adding Relocation 0x%x -> 0x%x (%s) ', rlva, ptr, dmglname)
                        if addbase:
                            vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)
                        else:
                            vw.addRelocation(rlva, vivisect.RTYPE_BASERELOC, ptr)
                        pname = "ptr_%s_%.8x" % (name, rlva)
                        if vw.vaByName(pname) is None:
                            vw.makeName(rlva, pname)

                        if addbase:
                            ptr += baseaddr
                        vw.makeName(ptr, name)
                        vw.setComment(ptr, dmglname)

                    else:
                        logger.info('R_ARM_JUMP_SLOT: adding Import 0x%x (%s) ', rlva, dmglname)
                        vw.makeImport(rlva, "*", dmglname)
                        vw.setComment(rlva, name)
                    
                elif rtype == Elf.R_ARM_GLOB_DAT:
                    symidx = Elf.getRelocSymTabIndex(r.r_info)
                    sym = elf.getDynSymbol(symidx)
                    ptr = sym.st_value

                    #quick check to make sure we don't provide this symbol
                    if ptr:
                        logger.info('R_ARM_GLOB_DAT: adding Relocation 0x%x -> 0x%x (%s) ', rlva, ptr, dmglname)
                        vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)
                        pname = "ptr_%s" % name
                        if vw.vaByName(pname) is None:
                            vw.makeName(rlva, pname)

                        if addbase:
                            ptr += baseaddr
                        vw.makeImport(ptr, "*", dmglname)
                        vw.setComment(ptr, name)

                    else:
                        logger.info('R_ARM_GLOB_DAT: adding Import 0x%x (%s) ', rlva, dmglname)
                        vw.makeImport(rlva, "*", dmglname)
                        vw.setComment(rlva, name)

                elif rtype == Elf.R_ARM_ABS32:
                    symidx = Elf.getRelocSymTabIndex(r.r_info)
                    sym = elf.getDynSymbol(symidx)
                    ptr = sym.st_value

                    if ptr:
                        logger.info('R_ARM_ABS32: adding Relocation 0x%x -> 0x%x (%s) ', rlva, ptr, dmglname)
                        vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)
                        pname = "ptr_%s" % name
                        if vw.vaByName(pname) is None and len(name):
                            vw.makeName(rlva, pname)

                    else:
                        logger.info('R_ARM_ABS32: adding Import 0x%x (%s) ', rlva, dmglname)
                        vw.makeImport(rlva, "*", dmglname)
                        vw.setComment(rlva, name)

                    vw.setComment(rlva, dmglname)

                elif rtype == Elf.R_ARM_RELATIVE:   # Adjust locations for the rebasing
                    ptr = vw.readMemoryPtr(rlva)
                    logger.info('R_ARM_RELATIVE: adding Relocation 0x%x -> 0x%x (name: %s) ', rlva, ptr, dmglname)
                    vw.addRelocation(rlva, vivisect.RTYPE_BASEPTR, ptr)
                    if len(name):
                        vw.makeName(rlva, dmglname, makeuniq=True)
                        vw.setComment(rlva, name)

                else:
                    logger.warn('unknown reloc type: %d %s (at %s)', rtype, name, hex(rlva))
                    logger.info(r.tree())

        except vivisect.InvalidLocation as e:
            logger.warn("NOTE\t%r", e)