示例#1
0
def report(vw):
    res = {}

    for fromva, tova, reftype, rflags in vw.getXrefs():
        if vw.getLocation(tova, range=True) is None:
            rname = v_const.ref_type_names.get(reftype, "Unknown")
            sname = "Unknown"
            seg = vw.getSegment(tova)
            if seg is not None:
                sname = seg[v_const.SEG_NAME]
            try:
                b = e_common.hexify(vw.readMemory(tova, 8))
            except Exception as e:
                b = str(e)
            res[tova] = (b, "%s ref from 0x%x (%s)" % (rname, fromva, sname))

    for va, name in vw.getNames():
        if vw.getLocation(va) is None:
            try:
                b = e_common.hexify(vw.readMemory(tova, 8))
            except Exception as e:
                b = str(e)
            res[va] = (b, name)

    return res
示例#2
0
    def render(self, mcanv, va):
        vastr = self.pformat % va
        # NOTE: we assume the memobj is a trace
        trace = mcanv.mem
        sym = trace.getSymByAddr(va)
        if sym is not None:
            mcanv.addText('\n')
            mcanv.addVaText(str(sym), va=va)
            mcanv.addText(':\n')

        op = trace.parseOpcode(va, arch=self.arch)
        obytes = trace.readMemory(va, op.size)[:8]

        prefix = self._getOpcodePrefix(trace, va, op)
        mcanv.addText(prefix)

        mcanv.addVaText(vastr, va=va)
        mcanv.addText(": %s " % e_common.hexify(obytes).ljust(17))
        op.render(mcanv)

        try:
            suffix = self._getOpcodeSuffix(trace, va, op)
            if suffix:
                mcanv.addText(' ;' + suffix)
        except Exception as e:
            mcanv.addText('; suffix error: %s' % e)

        mcanv.addText("\n")
        return len(op)
示例#3
0
文件: arm.py 项目: sprout42/vivisect
def armthumbdis(db, line, disasmobj):
    '''
    Core of disassmbly, for code-reuse.  Only difference is the object actually
    doing the disassembly.
    '''
    t = db.getTrace()

    argv = e_cli.splitargs(line)
    size = 20
    argc = len(argv)
    if argc == 0:
        addr = t.getProgramCounter()
    else:
        addr = t.parseExpression(argv[0])

    if argc > 1:
        size = t.parseExpression(argv[1])

    bytez = t.readMemory(addr, size)
    offset = 0

    db.vprint("Dissassembly:")
    while offset < size:
        va = addr + offset
        op = disasmobj.disasm(bytez, offset, va)
        obytez = bytez[offset:offset + len(op)]

        db.canvas.addVaText('0x%.8x' % va, va=va)
        db.canvas.addText(": %s " % e_common.hexify(obytez).ljust(17))
        op.render(db.canvas)
        db.canvas.addText("\n")

        offset += len(op)
示例#4
0
    def do_vampsig(self, line):
        """
        Generate a vamp signature string for the given function's first block.
        """
        if not line:
            return self.do_help("vampsig")

        va = self.parseExpression(line)

        fva = self.getFunction(va)
        if fva is None:
            self.vprint("Invalid Function Address: 0x%.8x (%s)" % (va, line))

        sig, mask = viv_vamp.genSigAndMask(self, fva)
        self.vprint("SIGNATURE: %s" % e_common.hexify(sig))
        self.vprint("MASK: %s" % e_common.hexify(mask))
示例#5
0
    def buttonClicked(self):
        curexpr, cur_esize = self.nav.getValues()
        encoding = str(self.mode_combo.currentText())
        rbytes = str(self.data_edit.text())
        erbytes = self.encodeData(rbytes, encoding)

        hexbytes = e_common.hexify(erbytes)
        self.writeToMemory.emit(curexpr, hexbytes)
示例#6
0
 def getNameTag(self, name, typename='name'):
     '''
     Return a "tag" for this memory canvas.  In the case of the
     qt tags, they are a tuple of html text (<opentag>, <closetag>)
     '''
     clsname = 'envi-%s' % typename
     namehex = e_common.hexify(name.lower())
     subclsname = 'envi-%s-%s' % (typename, namehex)
     return ('<span class="%s %s" envitag="%s" envival="%s" onclick="nameclick(this)">' % (clsname,subclsname,typename,namehex), '</span>')
