Пример #1
0
    def read_phdrs(self, at_phdr=None, at_phnum=None):
        '''
        Using the auxv array information, read and populate the phdrs list.

        @type  at_phdr: Integer 
        @param at_phdr: Location of the program headers

        @type  at_phnum: Integer
        @param at_phnum: Number of program headers
        '''

        if at_phdr == None:
            print "Location (AT_PHDR) could not be read, exiting"
            self.doexit()
        if at_phnum == None:
            print "Number (AT_PHNUM) could not be read, exiting"
            self.doexit()

        location = at_phdr

        for count in xrange(at_phnum):
            if CPU_WORD_SIZE == 4:
                length = len(Elf.Elf32Pheader())
                self.phdrs.append(\
                    Elf.Elf32Pheader(self.read_memory_libc(location,length)))
            elif CPU_WORD_SIZE == 8:
                length = len(Elf.Elf64Pheader())
                self.phdrs.append(\
                    Elf.Elf64Pheader(self.read_memory_libc(location,length)))

            location = location + length
Пример #2
0
 def test_minimal(self):
     for path in (('linux','amd64','static64.llvm.elf'), ('linux','i386','static32.llvm.elf')):
         logger.warn("======== %r ========", path)
         fn = helpers.getTestPath(*path)
         e = Elf.Elf(file(fn))
         vw = viv_cli.VivCli()
         vw.loadFromFile(fn)
Пример #3
0
    def parseBinary(self):
        typemap = {
            Elf.STT_FUNC: vtrace.SYM_FUNCTION,
            Elf.STT_SECTION: vtrace.SYM_SECTION,
            Elf.STT_OBJECT: vtrace.SYM_GLOBAL
        }

        elf = Elf.Elf(self.filename)
        base = self.loadbase

        # Quick pass to see if we need to assume prelink
        for sec in elf.sections:
            if sec.name != ".text":
                continue
            # Try to detect prelinked
            if sec.sh_addr != sec.sh_offset:
                base = 0
            break

        for sec in elf.sections:
            self.addSymbol(sec.name, sec.sh_addr + base, sec.sh_size,
                           vtrace.SYM_SECTION)

        for sym in elf.symbols:
            self.addSymbol(sym.name, sym.st_value + base, sym.st_size,
                           typemap.get((sym.st_info & 0xf), vtrace.SYM_MISC))

        for sym in elf.dynamic_symbols:
            self.addSymbol(sym.name, sym.st_value + base, sym.st_size,
                           typemap.get((sym.st_info & 0xf), vtrace.SYM_MISC))
Пример #4
0
    def test_files(self):
        results = []
        for name, test_data, path in self.data:
            logger.warning("======== %r ========", name)
            fn = helpers.getTestPath(*path)
            e = Elf.Elf(open(fn, 'rb'))
            vw = viv_cli.VivCli()
            vw.loadFromFile(fn)

            do_analyze(vw)

            logger.debug("testing %r (%r)...", name, fn)
            retval = self.do_file(vw, test_data, name)
            results.append(retval)

        failed = 0
        for fidx, tres in enumerate(results):
            for testname, testdata in tres.items():
                if testdata != (0, 0):
                    failed += testdata[0] + testdata[1]
                    fname = self.data[fidx][0]
                    failed_old, failed_new = testdata
                    logger.error('%s:  %s: missing: %r   new: %r (%r)', fname, testname, failed_old, failed_new, fname)

        self.assertEqual(failed, 0, msg="ELF Tests Failed (see error log)")
Пример #5
0
    def platformParseBinary(self, filename, baseaddr, normname):
        typemap = {
            Elf.STT_FUNC: e_resolv.FunctionSymbol,
            Elf.STT_SECTION: e_resolv.SectionSymbol,
        }

        fd = file(filename, 'rb')
        elf = Elf.Elf(fd)
        addbase = 0
        if not elf.isPreLinked() and elf.isSharedObject():
            addbase = baseaddr

        for sec in elf.sections:
            sym = e_resolv.SectionSymbol(sec.name, sec.sh_addr + addbase,
                                         sec.sh_size, normname)
            self.addSymbol(sym)

        for sym in elf.symbols:
            symclass = typemap.get((sym.st_info & 0xf), e_resolv.Symbol)
            sym = symclass(sym.name, sym.st_value + addbase, sym.st_size,
                           normname)
            self.addSymbol(sym)

        for sym in elf.dynamic_symbols:
            symclass = typemap.get((sym.st_info & 0xf), e_resolv.Symbol)
            sym = symclass(sym.name, sym.st_value + addbase, sym.st_size,
                           normname)
            self.addSymbol(sym)
