예제 #1
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def __str__(self, **kargs):
     ''' text output, to be used by an assembler '''
     out = self.txt(**kargs)
     fmt = '%-50s ## '
     if self.long_display and hasattr(self, 'pic'):
         pic_label, pic_list = self.pic
         pic_list = ';'.join([str(_) for _ in pic_list])
         if pic_label is not None:
             pic_list = "%s:%s" % (pic_label, pic_list)
         out = (fmt + 'PIC:%s') % (out, pic_list)
         fmt = '%-80s # '
     if self.long_display and hasattr(self, 'stack'):
         registers, positions = self.stack
         if isinstance(registers, bool):
             stack_status = '%s:' % registers
         else:
             stack_status = []
             for k in sorted(registers):
                 stack_status.append('%r: %r' %
                                     (k, sorted(list(registers[k]))))
             stack_status = '{' + ', '.join(stack_status) + '}:'
         stack_status += str(tuple(sorted(positions)))
         out = (fmt + 'STACK:%s') % (out, stack_status)
         fmt = '%-80s # '
     if self.long_display and hasattr(self, 'dead'):
         dead = self.dead
         dead = sorted([str(_) for _ in dead])
         out = (fmt + ' DEAD:%s') % (out, ';'.join(dead))
         if hasattr(self, 'pic'):
             for pic in self.pic[1]:
                 for reg in dead:
                     if str(reg) in str(pic):
                         out += ' COLLISION'
     return out
예제 #2
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def get_ancestors(self):
     # if visible symbol, there may be external ancestors
     if self.is_new_object():
         return [None] + sorted(self.graph[1])
     # if parsed from assembly, many elements of the graph are missing,
     # compared to binary parsing, e.g. arrows for switch tables
     if not 'endianess' in self.symbols.meta and self.is_named():
         return [None] + sorted(self.graph[1])
     return sorted(self.graph[1])
예제 #3
0
def do_compare(obj1, obj2, quick=False):
    do_exit = False
    symbols1, dump1 = parse_objdump(obj1, quick=quick)
    symbols2, dump2 = parse_objdump(obj2, quick=quick)
    from difflib import context_diff
    diff = []
    if sorted(symbols1) != sorted(symbols2):
        diff.extend(list(context_diff(symbols1, symbols2, n=1)))
    diff.extend(list(context_diff(dump1, dump2, n=1)))
    return diff
예제 #4
0
def mk_objdump(symbols, filename=None):
    if symbols.file_type != 'ELF':
        return "Cannot output a %s file in objdump format" % symbols.file_type
    import struct
    from elfesteem import elf
    e = symbols.file_elfesteem
    from plasmasm.python.compatibility import hexbytes
    output = "\n"
    filetype = struct.unpack("B",
                             e.Ehdr.ident[elf.EI_CLASS:elf.EI_CLASS + 1])[0]
    if filetype == 1: filetype = 'elf32'
    elif filetype == 2: filetype = 'elf64'
    else: raise ValueError("ELF file class %d" % filetype)
    cputype = {2: 'sparc', 3: 'i386', 62: 'x86-64', 192: 'm8'}
    if e.Ehdr.machine in cputype: cputype = cputype[e.Ehdr.machine]
    else: cputype = "[CPU%d]" % e.Ehdr.machine
    if cputype == 'i386': symbols_set_asm_format(symbols, 'att_syntax objdump')
    output += "%s:     file format %s-%s\n" % (filename, filetype, cputype)
    output += "\n"
    output += "\n"
    symbols_by_section = {}
    for s in symbols.symbols:
        if hasattr(s, 'section') and hasattr(s, 'lines'):
            if not s.section in symbols_by_section:
                symbols_by_section[s.section] = []
            symbols_by_section[s.section].append(s)
    for section in sorted(symbols_by_section):
        output += "Disassembly of section %s:\n" % section
        for s in sorted(symbols_by_section[section], key=lambda x: x.address):
            if s.is_symbol():
                output += "\n"
                output += "%08x <%s>:\n" % (s.address, s)
            ad_fmt = "%4x"
            if s.lines[-1].offset >= 0x1000: ad_fmt = "%8x"
            for l in s.lines:
                output += ad_fmt % l.offset
                output += ":\t"
                b = hexbytes(l.pack())
                if hasattr(l, 'miasm'):
                    output += "%-21s\t%s\n" % (" ".join(b[:7]), l)
                    if len(b) > 7:
                        output += ad_fmt % (l.offset + 7)
                        output += ":\t"
                        output += "%s \n" % (" ".join(b[7:]))
                elif hasattr(l, 'amoco'):
                    lstr = str(l)
                    if lstr in ["nop", "retl"]: lstr += " "
                    output += "%-15s\t%s\n" % (" ".join(b), lstr)
                else:
                    output += "%s\n" % l
    return output[:-1]