示例#7
0
 def addRandomSeed(self):
     '''
     Add a random seed to the name hashing subsystem.  This will
     produce values which may *only* be compared to other values
     generated by this solver.  It also lets you calculate deltas
     by solving for deltas between two symbols in different seed
     inputs to see if they are likely arithmetically related.
     '''
     self._sym_rseed = e_common.hexify(os.urandom(10))
示例#8
0
def release():

    parser = optparse.OptionParser()

    parser.add_option('--cacert', dest='cacert', default=None)
    parser.add_option('--sslkey', dest='sslkey', default=None)
    parser.add_option('--sslcert', dest='sslcert', default=None)

    opts, argv = parser.parse_args()
    pyzfile, appuri = argv

    with open(__file__, 'rb') as f:
        mainsrc = f.read()
    mainlines = mainsrc.split('\n')[:-2]

    castr = 'None'
    keystr = 'None'
    certstr = 'None'

    if opts.cacert:
        with open(opts.cacert, 'rb') as f:
            castr = '"%s"' % e_common.hexify(f.read())

    if opts.sslkey:
        with open(opts.sslkey, 'rb') as f:
            keystr = '"%s"' % e_common.hexify(f.read())

    if opts.sslcert:
        with open(opts.sslcert, 'rb') as f:
            certstr = '"%s"' % e_common.hexify(f.read())

    mainlines.append('    appuri="%s"' % appuri)
    mainlines.append('    cacrt=%s' % castr)
    mainlines.append('    sslkey=%s' % keystr)
    mainlines.append('    sslcert=%s' % certstr)
    mainlines.append(
        '    main(appuri, cacrt=cacrt, sslcert=sslcert, sslkey=sslkey)')

    mainsrc = '\n'.join(mainlines)

    pyz = zipfile.PyZipFile(pyzfile, 'w')
    pyz.writepy('cobra')
    pyz.writestr('__main__.py', mainsrc)
    pyz.close()
示例#9
0
 def _monitorCommand(self, cmd):
     resp = ''
     cmd = 'qRcmd,%s' % e_common.hexify(cmd)
     pkt = self._cmdTransact(cmd)
     while not pkt.startswith('OK'):
         self._raiseIfError(pkt)
         if not pkt.startswith('O'):
             return binascii.unhexlify(pkt)
         resp += binascii.unhexlify(pkt[1:])
         pkt = self._recvPkt()
     return resp
示例#10
0
 def platformSetRegCtx(self, tid, ctx):
     '''
     Set the target stub's register context from the envi register context
     '''
     # FIXME tid!
     regbytes = binascii.unhexlify(self._cmdTransact('g'))
     regremain = regbytes[self._gdb_regsize:]
     rvals = struct.unpack(self._gdb_regfmt, regbytes[:self._gdb_regsize])
     rvals = list(rvals) # So we can assign to them...
     for myidx, enviidx in self._gdb_reg_xlat:
         rvals[myidx] = ctx.getRegister(enviidx)
     newbytes = struct.pack(self._gdb_regfmt, rvals) + regremain
     return self._cmdTransact('G' + e_common.hexify(newbytes))
示例#11
0
    def do_memcmp(self, line):
        '''
        Compare memory at the given locations.  Outputs a set of
        differences showing bytes at their given offsets....

        Usage: memcmp <addr_expr1> <addr_expr2> <size_expr>
        '''
        if len(line) == 0:
            return self.do_help('memcmp')

        argv = splitargs(line)
        if len(argv) != 3:
            return self.do_help('memcmp')

        addr1 = self.parseExpression(argv[0])
        addr2 = self.parseExpression(argv[1])
        size  = self.parseExpression(argv[2])

        bytes1 = self.memobj.readMemory(addr1, size)
        bytes2 = self.memobj.readMemory(addr2, size)

        res = e_mem.memdiff(bytes1, bytes2)
        if len(res) == 0:
            self.vprint('No Differences!')
            return

        for offset, offsize in res:
            diff1 = addr1+offset
            diff2 = addr2+offset
            self.canvas.addText('==== %d byte difference at offset %d\n' % (offsize,offset))
            self.canvas.addVaText("0x%.8x" % diff1, diff1)
            self.canvas.addText(":")
            self.canvas.addText(e_common.hexify(bytes1[offset:offset+offsize]))
            self.canvas.addText('\n')
            self.canvas.addVaText("0x%.8x" % diff2, diff2)
            self.canvas.addText(":")
            self.canvas.addText(e_common.hexify(bytes2[offset:offset+offsize]))
            self.canvas.addText('\n')