Пример #6
0
    def dynamic_array_entry_generator(self, offset):
        '''
        Iterate over the dynamic array entries.  It will automatically
        seek() via the reads.  We do an infinite loop since we don't 
        know where DT_NULL will be found.

        @type  offset: Integer
        @param offset: Offset to where the dynamic array can be found
        '''

        while 1:
            self.elf.seek(offset, 0)
            offset = offset + CPU_WORD_SIZE * 2

            if CPU_WORD_SIZE == 4:
                yield Elf.Elf32Dynamic(self.elf.read(CPU_WORD_SIZE * 2))
            elif CPU_WORD_SIZE == 8:
                yield Elf.Elf64Dynamic(self.elf.read(CPU_WORD_SIZE * 2))
Пример #7
0
 def DISABLEtest_minimal(self):
     '''
     Until we've got soe decent tests for this, all this does is prolong the test time
     '''
     for path in (('linux','amd64','static64.llvm.elf'), ('linux','i386','static32.llvm.elf')):
         logger.warning("======== %r ========", path)
         fn = helpers.getTestPath(*path)
         e = Elf.Elf(open(fn, 'rb'))
         vw = viv_cli.VivCli()
         vw.loadFromFile(fn)
Пример #8
0
def makeRelocTable(vw, va, maxva, addbase, baseaddr, addend=False):
    if addend:
        sname = 'elf.Elf%dReloca' % (vw.getPointerSize() * 8)
    else:
        sname = 'elf.Elf%dReloc' % (vw.getPointerSize() * 8)

    while va < maxva:
        s = vw.makeStructure(va, sname)
        tname = Elf.r_types_386.get(Elf.getRelocType(s.r_info), "Unknown Type")
        vw.setComment(va, tname)
        va += len(s)
Пример #9
0
    def platformParseBinary(self, filename, baseaddr, normname):
        typemap = {
            Elf.STT_FUNC: e_resolv.FunctionSymbol,
            Elf.STT_SECTION: e_resolv.SectionSymbol,
        }

        try:
            fd = self.platformOpenFile(filename)
            elf = Elf.Elf(fd)
        except IOError:
            try:
                # it's possible we hit vdso or something similar
                elf = Elf.elfFromMemoryObject(self, baseaddr)
            except:
                raise
        # elf = Elf.Elf(fd)
        addbase = 0
        if not elf.isPreLinked() and elf.isSharedObject():
            addbase = baseaddr

        for sec in elf.sections:
            sym = e_resolv.SectionSymbol(sec.name, sec.sh_addr + addbase,
                                         sec.sh_size, normname)
            self.addSymbol(sym)

        for sym in elf.symbols:
            symclass = typemap.get((sym.st_info & 0xf), e_resolv.Symbol)
            sym = symclass(sym.name, sym.st_value + addbase, sym.st_size,
                           normname)
            self.addSymbol(sym)

        for sym in elf.dynamic_symbols:
            symclass = typemap.get((sym.st_info & 0xf), e_resolv.Symbol)
            sym = symclass(sym.name, sym.st_value + addbase, sym.st_size,
                           normname)
            self.addSymbol(sym)

        if elf.isExecutable():
            sym = e_resolv.Symbol('__entry', elf.e_entry, 0, normname)
            self.addSymbol(sym)
Пример #10
0
def update_elfDict(game, my_elves):
    global elfDict
    if my_elves:  # add new and delete old elves from the dictionary
        for elf in my_elves:  # add new
            if elf.unique_id not in elfDict.keys():
                elfDict[elf.unique_id] = Elf(game, elf)

        for uid in elfDict.keys():  # delete old
            if uid not in [elf.unique_id for elf in my_elves]:
                del elfDict[uid]
    else:  # if we have no elves just clear the dictionary
        elfDict.clear()

    for elf in elfDict.values():  # update game for all elf objects
        elf.game = game
Пример #11
0
    def parse_dt_symtab(self, dyn):
        '''
        Callback responsible for parsing the DT_SYMTAB dynamic array entry.
        Currently this just locates where the .symtab section is.

        Override this function to perform your own analysis on DT_SYMTAB.

        @type  dyn: ElfXXDynamic
        @param dyn: Dynamic array entry
        '''

        if CPU_WORD_SIZE == 4:
            self.elf_header.sections.append(Elf.Elf32Section())
        elif CPU_WORD_SIZE == 8:
            self.elf_header.sections.append(Elf.Elf64Section())

        symtab = self.elf_header.sections[-1]
        symtab.setName(".symtab")

        if self.elf_header.e_type == Elf.ET_EXEC:
            symtab.sh_offset = dyn.d_value
            #XXX: symtab.sh_offset = dyn.d_value - BASEADDR
        elif self.elf_header.e_type == Elf.ET_DYN:
            symtab.sh_offset = dyn.d_value