예제 #5
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def display(self):
     out = "%s\n" % repr(self)
     if hasattr(self, 'section'):
         out += "    ENDER %s -- NXT %s\n" % (self.ender, self.nxt)
         for cfg in self.cfg:
             out += "    CFG %s\n" % cfg
     for label in sorted(self.graph[0]):
         out += "    GRAPH_NXT %s\n" % label
     for label in sorted(self.graph[1]):
         out += "    GRAPH_PRV %s\n" % label
     out += self.stack.display()
     if hasattr(self, 'lines'):
         for l in self.lines:
             out += "%s\n" % l.display()
     return out
예제 #6
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def find_symbol(self, **props):
     found = self.find_symbols(**props)
     if len(found) == 0: return None
     elif len(found) == 1: return found[0]
     else:
         found = sorted(found, key=lambda x: x.name)
         return getattr(self, 'choose_symbol', lambda _, f: f[0])(found)
예제 #7
0
def update_pic(l, pic):
    # x86 specific, but it should be generalized
    pic_list = pic[1]
    if l.flow in ['sub', 'D.sub']:
        # During a function call, some registers may be overwritten,
        # but edi, esi, ebx, ebp and esp are kept.
        pic_list = [
            _ for _ in pic_list if 'edi' in _ or 'esi' in _ or 'ebx' in _
            or 'ebp' in _ or 'esp' in _
        ]
    else:
        # Delete overwritten registers from pic_list
        # and references (to esp or ebp) if these registers are written
        # Not applied for 'call', because 'call' modifies esp, but it is
        # restored after returning from the call
        for w in l.rw[1]:
            w = str(w)
            pic_list = [_ for _ in pic_list if not w in str(_)]
    if l.opname == 'mov':
        # Add places where the PIC value is stored
        read = str(l.api_arg_txt(1))
        written = str(l.api_arg_txt(0))
        if written in pic_list:
            # Erased
            pic_list.remove(written)
        if read in pic_list:
            # Copied
            pic_list.append(written)
    return (pic[0], tuple(sorted(pic_list)))
예제 #8
0
def test_io(file, suffix, kargs):
    pool = File().from_filename("non_regression/" + file, **kargs)
    fd = open("non_regression/" + file + "." + suffix, "r")
    res = fd.read()
    fd.close()
    from plasmasm import constants
    if "rw" in kargs:
        # Same output as disass.py -rLWT
        pool.arch.set_asm_format('att_syntax')
        pool.arch.long_display = True
        constants.Constant.out_format = None
    else:
        # Same output as disass.py -r
        pool.arch.set_asm_format('raw')
        constants.Constant.out_format = 'raw'
    if "pic" in kargs:
        from staticasm.pic_tracking import analyze_PIC
        analyze_PIC(pool)
        from staticasm.stack_tracking import analyze_stack
        analyze_stack(pool)
    if "dead" in kargs:
        from staticasm.dead_registers import analyze_dead
        analyze_dead(pool)
    rep = [_.display() for _ in pool.blocs]
    rep += [
        _.display() for _ in sorted(
            [s for s in pool.symbols if not s in pool.bloc_set],
            key=lambda x: (getattr(x, 'section', ''), getattr(x, 'address', 0),
                           getattr(x, 'name', None)))
    ]
    rep += [
        str(tuple((s, pool.sections.asm_name[s])))
        for s in sorted(pool.sections.asm_name)
    ]
    rep += [
        ','.join(
            ["%s:%r" % (_, pool.meta[_]) for _ in reversed(sorted(pool.meta))])
    ]
    rep += ['']
    rep = '\n'.join(rep)
    if sys.version_info[0] == 2 and sys.version_info[1] <= 3:
        # long are displayed differently
        import re
        rep = re.sub('([0-9]+)L', '\\1', rep)
    assert rep == res