示例#12
0
    def createEventChannel(self, wsname):
        wsinfo = self._req_wsinfo(wsname)
        chan = e_common.hexify(os.urandom(16))

        lock, fpath, pevents, users = wsinfo
        with lock:
            events = []
            events.extend(viv_basicfile.vivEventsFromFile(fpath))
            events.extend(pevents)
            # These must reference the same actual list object...
            queue = e_threads.ChunkQueue(items=events)
            users[chan] = queue
            self.chandict[chan] = [wsinfo, queue]

        return chan
示例#13
0
    def _menuCopyBytesToClipBoard(self, va, currend, all_window_bytes):
        t = self.db.getTrace()
        if all_window_bytes:
            va = self._canv_beginva
            size = self._canv_endva - va

        else:
            if 'asm' in currend:
                op = t.parseOpcode(va)
                size = len(op)
            else:
                size = t.getPointerSize()

        bytez = t.readMemory(va, size)

        clipboard = QApplication.clipboard()
        clipboard.setText(e_common.hexify(bytez))
示例#14
0
    def disasm(self, bytez, offset, va):
        """
        Parse a sequence of bytes out into an envi.Opcode instance.
        """
        opval, = struct.unpack_from('>H', bytez, offset)

        prim = opval >> 8
        opdata = h8_parsers.main_table[prim]

        if opdata is None:
            raise envi.InvalidInstruction(bytez=bytez[offset:offset + 16],
                                          va=va)

        subtable, mnem, decoder, tsize, iflags = opdata

        if subtable:
            raise Exception("NEED subtable at 0x%x:  %s" %
                            (va, e_common.hexify(bytez[offset:offset + 16])))

        elif decoder is not None:
            opcode, nmnem, olist, flags, isize = decoder(
                va, opval, bytez, offset, tsize)
            # print opcode, nmnem, olist, flags, isize, decoder
            if nmnem is not None:
                mnem = nmnem
            iflags |= flags

        else:
            opcode = opval
            isize = 2
            olist = tuple()

        if olist is None:
            raise envi.InvalidInstruction(
                mesg='Operand list cannot be None for instruction "%s"' % mnem,
                bytez=bytez[offset:offset + 16],
                va=va)
        op = h8_operands.H8Opcode(va, opcode, mnem, None, isize, olist, iflags)

        if op.opers is not None:
            # following the nasty little hack from other modules.  "everybody's doing it!"
            for oper in op.opers:
                oper._dis_regctx = self._dis_regctx

        return op
示例#15
0
def dismain(d):
    '''
    Easy utility for implementing stand-alone disassembler utils...
    '''

    # TODO: this belongs as a standalone utility, not in an __init__ file
    if os.path.isfile(sys.argv[1]):
        with open(sys.argv[1], 'rb') as f:
            b = f.read()
    else:
        b = binascii.unhexlify(sys.argv[1])

    offset = 0
    va = 0x41414141
    while offset < len(b):
        op = d.disasm(b, offset, va + offset)
        print('0x%.8x %s %s' %
              (va + offset, e_common.hexify(
                  b[offset:offset + len(op)]).ljust(16), repr(op)))
        offset += len(op)