Пример #12
0
    def find_elf_header(self):
        '''
        Find and populate an ELF header structure.
        Will also clear all section header information since it is invalid.
        '''

        self.elf.seek(0, 0)
        self.elf_header = Elf.Elf(self.elf.read(64))
        self.elf_header.myname = "rebuilt elf header"
        self.elf_header.e_shoff = 0
        self.elf_header.e_shentsize = 0
        self.elf_header.e_shnum = 0
        self.elf_header.e_shstrndx = 0

        self.elf.seek(0, 0)
        self.elf.write(self.elf_header.serialize())
Пример #13
0
 def createUnitToBuy(self):
     self.uniteToBuy = [
         Amazon(),
         Dwarf(),
         Elf(),
         Giant(),
         Hobbit(),
         Humans(),
         Mago(),
         Orc(),
         Rats(),
         Skeletton(),
         Triton(),
         Troll(),
         Wizzard(),
         Zombie()
     ]
     shuffle(self.uniteToBuy)
Пример #14
0
    def setUpClass(cls):
        super(ELFTests, cls).setUpClass()

        cls.tests = []
        for test in data:
            name, test_data, path = test
            logger.warn("======== %r ========", name)
            fn = helpers.getTestPath(*path)
            e = Elf.Elf(file(fn))
            vw = viv_cli.VivCli()
            vw.loadFromFile(fn)
            #vw.analyze()
            vae.analyze(vw)
            vagr.analyze(vw)
            vaeep.analyze(vw)
            vagp.analyze(vw)

            cls.tests.append((name, test_data, fn, e, vw))

        cls.maxDiff = None
Пример #15
0
    def platformParseBinary(self, filename, baseaddr, normname):
        typemap = {
            Elf.STT_FUNC: e_resolv.FunctionSymbol,
            Elf.STT_SECTION: e_resolv.SectionSymbol,
        }

        try:
            fd = self.platformOpenFile(filename)
            elf = Elf.Elf(fd)
        except IOError:
            try:
                # it's possible we hit vdso or something similar
                elf = Elf.elfFromMemoryObject(self, baseaddr)
            except:
                raise
        # elf = Elf.Elf(fd)
        addbase = 0
        if not elf.isPreLinked() and elf.isSharedObject():
            addbase = baseaddr

        for sec in elf.sections:
            sym = e_resolv.SectionSymbol(sec.name, sec.sh_addr+addbase, sec.sh_size, normname)
            self.addSymbol(sym)

        for sym in elf.symbols:
            symclass = typemap.get((sym.st_info & 0xf), e_resolv.Symbol)
            sym = symclass(sym.name, sym.st_value+addbase, sym.st_size, normname)
            self.addSymbol(sym)

        for sym in elf.dynamic_symbols:
            symclass = typemap.get((sym.st_info & 0xf), e_resolv.Symbol)
            sym = symclass(sym.name, sym.st_value+addbase, sym.st_size, normname)
            self.addSymbol(sym)

        if elf.isExecutable():
            sym = e_resolv.Symbol('__entry', elf.e_entry, 0, normname)
            self.addSymbol(sym)
Пример #16
0
    def __init__(self, name, trace=None, verbose=False):
        self.binexe = name.split(os.sep)[-1]
        self.verbose = verbose
        self.locsec = None
        self.bin = None
        self.startaddress = None
        self.eip = 0
        self.lastcall = (0, 0)  # last target and last source address
        if os.name == 'posix':
            self.bin = Elf(argv[1])
            self.startaddress = self.bin.e_entry
        elif os.name == 'nt':
            self.bin = PE(argv[1])
            self.startaddress = self.bin.OPTIONAL_HEADER.AddressOfEntryPoint + self.bin.OPTIONAL_HEADER.ImageBase

        self.me = getTrace()
        self.me.registerNotifier(NOTIFY_EXIT, VerboseNotifier())
        self.me.registerNotifier(NOTIFY_BREAK, VerboseNotifier())
        self.me.registerNotifier(NOTIFY_LOAD_LIBRARY, LibraryNotifier())
        self.me.addBreakpoint(
            Breakpoint(self.startaddress)
        )  # This should get us past the loader code into the actual start of the binary
        self.me.metadata['RUN'] = True
        self.me.execute(argv[1])
Пример #17
0
def parseFd(vw, fd, filename=None, baseaddr=None):
    fd.seek(0)
    elf = Elf.Elf(fd)
    return loadElfIntoWorkspace(vw, elf, filename=filename, baseaddr=baseaddr)
Пример #18
0
def parseBytes(vw, bytes, baseaddr=None):
    fd = StringIO(bytes)
    elf = Elf.Elf(fd)
    return loadElfIntoWorkspace(vw, elf, baseaddr=baseaddr)
Пример #19
0
def parseFile(vw, filename, baseaddr=None):
    fd = open(filename, 'rb')
    elf = Elf.Elf(fd)
    return loadElfIntoWorkspace(vw, elf, filename=filename, baseaddr=baseaddr)