예제 #9
0
파일: expression.py 프로젝트: LRGH/miasmX
 def __init__(self, dst, src):
     #if dst is slice=> replace with id make composed src
     if isinstance(dst, ExprSlice):
         self.dst = dst.arg
         rest = [(ExprSlice(dst.arg, r[0], r[1]), r[0], r[1])
                 for r in slice_rest(dst.arg.size, dst.start, dst.stop)]
         all_a = sorted([(src, dst.start, dst.stop)] + rest,
                        key=lambda x: x[1])
         self.src = ExprCompose(all_a)
     else:
         self.dst, self.src = dst, src
예제 #10
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def flatten_loop(self, todo=[]):
     # Outputs the list of all known possible stacks
     # Non-recursive variant: stack length may be more than 1000
     todo = [self]  # stacks where nothing is computed
     seen = []  # stacks where all substacks have been added to todo
     done = {}  # stacks that have been flattened
     while len(todo):
         x = todo.pop()
         # If empty, then we are done
         if len(x.stacks) == 0:
             done[x] = []
             continue
         # If not, explore all substacks,
         # in reversed order, to get the same result as the recursive variant
         for pos, stk in reversed(sorted(x.stacks,
                                         key=lambda _: str(_[0]))):
             if not stk in seen and not stk in todo:
                 todo.append(stk)
         seen.append(x)
     while len(seen):
         x = seen.pop()
         # 'x' has substacks, all of them have been done, because
         # they were added to 'seen' after 'x'
         done[x] = []
         for pos, stk in sorted(x.stacks, key=lambda _: str(_[0])):
             # If not in done, it is a recursive stack
             # it is made empty to avoid infinite loops
             stk = done.get(stk, [])
             if stk == []:
                 if not isinstance(pos, StackTopVoid):
                     done[x].append([pos])
             else:
                 if isinstance(pos, StackTopVoid): pos = []
                 else: pos = [pos]
                 for s in stk:
                     s = pos + s
                     if not s == [] and not s in done[x]:
                         done[x].append(s)
     return done[self]
예제 #11
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def repr_attr(self, f, _stack={}):
     v = getattr(self, f)
     # _stack is added to detect recursion loops
     # not necessary with CPython, but necessary with Pypy
     if v.__class__ == tuple:
         if (self, f) in _stack:
             return "%s=(...)" % f
         else:
             _stack[(self, f)] = 1
     if type(v) == dict:
         v = ','.join([
             "%s:%s" % (k, v[k])
             for k in sorted(v.keys(), key=lambda a: str(a))
         ])
     if v.__class__.__name__ == 'long':
         return "%s=%s" % (f, v)
     return "%s=%r" % (f, v)
예제 #12
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def flatten_recursive(self, marked=None):
     # Outputs the list of all known possible stacks
     if marked is None: marked = set()
     if self in marked: return []
     out = []
     marked.add(self)
     for pos, stk in sorted(self.stacks, key=lambda _: str(_[0])):
         stk = stk.flatten_recursive(marked)
         if stk == []:
             if not isinstance(pos, StackTopVoid):
                 out.append([pos])
         else:
             if isinstance(pos, StackTopVoid):
                 pos = []
             else:
                 pos = [pos]
             for s in stk:
                 out.append(pos + s)
     return out
예제 #13
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def display(self):
     ''' (long) display of internals of the instruction '''
     out = str(type(self))
     out = out.replace("<class '", "'")
     if hasattr(self, 'offset'):
         out += "%s " % self.offset
     if self.flow != False:
         out += "[%s]" % self.flow
     if hasattr(self, 'immutable'):
         out += "[immutable=%s]" % self.immutable
     out += self.txt()
     if self.long_display:
         if hasattr(self, 'rw'):
             out += "\n\t R%s W%s" % (sorted([
                 self.reg_name(r) for r in self.rw[0]
             ]), sorted([self.reg_name(r) for r in self.rw[1]]))
         if hasattr(self, 'dead'):
             out += "\n\t D%s" % (sorted(
                 [self.reg_name(r) for r in self.dead]))
         if hasattr(self, 'pic'):
             pic_label, pic_list = self.pic
             pic_list = ';'.join([str(_) for _ in pic_list])
             if pic_label is not None:
                 pic_list = "%s:%s" % (pic_label, pic_list)
             out += "\n\t PIC:%s" % pic_list
         if hasattr(self, 'stack'):
             registers, positions = self.stack
             if isinstance(registers, bool):
                 stack_status = '%s:' % registers
             else:
                 stack_status = []
                 for k in sorted(registers):
                     stack_status.append('%r: %r' %
                                         (k, sorted(list(registers[k]))))
                 stack_status = '{' + ', '.join(stack_status) + '}:'
             stack_status += str(tuple(sorted(positions)))
             out += "\n\t STACK:%s" % stack_status
         if hasattr(self, 'dst') and len(self.dst) != 0:
             out += "\n\t dst=%s" % (self.dst)
     return out