示例#16
0
    def render(self, mcanv, va):
        trace = mcanv.mem
        max_readable = trace.getMaxReadSize(va)
        if max_readable <= 0:
            return ''
        rsize = min(self.readsize, max_readable)
        bytez = trace.readMemory(va, rsize)

        prettyperm = ''
        mmap = trace.getMemoryMap(va)
        if mmap is not None:
            addr, size, perm, fname = mmap
            prettyperm = e_memory.reprPerms(perm)

        ascii_text = getAsciiFormatted(bytez)
        uni_text = getBasicUnicodeFormatted(bytez)
        sym = getSymByAddrFormatted(trace, va)
        fname = getFilenameFromFdFormatted(trace, va)

        desc = ''
        pdesc = (ascii_text, uni_text, sym, fname)
        items = [ppdesc for ppdesc in pdesc if ppdesc is not None]
        if len(items) == 1:
            desc = items[0]
        elif len(items) == 0:
            # if none match, just return the bytes.
            desc = e_common.hexify(bytez)
        elif len(items) > 1:
            # we only really expect one or none of these to match.
            desc = 'Error, multiple matches for this address!'
        else:
            raise Exception('should never get here')

        best_desc = '%s %s' % (prettyperm, desc)
        chopped_best_desc = best_desc[:self.maxrend]
        if len(best_desc) > len(chopped_best_desc):
            mcanv.addText(' %s...' % chopped_best_desc)
        else:
            mcanv.addText(' %s' % chopped_best_desc)

        return len(chopped_best_desc)
示例#17
0
    def test_parsers_rudimentary(self,
                                 buf=b'ABCDEFGHIJKLMNOP',
                                 off=3,
                                 va=0x2544):
        val, = struct.unpack_from('>H', buf, off)

        for tsize in (1, 2, 4):
            p_i3_Rd(va, val, buf, off, tsize)
            p_i3_aERd(va, val, buf, off, tsize)
            p_i3_aAA8(va, val, buf, off, tsize)
            p_i8_CCR(va, val, buf, off, tsize)
            p_i8_Rd(va, val, buf, off, tsize)
            p_i16_Rd(va, val, buf, off, tsize)
            p_i32_ERd(va, val, buf, off, tsize)
            p_Rd(va, val, buf, off, tsize)
            p_Rs_Rd(va, val, buf, off, tsize)
            p_Rs_Rd_4b(va, val, buf, off, tsize)
            p_Rs_ERd(va, val, buf, off, tsize)
            p_Rs_ERd_4b(va, val, buf, off, tsize)
            p_ERd(va, val, buf, off, tsize)
            p_ERs_ERd(va, val, buf, off, tsize)
            p_Rn_Rd(va, val, buf, off, tsize)
            p_Rn_aERd(va, val, buf, off, tsize)
            p_Rn_aAA8(va, val, buf, off, tsize)
            p_aERn(va, val, buf, off, tsize)
            p_aAA24(va, val, buf, off, tsize)
            p_aaAA8(va, val, buf, off, tsize)
            p_disp8(va, val, buf, off, tsize)
            p_disp16(va, val, buf, off, tsize)
            p_nooperands(va, val, buf, off, tsize)

        h8m = envi.getArchModule('h8')

        for instr in raw_instrs:
            inst = binascii.unhexlify(instr[0])
            op = h8m.archParseOpcode(inst, 0, 0x50)
            if len(op) != len(inst):
                raise Exception(
                    " LENGTH FAILURE:  %s '%s'  expected: %d  real: %d  '%s'" %
                    (instr[0], op, len(inst), len(op), e_common.hexify(inst)))
示例#18
0
def thumb(db, line):
    '''
    Disassemble thumb instructions from the given address.

    Usage: thumb <addr_exp>
    '''
    t = db.getTrace()

    d = e_thumb.ArmThumbDisasm()

    argv = e_cli.splitargs(line)
    size = 20
    argc = len(argv)
    if argc == 0:
        addr = t.getProgramCounter()
    else:
        addr = t.parseExpression(argv[0])

    if argc > 1:
        size = t.parseExpression(argv[1])

    bytes = t.readMemory(addr, size)
    offset = 0

    db.vprint("Dissassembly:")
    while offset < size:
        va = addr + offset
        op = d.disasm(bytes, offset, va)
        obytes = bytes[offset:offset + len(op)]

        db.canvas.addVaText('0x%.8x' % va, va=va)
        db.canvas.addText(": %s " % e_common.hexify(obytes).ljust(17))
        op.render(db.canvas)
        db.canvas.addText("\n")

        offset += len(op)