Пример #20
0
def loadElfIntoWorkspace(vw, elf, filename=None):

    arch = arch_names.get(elf.e_machine)
    if arch == None:
        raise Exception("Unsupported Architecture: %d\n", elf.e_machine)

    platform = elf.getPlatform()

    # setup needed platform/format
    vw.setMeta('Architecture', arch)
    vw.setMeta('Platform', platform)
    vw.setMeta('Format', 'elf')

    vw.setMeta('DefaultCall', archcalls.get(arch, 'unknown'))

    vw.addNoReturnApi("*.exit")

    # Base addr is earliest section address rounded to pagesize
    # NOTE: This is only for prelink'd so's and exe's.  Make something for old style so.
    addbase = False
    if not elf.isPreLinked() and elf.isSharedObject():
        addbase = True
    baseaddr = elf.getBaseAddress()

    #FIXME make filename come from dynamic's if present for shared object
    if filename == None:
        filename = "elf_%.8x" % baseaddr

    fhash = "unknown hash"
    if os.path.exists(filename):
        fhash = v_parsers.md5File(filename)

    fname = vw.addFile(filename.lower(), baseaddr, fhash)

    strtabs = {}
    secnames = []
    for sec in elf.getSections():
        secnames.append(sec.getName())

    pgms = elf.getPheaders()
    secs = elf.getSections()

    for pgm in pgms:
        if pgm.p_type == Elf.PT_LOAD:
            if vw.verbose: vw.vprint('Loading: %s' % (repr(pgm)))
            bytez = elf.readAtOffset(pgm.p_offset, pgm.p_filesz)
            bytez += "\x00" * (pgm.p_memsz - pgm.p_filesz)
            pva = pgm.p_vaddr
            if addbase: pva += baseaddr
            vw.addMemoryMap(pva, pgm.p_flags & 0x7, fname, bytez)  #FIXME perms
        else:
            if vw.verbose: vw.vprint('Skipping: %s' % repr(pgm))

    if len(pgms) == 0:
        # fall back to loading sections as best we can...
        if vw.verbose: vw.vprint('elf: no program headers found!')

        maps = [[s.sh_offset, s.sh_size] for s in secs
                if s.sh_offset and s.sh_size]
        maps.sort()

        merged = []
        for i in xrange(len(maps)):

            if merged and maps[i][0] == (merged[-1][0] + merged[-1][1]):
                merged[-1][1] += maps[i][1]
                continue

            merged.append(maps[i])

        baseaddr = 0x05000000
        for offset, size in merged:
            bytez = elf.readAtOffset(offset, size)
            vw.addMemoryMap(baseaddr + offset, 0x7, fname, bytez)

        for sec in secs:
            if sec.sh_offset and sec.sh_size:
                sec.sh_addr = baseaddr + sec.sh_offset

    # First add all section definitions so we have them
    for sec in secs:
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue  # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        vw.addSegment(sva, size, sname, fname)

    # Now trigger section specific analysis
    for sec in secs:
        #FIXME dup code here...
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue  # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        if sname == ".interp":
            vw.makeString(sva)

        elif sname == ".init":
            vw.makeName(sva, "init_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".fini":
            vw.makeName(sva, "fini_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".dynamic":  # Imports
            makeDynamicTable(vw, sva, sva + size)

        # FIXME section names are optional, use dynamic info from .dynamic
        elif sname == ".dynstr":  # String table for dynamics
            makeStringTable(vw, sva, sva + size)

        elif sname == ".dynsym":
            #print "LINK",sec.sh_link
            for s in makeSymbolTable(vw, sva, sva + size):
                pass
                #print "########################.dynsym",s

        # If the section is really a string table, do it
        if sec.sh_type == Elf.SHT_STRTAB:
            makeStringTable(vw, sva, sva + size)

        elif sec.sh_type == Elf.SHT_SYMTAB:
            makeSymbolTable(vw, sva, sva + size)

        elif sec.sh_type == Elf.SHT_REL:
            makeRelocTable(vw, sva, sva + size, addbase, baseaddr)

        if sec.sh_flags & Elf.SHF_STRINGS:
            print "FIXME HANDLE SHF STRINGS"

    # Let pyelf do all the stupid string parsing...
    for r in elf.getRelocs():
        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
            if arch in ('i386', 'amd64'):

                name = r.getName()
                if name:
                    if rtype == Elf.R_386_JMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    # FIXME elf has conflicting names for 2 relocs?
                    #elif rtype == Elf.R_386_GLOB_DAT:
                    #vw.makeImport(rlva, "*", name)

                    elif rtype == Elf.R_386_32:
                        pass

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' %
                                     (rtype, name, hex(rlva)))

            if arch == 'arm':
                name = r.getName()
                if name:
                    if rtype == Elf.R_ARM_JUMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' %
                                     (rtype, name, hex(rlva)))

        except vivisect.InvalidLocation, e:
            print "NOTE", e