예제 #14
0
def guess_asm_cpu(symbols):
    from plasmasm import arch
    cpu_opcodes = {}
    for cpu in arch.CPUs:
        cpu_opcodes.update(arch.import_cpu_meta(cpu).opcodes)
    opcodes = set()
    operands = set()
    for label in symbols.symbols:
        for line in getattr(label, 'lines', []):
            if not isinstance(line, Instruction):
                continue
            opcodes.add(line.opname)
            operands.update(line.operands)
    if len(operands) == 0:
        return None
    delta = []
    for cpu in cpu_opcodes:
        delta.append((len(opcodes.difference(cpu_opcodes[cpu])), cpu))
    delta.sort()
    cpu = delta[0][1]
    if delta[0][0] == 0 and delta[1][0] != 0:
        return cpu
    if delta[0][0] == delta[1][0]:
        val = delta[0][0]
        cpu = [x for n, x in delta if n == val]
        # Filter possible cpu by looking at operands
        # Necessary to make the difference between I386 and X64
        cpu_base = set([_ for _ in cpu if not '-' in _])
        cpu_base.update(set([_[:_.find('-')] for _ in cpu if '-' in _]))
        for op in operands:
            if op in ('%g0', '%g1', '%o0'):
                NON_REGRESSION_FOUND
                cpu_base.intersection_update(set(['SPARC']))
            for reg in [
                    'rax', 'rbx', 'rcx', 'rdx', 'rbp', 'rsp', 'rsi', 'rdi',
                    'rip'
            ] + ['r%d' % _ for _ in range(8, 16)]:
                if op in (reg, '%' + reg, '(%' + reg + ')'):
                    cpu_base.intersection_update(set(['X64']))
                if '%' + reg in op or '[' + reg in op:
                    cpu_base.intersection_update(set(['X64']))
            if op in ('eax', '%eax'):
                cpu_base.intersection_update(set(['X64', 'I386']))
            if len(cpu_base) <= 1: break
        if cpu_base == set(['I386', 'X64']):
            # Sometimes an assembly file generated for 64-bit architecture
            # is also a valid 32-bit assembly; but we need to know which
            # was the target architecture, e.g. obfuscation will be different
            if '.rodata.str1.8' in symbols.sections.asm_name:
                # 32-bit uses .rodata.str1.4
                NON_REGRESSION_FOUND
                cpu_base = set(['X64'])
            else:
                cpu_base = set(['I386'])
        # Get back to full CPU description (with AT&T/Intel syntax)
        def startswith(cpu, cpu_base):
            # str.startswith(tuple) is invalid for python 2.3
            for _ in cpu_base:
                if cpu.startswith(_): return True
            return False

        cpu = [_ for _ in cpu if startswith(_, cpu_base)]
        if len(cpu) == 1:
            return cpu[0]
        if set(cpu) == set(['I386-att', 'I386-intel']):
            if not 'format' in symbols.get_meta():
                return 'I386-att'
            else:
                NON_REGRESSION_FOUND
                return 'I386-intel'
        log.warning("Guessing cpu: %s are matching", cpu)
        return cpu[0]
    diff = opcodes.difference(cpu_opcodes[cpu])
    if len(diff) * 2 > len(opcodes):
        log.warning(
            "Guessing cpu: best guess is %s but too many opcodes are missing",
            cpu)
        return None
    log.warning("Guessing cpu %s; additional opcodes are %s", cpu,
                sorted(list(diff)))
    return cpu