示例#19
0
def _loadMacho(vw, filebytes, filename=None, baseaddr=None):

    # We fake them to *much* higher than norm so pointer tests do better...
    if baseaddr is None:
        baseaddr = vw.config.viv.parsers.macho.baseaddr

    if filename is None:
        filename = 'macho_%.8x' % baseaddr  # FIXME more than one!

    # grab md5 and sha256 hashes before we modify the bytes
    fhash = viv_parsers.md5Bytes(filebytes)
    sha256 = viv_parsers.sha256Bytes(filebytes)

    # Check for the FAT binary magic...
    if e_common.hexify(filebytes[:4]) in ('cafebabe', 'bebafeca'):

        archhdr = None
        fatarch = vw.config.viv.parsers.macho.fatarch

        archlist = []

        offset = 0
        fat = vsm_fat.fat_header()
        offset = fat.vsParse(filebytes, offset=offset)
        if fat.magic in vsm_const.FAT_64:
            archcon = vsm_fat.fat_arch_64
        else:
            archcon = vsm_fat.fat_arch

        for i in range(fat.nfat_arch):
            ar = archcon()
            offset = ar.vsParse(filebytes, offset=offset)
            archname = vs_macho.mach_cpu_names.get(ar.cputype)
            if archname == fatarch:
                archhdr = ar
                break
            archlist.append((archname, ar))

        if not archhdr:
            # If we don't have a specified arch, exception!
            vw.vprint('Mach-O Fat Binary Architectures:')
            for archname, ar in archlist:
                vw.vprint('0x%.8x 0x%.8x %s' % (ar.offset, ar.size, archname))
            raise Exception(
                'Mach-O Fat Binary: Please specify arch with -O viv.parsers.macho.fatarch="<archname>"'
            )

        filebytes = filebytes[archhdr.offset:archhdr.offset + archhdr.size]

    # Instantiate the parser wrapper and parse bytes
    macho = vs_macho.mach_o()
    macho.vsParse(filebytes)

    arch = vs_macho.mach_cpu_names.get(macho.mach_header.cputype)
    if arch is None:
        raise Exception('Unknown MACH-O arch: %.8x' %
                        macho.mach_header.cputype)

    # Setup arch/plat/fmt
    vw.setMeta('Architecture', arch)
    vw.setMeta("Platform", "Darwin")
    vw.setMeta("Format", "macho")

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

    # Add the file entry

    fname = vw.addFile(filename, baseaddr, fhash)
    vw.setFileMeta(fname, 'sha256', sha256)

    # Add the memory maps and segments from the macho definition
    for segname, rva, perms, segbytes in macho.getSegments():
        segbase = baseaddr + rva
        vw.addMemoryMap(segbase, perms, fname, segbytes)
        vw.addSegment(segbase, len(segbytes), segname, fname)

    # Add the library dependancies
    for libname in macho.getLibDeps():
        # FIXME hack....
        libname = libname.split('/')[-1]
        libname = libname.split('.')[0].lower()
        vw.addLibraryDependancy(libname)

    return fname
示例#20
0
 def platformWriteMemory(self, addr, mbytes):
     cmd = 'M%x,%x:%s' % (addr, len(mbytes), e_common.hexify(mbytes))
     pkt = self._cmdTransact(cmd)