Пример #21
0
def makeRelocTable(vw, va, maxva, addbase, baseaddr):
    while va < maxva:
        s = vw.makeStructure(va, "elf.Elf32Reloc")
        tname = Elf.r_types_386.get(Elf.getRelocType(s.r_info), "Unknown Type")
        vw.setComment(va, tname)
        va += len(s)
Пример #22
0
def loadElfIntoWorkspace(vw, elf, filename=None):

    arch = arch_names.get(elf.e_machine)
    if arch == None:
       raise Exception("Unsupported Architecture: %d\n", elf.e_machine)

    # setup needed platform/format
    vw.setMeta('Architecture', arch)
    vw.setMeta('Platform', 'unknown')
    vw.setMeta('Format', 'elf')

    # FIXME try to determine *which* Elf system...
    if arch == 'i386':
        vw.setMeta("DefaultCall", "cdecl")

    elif arch == 'amd64':
        vw.setMeta("DefaultCall", "sysvamd64call")

    vw.addNoReturnApi("*.exit")

    # Base addr is earliest section address rounded to pagesize
    # NOTE: This is only for prelink'd so's and exe's.  Make something for old style so.
    addbase = False
    if not elf.isPreLinked() and elf.isSharedObject():
        addbase = True
    baseaddr = elf.getBaseAddress()

    #FIXME make filename come from dynamic's if present for shared object
    if filename == None:
        filename = "elf_%.8x" % baseaddr

    fname = vw.addFile(filename, baseaddr, v_parsers.md5File(filename))

    strtabs = {}
    secnames = []
    for sec in elf.getSections():
        secnames.append(sec.getName())

    for pgm in elf.getPheaders():
        if pgm.p_type == Elf.PT_LOAD:
            if vw.verbose: vw.vprint('Loading: %s' % (repr(pgm)))
            bytes = elf.readAtOffset(pgm.p_offset, pgm.p_filesz)
            bytes += "\x00" * (pgm.p_memsz - pgm.p_filesz)
            pva = pgm.p_vaddr
            if addbase: pva += baseaddr
            vw.addMemoryMap(pva, pgm.p_flags & 0x7, fname, bytes) #FIXME perms
        else:
            if vw.verbose: vw.vprint('Skipping: %s' % repr(pgm))

    # First add all section definitions so we have them
    for sec in elf.getSections():
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        vw.addSegment(sva, size, sname, fname)

    # Now trigger section specific analysis
    for sec in elf.getSections():
        #FIXME dup code here...
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        if sname == ".interp":
            vw.makeString(sva)

        elif sname == ".init":
            vw.makeName(sva, "init_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".fini":
            vw.makeName(sva, "fini_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".dynamic": # Imports
            makeDynamicTable(vw, sva, sva+size)

        # FIXME section names are optional, use dynamic info from .dynamic
        elif sname == ".dynstr": # String table for dynamics
            makeStringTable(vw, sva, sva+size)

        elif sname == ".dynsym":
            #print "LINK",sec.sh_link
            for s in makeSymbolTable(vw, sva, sva+size):
                pass
                #print "########################.dynsym",s

        # If the section is really a string table, do it
        if sec.sh_type == Elf.SHT_STRTAB:
            makeStringTable(vw, sva, sva+size)

        elif sec.sh_type == Elf.SHT_SYMTAB:
            # FIXME 32 bit specific!
            #print "FOUND A SYMBOL TABLE!"
            makeSymbolTable(vw, sva, sva+size)

        elif sec.sh_type == Elf.SHT_REL:
            makeRelocTable(vw, sva, sva+size, addbase, baseaddr)

        if sec.sh_flags & Elf.SHF_STRINGS:
            print "FIXME HANDLE SHF STRINGS"

    # Let pyelf do all the stupid string parsing...
    for r in elf.getRelocs():
        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
            if arch in ('i386','amd64'):

                name = r.getName()
                if name:
                    if rtype == Elf.R_386_JMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    # FIXME elf has conflicting names for 2 relocs?
                    #elif rtype == Elf.R_386_GLOB_DAT:
                        #vw.makeImport(rlva, "*", name)

                    elif rtype == Elf.R_386_32:
                        pass

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' % (rtype, name, hex(rlva)))

            if arch == 'arm':
                name = r.getName()
                if name:
                    if rtype == Elf.R_ARM_JUMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' % (rtype, name, hex(rlva)))

        except vivisect.InvalidLocation, e:
            print "NOTE",e
Пример #23
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:
                    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 = r.getSymTabIndex()
                    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 = r.getSymTabIndex()
                    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 = r.getSymTabIndex()
                    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)
Пример #24
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: %s (%s)', 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,
                                   Elf.R_X86_64_TPOFF64):
                        pass

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

                else:
                    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.warning('unknown reloc type: %d %s (at %s)',
                                       rtype, name, hex(rlva))
                        logger.info(r.tree())

            if arch in ('arm', 'thumb', 'thumb16'):
                # ARM REL entries require an addend that could be stored as a
                # number or an instruction!
                import envi.archs.arm.const as eaac
                if r.vsHasField('addend'):
                    # this is a RELA object, bringing its own addend field!
                    addend = r.addend
                else:
                    # otherwise, we have to check the stored value for number or instruction
                    # if it's an instruction, we have to use the immediate value and then
                    # figure out if it's negative based on the instruction!
                    try:
                        temp = vw.readMemoryPtr(rlva)
                        if rtype in Elf.r_armclasses[
                                Elf.
                                R_ARMCLASS_DATA] or rtype in Elf.r_armclasses[
                                    Elf.R_ARMCLASS_MISC]:
                            # relocation points to a DATA or MISCELLANEOUS location
                            addend = temp
                        else:
                            # relocation points to a CODE location (ARM, THUMB16, THUMB32)
                            op = vw.parseOpcode(rlva)
                            for oper in op.opers:
                                if hasattr(oper, 'val'):
                                    addend = oper.val
                                    break

                                elif hasattr(oper, 'offset'):
                                    addend = oper.offset
                                    break

                            lastoper = op.opers[-1]
                            if op.mnem.startswith('sub') or \
                                    op.mnem in ('ldr', 'str') and \
                                    hasattr(lastoper, 'pubwl') and \
                                    not (lastoper.pubwl & eaac.PUxWL_ADD):
                                addend = -addend
                    except Exception as e:
                        logger.exception("ELF: Reloc Addend determination: %s",
                                         e)
                        addend = temp

                logger.debug('addend: 0x%x', addend)

                if rtype == Elf.R_ARM_JUMP_SLOT:
                    symidx = r.getSymTabIndex()
                    sym = elf.getDynSymbol(symidx)
                    ptr = sym.st_value

                    # quick check to make sure we don't provide this symbol
                    # some toolchains like to point the GOT back at it's PLT entry
                    # that does *not* mean it's not an IMPORT
                    if ptr and not isPLT(vw, 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)

                        # name the target as well
                        if addbase:
                            ptr += baseaddr
                        # normalize thumb addresses
                        ptr &= -2
                        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 = r.getSymTabIndex()
                    sym = elf.getDynSymbol(symidx)
                    ptr = sym.st_value

                    if ptr:
                        logger.info(
                            'R_ARM_GLOB_DAT: 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" % 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 = r.getSymTabIndex()
                    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)

                elif rtype == Elf.R_ARM_COPY:
                    pass

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

        except vivisect.InvalidLocation as e:
            logger.warning("NOTE\t%r", e)