예제 #15
0
    def eval_ExprMem(self, e, eval_cache={}):
        a_val = expr_simp(self.eval_expr(e.arg, eval_cache))
        if isinstance(a_val, ExprTop):
            #XXX hack test
            ee = ExprMem(e.arg, e.size)
            ee.is_term = True
            return ee
        a = expr_simp(ExprMem(a_val, size=e.size))
        if a in self.pool:
            return self.pool[a]
        tmp = None
        #test if mem lookup is known
        """
        for k in self.pool:
            if not isinstance(k, ExprMem):
                continue
            if a_val == k.arg:
                tmp = k
                break
        """
        if a_val in self.pool.pool_mem:
            tmp = self.pool.pool_mem[a_val][0]
        """
        for k in self.pool:
            if not isinstance(k, ExprMem):
                continue
            if a_val == k.arg:
                tmp = k
                break
        """
        if tmp is None:

            v = self.find_mem_by_addr(a_val)
            if not v:
                out = []
                ov = self.get_mem_overlapping(a, eval_cache)
                off_base = 0
                ov.sort()
                ov.reverse()
                for off, x in ov:
                    off_base = off * 8
                    if off >= 0:
                        m = min(a.get_size() - off_base, x.get_size())
                        ee = ExprSlice(self.pool[x], 0, m)
                        ee = expr_simp(ee)
                        out.append((ee, off_base, off_base + ee.get_size()))
                        off_base += ee.get_size()
                    else:
                        m = min(a.get_size() - off * 8, x.get_size())
                        ee = ExprSlice(self.pool[x], -off * 8, m)
                        ee = expr_simp(ee)
                        out.append((ee, off_base, off_base + ee.get_size()))
                        off_base += ee.get_size()
                if out:
                    missing_slice = self.rest_slice(out, 0, a.get_size())
                    for sa, sb in missing_slice:
                        ptr = expr_simp(a_val + ExprInt32(sa / 8))
                        out.append((ExprMem(ptr, size=sb - sa), sa, sb))
                    out = sorted(out, key=lambda x: x[1])
                    #for e, sa, sb in out:
                    #    print("%s %s %s"%(e, sa, sb))
                    ee = ExprSlice(ExprCompose(out), 0, a.get_size())
                    ee = expr_simp(ee)
                    return ee
            if self.func_read and isinstance(a.arg, ExprInt):
                return self.func_read(self, a)
            else:
                #XXX hack test
                a.is_term = True
                return a
        #eq lookup
        if a.size == tmp.size:
            return self.pool[tmp]
        #bigger lookup
        if a.size > tmp.size:
            rest = a.size
            ptr = a_val
            out = []
            ptr_index = 0
            while rest:
                v = self.find_mem_by_addr(ptr)
                if v is None:
                    #raise ValueError("cannot find %s in mem"%str(ptr))
                    val = ExprMem(ptr, 8)
                    v = val
                    diff_size = 8
                elif rest >= v.size:
                    val = self.pool[v]
                    diff_size = v.size
                else:
                    diff_size = rest
                    val = self.pool[v][0:diff_size]
                val = (val, ptr_index, ptr_index + diff_size)
                out.append(val)
                ptr_index += diff_size
                rest -= diff_size
                ptr = expr_simp(
                    self.eval_expr(
                        ExprOp('+', ptr, ExprInt(uint32(v.size / 8))),
                        eval_cache))
            e = expr_simp(ExprCompose(out))
            return e
        #part lookup
        tmp = expr_simp(ExprSlice(self.pool[tmp], 0, a.size))
        return tmp
예제 #16
0
def label_def(label):
    res = {}
    if getattr(label, 'type', None) == 'function': res['.type'] = 32
    if getattr(label, 'bind', None) == 'globl': res['.scl'] = 2
    if getattr(label, 'bind', None) == 'local': res['.scl'] = 3
    return ';\t'.join(['%s\t%s' % (_, res[_]) for _ in sorted(res)])