示例#21
0
    def do_search(self, line):
        '''
        search memory for patterns.

        search [options] <pattern>

        -e  <codec> encode the pattern with a codec (hex, utf-16le, etc)
        -X  pattern is in hex (ie. 41414242 is AABB)
        -E  pattern is an envi memory expression (numeric search)
        -r  pattern is a regular expression
        -R  <baseexpr:sizeexpr> search a range of memory (base + size)
        -c  show context (32 bytes) after each hit
        '''
        parser = VOptionParser()
        parser.add_option('-e', action='store', dest='encode_as')
        parser.add_option('-X', action='store_true', dest='is_hex')
        parser.add_option('-E', action='store_true', dest='is_expr')
        parser.add_option('-r', action='store_true', dest='is_regex')
        parser.add_option('-R', action='store', dest='range_search')
        parser.add_option('-c', action='store_const', dest='num_context_bytes',
                const=32)

        argv = shlex.split(line)
        try:
            options, args = parser.parse_args(argv)
        except Exception as e:
            self.vprint(repr(e))
            return self.do_help('search')

        pattern = (' '.join(args)).encode('utf-8')
        if len(pattern) == 0:
            self.vprint('you must specify a pattern')
            return self.do_help('search')

        if options.is_expr:
            sval = self.parseExpression(pattern)
            endian = self.memobj.getEndian()
            size = self.memobj.getPointerSize()
            pattern = e_bits.buildbytes(sval, size, bigend=endian)

        if options.is_hex:
            pattern = binascii.unhexlify(pattern)

        if options.encode_as is not None:
            if options.encode_as == 'hex':
                pattern = e_common.hexify(pattern)
            else:
                import codecs
                patternutf8 = pattern.decode('utf-8')
                pattern = codecs.encode(patternutf8, encoding=options.encode_as)

        if options.range_search:
            try:
                addrexpr, sizeexpr = options.range_search.split(":")
            except Exception as e:
                self.vprint(repr(e))
                return self.do_help('search')
            addr = self.parseExpression(addrexpr)
            size = self.parseExpression(sizeexpr)

            self.canvas.addText('searching from ')
            self.canvas.addVaText('0x%.8x' % addr, addr)
            self.canvas.addText(' for %d bytes\n' % size)
            res = self.memobj.searchMemoryRange(pattern, addr, size, regex=options.is_regex)
        else:
            self.vprint('searching all memory...')
            res = self.memobj.searchMemory(pattern, regex=options.is_regex)

        if len(res) == 0:
            self.vprint('pattern not found: %s (%s)' % (e_common.hexify(pattern), repr(pattern)))
            return

        brend = e_render.ByteRend()
        self.vprint('matches for: %s (%s)' % (e_common.hexify(pattern), repr(pattern)))
        for va in res:
            mbase,msize,mperm,mfile = self.memobj.getMemoryMap(va)
            pname = e_mem.reprPerms(mperm)
            sname = self.reprPointer(va)

            self.canvas.addVaText('0x%.8x' % va, va)
            self.canvas.addText(': ')
            self.canvas.addText('%s ' % pname)
            self.canvas.addText(sname)

            if options.num_context_bytes is not None:
                self.canvas.addText('\n')
                self.canvas.renderMemory(va, options.num_context_bytes, rend=brend)

            self.canvas.addText('\n')

        self.vprint('done (%d results).' % len(res))
示例#22
0
def hooks(vdb, line):
    '''
    Check the executable regions of the target process for any
    hooks by comparing against the PE on disk.  This will
    account for relocations and import entries.
    '''
    t = vdb.getTrace()
    bases = t.getMeta("LibraryBases")
    paths = t.getMeta("LibraryPaths")
    found = False
    for bname in bases.keys():
        base = bases.get(bname)
        fpath = paths.get(base)
        with open(fpath, 'rb') as fd:
            pobj = PE.PE(fpath)
            filebase = pobj.IMAGE_NT_HEADERS.OptionalHeader.ImageBase

            skips = {}
            # Get relocations for skipping
            r = list(range(t.getPointerSize()))
            for relrva, reltype in pobj.getRelocations():
                for i in r:
                    skips[base + relrva + i] = True

            # Add the import entries to skip
            for iva, libname, name in pobj.getImports():
                for i in r:
                    skips[base + iva + i] = True

            for sec in pobj.getSections():
                if sec.Characteristics & PE.IMAGE_SCN_MEM_EXECUTE:
                    size = sec.VirtualSize
                    va = base + sec.VirtualAddress
                    fileva = filebase + sec.VirtualAddress
                    filebytes = pobj.readAtRva(sec.VirtualAddress,
                                               sec.VirtualSize)
                    procbytes = t.readMemory(va, size)

                    for off, size in bindiff(filebytes, procbytes):
                        difva = va + off
                        fdifva = fileva + off

                        # Check for a relocation covering this...
                        if skips.get(difva):
                            continue

                        found = True
                        dmem = e_common.hexify(procbytes[off:off + size])[:10]
                        dfil = e_common.hexify(filebytes[off:off + size])[:10]

                        vdb.canvas.addVaText('0x%.8x' % difva, difva)
                        vdb.canvas.addText(' (0x%.8x) (%d)' % (fdifva, size))
                        vdb.canvas.addText(' mem: %s file: %s ' % (dmem, dfil))

                        sym = vdb.symobj.getSymByAddr(difva, exact=False)
                        if sym is not None:
                            vdb.canvas.addText(' ')
                            vdb.canvas.addVaText(
                                '%s + %d' % (repr(sym), difva - int(sym)),
                                difva)
                        vdb.canvas.addText('\n')

    if not found:
        vdb.canvas.addText('No Hooks Found!\n')