def loadElfIntoWorkspace(vw, elf, filename=None):

    arch = arch_names.get(elf.e_machine)
    if arch == None:
        raise Exception("Unsupported Architecture: %d\n", elf.e_machine)

    # setup needed platform/format
    vw.setMeta('Architecture', arch)
    vw.setMeta('Platform', 'unknown')
    vw.setMeta('Format', 'elf')

    # FIXME try to determine *which* Elf system...
    if arch == 'i386':
        vw.setMeta("DefaultCall", "cdecl")

    elif arch == 'amd64':
        vw.setMeta("DefaultCall", "sysvamd64call")

    vw.addNoReturnApi("*.exit")

    # Base addr is earliest section address rounded to pagesize
    # NOTE: This is only for prelink'd so's and exe's.  Make something for old style so.
    addbase = False
    if not elf.isPreLinked() and elf.isSharedObject():
        addbase = True
    baseaddr = elf.getBaseAddress()

    #FIXME make filename come from dynamic's if present for shared object
    if filename == None:
        filename = "elf_%.8x" % baseaddr

    fname = vw.addFile(filename, baseaddr, v_parsers.md5File(filename))

    strtabs = {}
    secnames = []
    for sec in elf.getSections():
        secnames.append(sec.getName())

    for pgm in elf.getPheaders():
        if pgm.p_type == Elf.PT_LOAD:
            if vw.verbose: vw.vprint('Loading: %s' % (repr(pgm)))
            bytes = elf.readAtOffset(pgm.p_offset, pgm.p_filesz)
            bytes += "\x00" * (pgm.p_memsz - pgm.p_filesz)
            pva = pgm.p_vaddr
            if addbase: pva += baseaddr
            vw.addMemoryMap(pva, pgm.p_flags & 0x7, fname, bytes)  #FIXME perms
        else:
            if vw.verbose: vw.vprint('Skipping: %s' % repr(pgm))

    # First add all section definitions so we have them
    for sec in elf.getSections():
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue  # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        vw.addSegment(sva, size, sname, fname)

    # Now trigger section specific analysis
    for sec in elf.getSections():
        #FIXME dup code here...
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue  # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        if sname == ".interp":
            vw.makeString(sva)

        elif sname == ".init":
            vw.makeName(sva, "init_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".fini":
            vw.makeName(sva, "fini_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".dynamic":  # Imports
            makeDynamicTable(vw, sva, sva + size)

        # FIXME section names are optional, use dynamic info from .dynamic
        elif sname == ".dynstr":  # String table for dynamics
            makeStringTable(vw, sva, sva + size)

        elif sname == ".dynsym":
            #print "LINK",sec.sh_link
            for s in makeSymbolTable(vw, sva, sva + size):
                pass
                #print "########################.dynsym",s

        # If the section is really a string table, do it
        if sec.sh_type == Elf.SHT_STRTAB:
            makeStringTable(vw, sva, sva + size)

        elif sec.sh_type == Elf.SHT_SYMTAB:
            # FIXME 32 bit specific!
            #print "FOUND A SYMBOL TABLE!"
            makeSymbolTable(vw, sva, sva + size)

        elif sec.sh_type == Elf.SHT_REL:
            makeRelocTable(vw, sva, sva + size, addbase, baseaddr)

        if sec.sh_flags & Elf.SHF_STRINGS:
            print "FIXME HANDLE SHF STRINGS"

    # Let pyelf do all the stupid string parsing...
    for r in elf.getRelocs():
        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
            if arch in ('i386', 'amd64'):

                name = r.getName()
                if name:
                    if rtype == Elf.R_386_JMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    # FIXME elf has conflicting names for 2 relocs?
                    #elif rtype == Elf.R_386_GLOB_DAT:
                    #vw.makeImport(rlva, "*", name)

                    elif rtype == Elf.R_386_32:
                        pass

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' %
                                     (rtype, name, hex(rlva)))

            if arch == 'arm':
                name = r.getName()
                if name:
                    if rtype == Elf.R_ARM_JUMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' %
                                     (rtype, name, hex(rlva)))

        except vivisect.InvalidLocation, e:
            print "NOTE", e