예제 #17
0
def set_pic_reg(todo):
    # 'todo' is a list of blocs where PIC register needs to be computed
    # of the form [ (label, start, (pic_label, pic_list)) ]
    # 'label' is the bloc label
    # 'start' is the idx of the first line where to set the PIC attribute
    # 'pic_label' is None or the label used as offset for PIC computation
    # 'pic_list' is a tuple of places containing the PIC offset
    done = {}
    blocs = ()
    while True:
        if len(todo) == 0:
            # When all 'todo' blocs have been analyzed, we can deduce that
            # all other blocs have no PIC data. This needs to be enforced,
            # e.g. when a bloc is a target of a jmp with PIC data and a jmp
            # without PIC data, this target should have no PIC data
            for _ in blocs:
                if _ in done: continue
                if len(_.lines) == 0: continue
                # Not executable bloc
                if not hasattr(_.lines[0], 'rw'): continue
                # Padding or alignment
                if isinstance(_.lines[0], P2Align): continue
                if getattr(_, 'type', None) == 'padding': continue
                # Data bloc that may be reached (the CFG may be incomplete)
                todo.append((_, 0, (False, ())))
        if len(todo) == 0:
            break
        label, start, pic = todo.pop(0)
        if label is None: continue
        blocs = label.symbols.blocs
        if not label in blocs: continue
        if label in done:
            prev_pic = done[label]
            # The pic_label of l should be the same
            if pic[0] is True or prev_pic[0] is True:
                # we are in the start of the function
                # we don't erase the pic tracking below call;pop
                continue
            if not pic[0] in [False, prev_pic[0]]:
                raise ValueError(
                    'PIC label should stay identical in a function. in %s, %s != %s'
                    % (label, pic[0], prev_pic[0]))
            # The pic_list of l should be included in pic_list
            # In other words, when a label is reached both through a jump
            # rather than through the normal flow, the PIC register may have
            # been overwritten
            pic = (pic[0],
                   tuple(sorted(set(pic[1]).intersection(set(prev_pic[1])))))
            if prev_pic == pic: continue
        done[label] = pic
        # TODO: exchange analysis of last lines when there is a delay slot
        for l in label.lines[start:]:
            l.pic = pic
            pic = update_pic(l, pic)
        if label.flow in ['sub', 'D.sub']:
            # We could propagate PIC status through function calls,
            # (if there is not external symbol and if we update esp)
            # but we don't want to
            todo.append((label.nxt, 0, pic))
        else:
            # Most jmp stay in the function, and keep the PIC register
            # However, tail-call optimization replaces a call ret by a jmp
            todo.extend([(_, 0, pic) for _ in label.cfg])
    for label in blocs:
        # Delete pic field when there is no PIC info
        for l in label.lines:
            if not hasattr(l, 'pic'):
                continue
            if l.pic[1] == (): del l.pic
예제 #18
0
def mk_asm_file(symbols, output_filename=None):
    meta = symbols.get_meta()
    asm_format, format_file = find_format(meta)
    symbols_set_asm_format(symbols, asm_format)
    if output_filename is None: output = ''
    else: output = TextIOWrapperWithAppend(output_filename)
    file = [s for s in symbols.symbols if getattr(s, 'bind', None) == 'file']
    if len(file) == 1:
        output += '\t.file\t"%s"\n' % file[0]
    output += format_file
    if meta.get('compiler') == 'clang' and 'os_minversion' in meta:
        osmaj, osmin, type = meta.get('os_minversion')
        if type == 'vermin':
            output += "\t.macosx_version_min %d, %d\n" % (osmaj, osmin)
        elif type == 'bldver':
            output += "\t.build_version macos, %d, %d" % (osmaj, osmin)
            output += "\tsdk_version %d, %d\n" % (osmaj, osmin)
    output += hack_for_gcc492(symbols)
    output += mk_asm_file_v2(symbols, meta, asm_format)
    for label in symbols.symbols:
        if hasattr(symbols, 'cds') and symbols.cds.hide_symbol(label.name):
            continue
        if label not in symbols.bloc_set:
            if hasattr(label, 'visibility'):
                output += '\t.%s\t%s\n' % (label.visibility, label.name)
            elif getattr(label, 'bind', None) == 'weak' and not getattr(
                    label, 'type', None) == 'endofsymbol':
                output += '\t.%s\t%s\n' % (label.bind, label.name)
        for key in getattr(label, 'data', {}):
            if key == 'set':
                if getattr(label, 'bind', None) == 'globl':
                    output += '\t.%s\t%s\n' % (label.bind, label.name)
                output += '\t.set\t%s,%s\n' % (label.name, label.data['set'])
                if hasattr(label, 'size') and label.size != getattr(
                        label.data['set'], 'size', None):
                    output += '\t.size\t%s, %s\n' % (label.name, label.size)
            elif key == 'weakref':
                output += '\t.weakref\t%s,%s\n' % (label.data['weakref'],
                                                   label.name)
            elif key == 'symver':
                output += '\t.symver\t%s,%s\n' % (label.name,
                                                  label.data['symver'])
            elif not key in [
                    'LFB', 'cfi_personality', 'cfi_lsda', 'indirect_symbol',
                    'cfg_warn', 'data_object', 'function'
            ]:
                raise ValueError("Unknown data key %r for %r" % (key, label))
    if meta.get('compiler') == 'mingw':
        s_external = [
            _ for _ in symbols.symbols
            if not _ in symbols.bloc_set and hasattr(_, 'type')
        ]
        for label in sorted(
                s_external,
                key=lambda x:
            (getattr(x, 'section', ''), getattr(x, 'address', 0))):
            if not (hasattr(symbols, 'cds')
                    and symbols.cds.hide_symbol(label.name)):
                output += '\t.def\t%s;\t%s;\t.endef\n' % (label.name,
                                                          label_def(label))
    if 'cfi_sections' in meta:
        output += '\t.cfi_sections\t%s\n' % meta['cfi_sections']
    if 'ident' in meta:
        output += '\t.ident\t"%s"\n' % meta['ident']
    if meta.get('compiler') == 'gcc' and asm_format != 'sparc':
        output += '\t.section\t.note.GNU-stack,"",@progbits\n'
    if meta.get('compiler') == 'clang':
        output += '\n.subsections_via_symbols\n'
    if output_filename is not None: output.file.close()
    return output