示例#23
0
    def menuCopyBytesToClipboard(self, va, size):
        bytez = self.mem.readMemory(va, size)

        clipboard = QApplication.clipboard()
        clipboard.setText(e_common.hexify(bytez))
示例#24
0
    def renderLocation(self, mcanv, loc, name, isfunc, cmnt, extra):
        """
        Actually render a given VA to the given text buffer.

        If there is *any* function to optimize, this is it... it renders EVERYTHING...
        """
        lva, lsize, ltype, tinfo = loc

        vatag = mcanv.getVaTag(lva)
        cmnttag = mcanv.getTag("comment")

        seg = self.vw.getSegment(lva)
        segname = "map" if seg is None else seg[SEG_NAME]

        vastr = self.vw.arch.pointerString(lva)
        linepre = "%s:%s  " % (segname, vastr)

        xrefs = self.vw.getXrefsTo(lva)

        xrcount = len(xrefs)

        if seg is not None and self._show_segment:
            segva, segsize, segname, segfname = seg
            if segva == lva:
                mcanv.addText(linepre, tag=vatag)
                mcanv.addText("Segment: %s (%d bytes) FIXME PERMS\n" %
                              (segname, segsize))

        if isfunc:
            mcanv.addText(linepre, tag=vatag)
            mcanv.addText('\n')

            mcanv.addText(linepre, tag=vatag)
            mcanv.addText("FUNC: ")

            api = self.vw.getFunctionApi(lva)
            rtype, rname, convname, apiname, apiargs = api
            mcanv.addNameText(rtype)
            mcanv.addText(' ')
            mcanv.addNameText(convname)
            mcanv.addText(' ')
            mcanv.addText(name, tag=vatag)

            mcanv.addText("( ")
            for typename, argname in apiargs:
                mcanv.addNameText(typename)
                mcanv.addText(' ')
                mcanv.addNameText(argname)
                mcanv.addText(', ')

            mcanv.addText(")")

            # FIXME color code and get args parsing goin on
            mcanv.addText(" ")
            xrtag = mcanv.getTag("xrefs")
            mcanv.addText("[%d XREFS]\n" % xrcount, tag=xrtag)

            mcanv.addText(linepre, tag=vatag)
            mcanv.addText('\n')

            mcanv.addText(linepre, tag=vatag)

            mcanv.addText('Stack Variables:\n')

            funclocals = self.vw.getFunctionLocals(lva)
            funclocals.sort()
            funclocals.reverse()

            for _, spdelta, _, _ in funclocals:
                # Make the workspace do the resolving for us
                typename, varname = self.vw.getFunctionLocal(lva, spdelta)
                mcanv.addText(linepre, tag=vatag)
                mcanv.addText('        ')
                mcanv.addText('%4d: ' % spdelta)
                mcanv.addNameText(typename)
                mcanv.addText(' ')
                mcanv.addNameText(varname)
                mcanv.addText('\n')

            mcanv.addText(linepre, tag=vatag)
            mcanv.addText('\n')

        elif xrcount > 0 or name is not None:
            mcanv.addText(linepre, tag=vatag)
            if name is None:
                name = "loc_%.8x" % lva
            mcanv.addText(urllib.parse.quote_plus(name), tag=vatag)
            mcanv.addText(": ")
            xrtag = mcanv.getTag("xrefs")
            mcanv.addText('[%d XREFS]\n' % xrcount, tag=xrtag)

        if ltype == LOC_OP:
            mcanv.addText(linepre, tag=vatag)
            opbytes = mcanv.mem.readMemory(lva, lsize)
            mcanv.addText(e_common.hexify(opbytes[:8]).ljust(17))

            # extra is the opcode object
            try:
                extra.render(mcanv)
            except Exception as e:
                mcanv.addText("Opcode Render Failed: %s (%s)\n" %
                              (repr(extra), str(e)))

            if cmnt is not None:
                mcanv.addText("    ;%s" % cmnt, tag=cmnttag)

            mcanv.addText("\n")

        elif ltype == LOC_STRUCT:

            for soff, sind, sname, sobj in extra.vsGetPrintInfo():

                sva = lva + soff

                if soff != 0:
                    vastr = self.vw.arch.pointerString(sva)
                    linepre = '%s:%s  ' % (segname, vastr)
                    vatag = mcanv.getVaTag(sva)

                mcanv.addText(linepre, tag=vatag)

                totag = None
                if isinstance(sobj, vs_prims.v_ptr):
                    stova = int(sobj)
                    stoname = self.vw.getName(stova)
                    if stoname is None:
                        stoname = repr(sobj)
                    if self.vw.isValidPointer(stova):
                        totag = mcanv.getVaTag(stova)

                # Insert the field name (and indent)
                mcanv.addText("  " * sind)
                mcanv.addNameText(sname)
                mcanv.addText(": ")

                # Insert the sobj info (if it's a primitive)
                if isinstance(sobj, vs_prims.v_prim):
                    if totag is not None:
                        mcanv.addText(stoname, tag=totag)
                    else:
                        mcanv.addText(repr(sobj))

                if soff != 0:
                    xrefs = self.vw.getXrefsTo(sva)
                    if len(xrefs):
                        xrtag = mcanv.getTag("xrefs")
                        mcanv.addText("[%d XREFS]" % len(xrefs), tag=xrtag)

                # Handle the comment if present
                cmnt = self.vw.getComment(sva)
                if cmnt is not None:
                    mcanv.addText("    ;%s" % cmnt, tag=cmnttag)

                mcanv.addText("\n")

        elif ltype == LOC_POINTER:

            fromva, tova, rtype, rflags = self.vw.getXrefsFrom(lva)[
                0]  # FIXME hardcoded one

            mcanv.addText(linepre, tag=vatag)
            mcanv.addNameText("ptr: ")

            totag = mcanv.getVaTag(tova)
            pstr = self.vw.arch.pointerString(tova)

            mcanv.addText(pstr, tag=totag)

            name = self.vw.getName(tova)
            if name is None:
                name = "loc_%.8x" % tova  # FIXME 64bit

            mcanv.addText(" (")
            mcanv.addText(name, tag=totag)
            mcanv.addText(")")
            if cmnt is not None:
                mcanv.addText("    ;%s" % cmnt, tag=cmnttag)
            mcanv.addText("\n")

        elif ltype == LOC_UNDEF:

            mcanv.addText(linepre, vatag)
            offset, bytez = self.vw.getByteDef(lva)
            b = bytez[offset:offset + 1]
            mcanv.addNameText(b.hex(), typename="undefined")

            try:
                b = b.decode('utf-8')
                if b in string.printable:
                    mcanv.addText('    %s' % repr(b), tag=cmnttag)
            except:
                # if we don't decode correctly, don't print it.
                pass

            if cmnt is not None:
                mcanv.addText('    ;%s' % cmnt, tag=cmnttag)

            mcanv.addText("\n")

        elif ltype == LOC_IMPORT:

            mcanv.addText(linepre, vatag)
            tva = self.vw.vaByName(tinfo)
            mcanv.addText('IMPORT: ')
            if tva is not None:
                mcanv.addVaText(tinfo, tva)
            else:
                mcanv.addText(tinfo)

            if cmnt is not None:
                mcanv.addText("    ;%s" % cmnt, tag=cmnttag)

            mcanv.addText("\n")

        else:
            tagname = loc_type_names.get(ltype, None)
            if tagname is None:
                tagname = "location"

            ltag = mcanv.getTag(tagname)
            cdone = False
            for line in self.vw.reprLocation(loc).split("\n"):
                mcanv.addText(linepre, tag=vatag)
                mcanv.addText(line, ltag)
                if not cdone:
                    cdone = True
                    if cmnt is not None:
                        mcanv.addText("    ;%s" % cmnt, tag=cmnttag)
                mcanv.addText("\n")