Пример #26
0
def loadElfIntoWorkspace(vw, elf, filename=None):

    arch = arch_names.get(elf.e_machine)
    if arch == None:
       raise Exception("Unsupported Architecture: %d\n", elf.e_machine)

    platform = elf.getPlatform()

    # setup needed platform/format
    vw.setMeta('Architecture', arch)
    vw.setMeta('Platform', platform)
    vw.setMeta('Format', 'elf')

    vw.setMeta('DefaultCall', archcalls.get(arch,'unknown'))

    vw.addNoReturnApi("*.exit")

    # Base addr is earliest section address rounded to pagesize
    # NOTE: This is only for prelink'd so's and exe's.  Make something for old style so.
    addbase = False
    if not elf.isPreLinked() and elf.isSharedObject():
        addbase = True
    baseaddr = elf.getBaseAddress()

    #FIXME make filename come from dynamic's if present for shared object
    if filename == None:
        filename = "elf_%.8x" % baseaddr

    fhash = "unknown hash"
    if os.path.exists(filename):
        fhash = v_parsers.md5File(filename)

    fname = vw.addFile(filename.lower(), baseaddr, fhash)

    strtabs = {}
    secnames = []
    for sec in elf.getSections():
        secnames.append(sec.getName())

    pgms = elf.getPheaders()
    secs = elf.getSections()

    for pgm in pgms:
        if pgm.p_type == Elf.PT_LOAD:
            if vw.verbose: vw.vprint('Loading: %s' % (repr(pgm)))
            bytez = elf.readAtOffset(pgm.p_offset, pgm.p_filesz)
            bytez += "\x00" * (pgm.p_memsz - pgm.p_filesz)
            pva = pgm.p_vaddr
            if addbase: pva += baseaddr
            vw.addMemoryMap(pva, pgm.p_flags & 0x7, fname, bytez) #FIXME perms
        else:
            if vw.verbose: vw.vprint('Skipping: %s' % repr(pgm))

    if len(pgms) == 0:
        # fall back to loading sections as best we can...
        if vw.verbose: vw.vprint('elf: no program headers found!')

        maps = [ [s.sh_offset,s.sh_size] for s in secs if s.sh_offset and s.sh_size ]
        maps.sort()

        merged = []
        for i in xrange(len(maps)):

            if merged and maps[i][0] == (merged[-1][0] + merged[-1][1]):
                merged[-1][1] += maps[i][1]
                continue

            merged.append( maps[i] )

        baseaddr = 0x05000000
        for offset,size in merged:
            bytez = elf.readAtOffset(offset,size)
            vw.addMemoryMap(baseaddr + offset, 0x7, fname, bytez)

        for sec in secs:
            if sec.sh_offset and sec.sh_size:
                sec.sh_addr = baseaddr + sec.sh_offset

    # First add all section definitions so we have them
    for sec in secs:
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        vw.addSegment(sva, size, sname, fname)

    # Now trigger section specific analysis
    for sec in secs:
        #FIXME dup code here...
        sname = sec.getName()
        size = sec.sh_size
        if sec.sh_addr == 0:
            continue # Skip non-memory mapped sections

        sva = sec.sh_addr
        if addbase: sva += baseaddr

        if sname == ".interp":
            vw.makeString(sva)

        elif sname == ".init":
            vw.makeName(sva, "init_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".fini":
            vw.makeName(sva, "fini_function", filelocal=True)
            vw.addEntryPoint(sva)

        elif sname == ".dynamic": # Imports
            makeDynamicTable(vw, sva, sva+size)

        # FIXME section names are optional, use dynamic info from .dynamic
        elif sname == ".dynstr": # String table for dynamics
            makeStringTable(vw, sva, sva+size)

        elif sname == ".dynsym":
            #print "LINK",sec.sh_link
            for s in makeSymbolTable(vw, sva, sva+size):
                pass
                #print "########################.dynsym",s

        # If the section is really a string table, do it
        if sec.sh_type == Elf.SHT_STRTAB:
            makeStringTable(vw, sva, sva+size)

        elif sec.sh_type == Elf.SHT_SYMTAB:
            makeSymbolTable(vw, sva, sva+size)

        elif sec.sh_type == Elf.SHT_REL:
            makeRelocTable(vw, sva, sva+size, addbase, baseaddr)

        if sec.sh_flags & Elf.SHF_STRINGS:
            print "FIXME HANDLE SHF STRINGS"

    # Let pyelf do all the stupid string parsing...
    for r in elf.getRelocs():
        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
            if arch in ('i386','amd64'):

                name = r.getName()
                if name:
                    if rtype == Elf.R_386_JMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    # FIXME elf has conflicting names for 2 relocs?
                    #elif rtype == Elf.R_386_GLOB_DAT:
                        #vw.makeImport(rlva, "*", name)

                    elif rtype == Elf.R_386_32:
                        pass

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' % (rtype, name, hex(rlva)))

            if arch == 'arm':
                name = r.getName()
                if name:
                    if rtype == Elf.R_ARM_JUMP_SLOT:
                        vw.makeImport(rlva, "*", name)

                    else:
                        vw.verbprint('unknown reloc type: %d %s (at %s)' % (rtype, name, hex(rlva)))

        except vivisect.InvalidLocation, e:
            print "NOTE",e
Пример #27
0
def makeRelocTable(vw, va, maxva, addbase, baseaddr):
    while va < maxva:
        s = vw.makeStructure(va, "elf.Elf32Reloc")
        tname = Elf.r_types_386.get(Elf.getRelocType(s.r_info), "Unknown Type")
        vw.setComment(va, tname)
        va += len(s)
Пример #28
0
def parseFile(vw, filename):
    fd = file(filename, 'rb')
    elf = Elf.Elf(fd)
    return loadElfIntoWorkspace(vw, elf, filename=filename)
Пример #29
0
def parseBytes(vw, bytes):
    fd = StringIO(bytes)
    elf = Elf.Elf(fd)
    return loadElfIntoWorkspace(vw, elf)
Пример #30
0
def load_level():
    global book
    global player
    global timer
    global elements
    global elfs

    values = {}

    file_name = "./Assets/Levels/level1.dat"

    if not os.path.isfile(file_name):
        return False

    else:
        file = open(file_name, "r")

        for line in file.readlines():
            v_n = ""
            v = ""
            s = 0

            for c in line:
                if c == '=':
                    s = 1
                    continue
                elif c == ' ':
                    continue

                if s == 0:
                    v_n = v_n + c
                elif s == 1:
                    v = v + c

            values[v_n] = v.replace('\n', '')

        file.close()

    if not os.path.isfile(values["board"]):
        return False

    else:
        player = Player(int(values["start_x"]), int(values["start_y"]))
        elements = []
        elfs = []

        file = open(values["board"], "r")

        i = 0

        for value in file.readlines():

            nu = ""
            co = ""
            ro = ""
            s = 0

            for c in value:
                if c == '-':
                    s = s + 1
                    continue
                if s == 0:
                    nu = nu + c
                elif s == 1:
                    co = co + c
                elif s == 2:
                    ro = ro + c

            sprite = titles[int(nu)]

            sprite = pygame.transform.rotate(sprite, 90 * int(ro))

            elements.append(
                Element(i % int(values["size_x"]),
                        int(i / int(values["size_x"])), sprite, int(co)))

            i = i + 1

        file.close()

        book = Book(elements)

        for i in range(3):
            elfs.append(Elf(elements, player))

        timer = threading.Thread(target=timer_loop)
        timer.start()