예제 #19
0
파일: expression.py 프로젝트: LRGH/miasmX
def canonize_expr_list(l):
    return sorted(l, key=key_expr)
예제 #20
0
파일: symbols.py 프로젝트: LRGH/plasmasm
 def object_list(self):
     if 'object_list' in self._precomputed:
         return self._precomputed['object_list']
     # res is a list of objects, each being a list of blocs
     # the end of an object is determined with the following heuristics:
     # - symbol with type, data or bind==globl
     # - symbol in comm_symbol_section
     # if not at the end, the object continues within the same section
     # res_sections is the list of sections of the objects
     res = []
     res_sections = []
     for label in self.blocs:
         section = label.section
         if is_comm(label): section = comm_symbol_section
         if label.is_new_object():
             prv = None
         else:
             for idx in range(len(res)):
                 prv_section = res_sections[-idx - 1]
                 if prv_section == section:
                     prv = res[-idx - 1]
                     break
             else:
                 prv = None
         if prv is None:  # New object/function
             res.append([label])
             res_sections.append(section)
         else:
             prv.append(label)
     # nxt is the list of objects having a 'nxt', therefore needing to be
     # merged with the next object
     nxt = []
     for o in res:
         if o[-1].nxt is not None \
                 and section_type(o[-1].section) != 'common' \
                 and getattr(o[-1], 'type', None) != 'padding':
             nxt.append(o)
     for o in nxt:
         log.warning("Object %s has nxt %s", [str(l) for l in o], o[-1].nxt)
     # reorder objects, based on the original section order, plus some hints
     # objects in .text.__i686.get_pc_thunk.* should be last
     # objects in __IMPORT,__pointers should be last, too
     last_section_eos = -1
     for o in self.sections.eos:
         if not o.__class__ == str and last_section_eos < o:
             last_section_eos = o
     res_ordered = {}
     for o, section in zip(res, res_sections):
         if section.startswith('__IMPORT,__pointers'):
             pos = last_section_eos + 2
         elif section.endswith('.__i686.get_pc_thunk.cx'):
             pos = last_section_eos + 2
         elif section.endswith('.__i686.get_pc_thunk.bx'):
             pos = last_section_eos + 3
         elif section in self.sections.eos:
             pos = self.sections.eos[section]
         else:
             pos = last_section_eos + 1
         if not pos in res_ordered:
             res_ordered[pos] = []
         res_ordered[pos].append(o)
     res = []
     for pos in sorted(res_ordered.keys()):
         res.extend(res_ordered[pos])
     self._precomputed['object_list'] = res
     return res
예제 #21
0
파일: expression.py 프로젝트: LRGH/miasmX
def canonize_expr_list_compose(l):
    return sorted(l, key=key_expr_compose)