예제 #1
0
 def __init__(self, *args, **kwargs):
     sp = asmblock.AsmSymbolPool()
     jitter.__init__(self, ir_x86_16(sp), *args, **kwargs)
     self.vm.set_little_endian()
     self.ir_arch.do_stk_segm = False
     self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode
     self.ir_arch.irbloc_fix_regs_for_mode = self.ir_archbloc_fix_regs_for_mode
예제 #2
0
def parse_txt(mnemo, attrib, txt, symbol_pool=None):
    """Parse an assembly listing. Returns a couple (asmcfg, symbol_pool), where
    asmcfg is an AsmCfg instance and symbol_pool the associated AsmSymbolPool

    @mnemo: architecture used
    @attrib: architecture attribute
    @txt: assembly listing
    @symbol_pool: (optional) the AsmSymbolPool instance used to handle labels
    of the listing

    """

    if symbol_pool is None:
        symbol_pool = asmblock.AsmSymbolPool()

    C_NEXT = asmblock.AsmConstraint.c_next
    C_TO = asmblock.AsmConstraint.c_to

    lines = []
    # parse each line
    for line in txt.split('\n'):
        # empty
        if EMPTY_RE.match(line):
            continue
        # comment
        if COMMENT_RE.match(line):
            continue
        # labels to forget
        if FORGET_LABEL_RE.match(line):
            continue
        # label beginning with .L
        match_re = LABEL_RE.match(line)
        if match_re:
            label_name = match_re.group(1)
            label = symbol_pool.getby_name_create(label_name)
            lines.append(label)
            continue
        # directive
        if DIRECTIVE_START_RE.match(line):
            match_re = DIRECTIVE_RE.match(line)
            directive = match_re.group(1)
            if directive in ['text', 'data', 'bss']:
                continue
            if directive in ['string', 'ascii']:
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r'"')]
                raw = raw.decode('string_escape')
                if directive == 'string':
                    raw += "\x00"
                lines.append(asmblock.AsmRaw(raw))
                continue
            if directive == 'ustring':
                # XXX HACK
                line = line.replace(r'\n', '\n').replace(r'\r', '\r')
                raw = line[line.find(r'"') + 1:line.rfind(r'"')] + "\x00"
                raw = raw.decode('string_escape')
                raw = "".join([string + '\x00' for string in raw])
                lines.append(asmblock.AsmRaw(raw))
                continue
            if directive in declarator:
                data_raw = line[match_re.end():].split(' ', 1)[1]
                data_raw = data_raw.split(',')
                size = declarator[directive]
                expr_list = []

                # parser

                for element in data_raw:
                    element = element.strip()
                    element_parsed = base_expr.parseString(element)[0]
                    element_expr = asm_ast_to_expr_with_size(
                        element_parsed, symbol_pool, size)
                    expr_list.append(element_expr)

                raw_data = asmblock.AsmRaw(expr_list)
                raw_data.element_size = size
                lines.append(raw_data)
                continue
            if directive == 'comm':
                # TODO
                continue
            if directive == 'split':  # custom command
                lines.append(DirectiveSplit())
                continue
            if directive == 'dontsplit':  # custom command
                lines.append(DirectiveDontSplit())
                continue
            if directive == "align":
                align_value = int(line[match_re.end():], 0)
                lines.append(DirectiveAlign(align_value))
                continue
            if directive in [
                    'file', 'intel_syntax', 'globl', 'local', 'type', 'size',
                    'align', 'ident', 'section'
            ]:
                continue
            if directive[0:4] == 'cfi_':
                continue

            raise ValueError("unknown directive %s" % str(directive))

        # label
        match_re = LABEL_RE.match(line)
        if match_re:
            label_name = match_re.group(1)
            label = symbol_pool.getby_name_create(label_name)
            lines.append(label)
            continue

        # code
        if ';' in line:
            line = line[:line.find(';')]
        line = line.strip(' ').strip('\t')
        instr = mnemo.fromstring(line, symbol_pool, attrib)

        replace_orphan_labels(instr, symbol_pool)

        if instr.dstflow():
            instr.dstflow2label(symbol_pool)
        lines.append(instr)

    asmblock.log_asmblock.info("___pre asm oki___")
    # make asmcfg

    cur_block = None
    state = STATE_NO_BLOC
    i = 0
    asmcfg = asmblock.AsmCFG(symbol_pool)
    block_to_nlink = None
    delayslot = 0
    while i < len(lines):
        if delayslot:
            delayslot -= 1
            if delayslot == 0:
                state = STATE_NO_BLOC
        line = lines[i]
        # no current block
        if state == STATE_NO_BLOC:
            if isinstance(line, DirectiveDontSplit):
                block_to_nlink = cur_block
                i += 1
                continue
            elif isinstance(line, DirectiveSplit):
                block_to_nlink = None
                i += 1
                continue
            elif not isinstance(line, LocKey):
                # First line must be a label. If it's not the case, generate
                # it.
                loc = guess_next_new_label(symbol_pool)
                cur_block = asmblock.AsmBlock(loc, alignment=mnemo.alignment)
            else:
                cur_block = asmblock.AsmBlock(line, alignment=mnemo.alignment)
                i += 1
            # Generate the current bloc
            asmcfg.add_block(cur_block)
            state = STATE_IN_BLOC
            if block_to_nlink:
                block_to_nlink.addto(
                    asmblock.AsmConstraint(cur_block.loc_key, C_NEXT))
            block_to_nlink = None
            continue

        # in block
        elif state == STATE_IN_BLOC:
            if isinstance(line, DirectiveSplit):
                state = STATE_NO_BLOC
                block_to_nlink = None
            elif isinstance(line, DirectiveDontSplit):
                state = STATE_NO_BLOC
                block_to_nlink = cur_block
            elif isinstance(line, DirectiveAlign):
                cur_block.alignment = line.alignment
            elif isinstance(line, asmblock.AsmRaw):
                cur_block.addline(line)
                block_to_nlink = cur_block
            elif isinstance(line, LocKey):
                if block_to_nlink:
                    cur_block.addto(asmblock.AsmConstraint(line, C_NEXT))
                    block_to_nlink = None
                state = STATE_NO_BLOC
                continue
            # instruction
            elif isinstance(line, instruction):
                cur_block.addline(line)
                block_to_nlink = cur_block
                if not line.breakflow():
                    i += 1
                    continue
                if delayslot:
                    raise RuntimeError("Cannot have breakflow in delayslot")
                if line.dstflow():
                    for dst in line.getdstflow(symbol_pool):
                        if not isinstance(dst, ExprId):
                            continue
                        if dst in mnemo.regs.all_regs_ids:
                            continue
                        cur_block.addto(asmblock.AsmConstraint(dst.name, C_TO))

                if not line.splitflow():
                    block_to_nlink = None

                delayslot = line.delayslot + 1
            else:
                raise RuntimeError("unknown class %s" % line.__class__)
        i += 1

    for block in asmcfg.blocks:
        # Fix multiple constraints
        block.fix_constraints()

        # Log block
        asmblock.log_asmblock.info(block)
    return asmcfg, symbol_pool
예제 #3
0
 def __init__(self, *args, **kwargs):
     sp = asmblock.AsmSymbolPool()
     jitter.__init__(self, ir_arml(sp), *args, **kwargs)
     self.vm.set_little_endian()
예제 #4
0
 def __init__(self, *args, **kwargs):
     sp = asmblock.AsmSymbolPool()
     jitter.__init__(self, ir_mips32b(sp), *args, **kwargs)
     self.vm.set_big_endian()
예제 #5
0
    virt = pe.virt
    output = pe
    dst_interval = interval([(pe.rva2virt(s_text.addr),
                              pe.rva2virt(s_text.addr + s_text.size))])
else:
    st = StrPatchwork()

    addr_main = 0
    virt = st
    output = st

# Get and parse the source code
with open(args.source) as fstream:
    source = fstream.read()

symbol_pool = asmblock.AsmSymbolPool()

asmcfg, symbol_pool = parse_asm.parse_txt(machine.mn, attrib, source,
                                          symbol_pool)

# Fix shellcode addrs
symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main)

if args.PE:
    symbol_pool.set_offset(
        symbol_pool.getby_name_create("MessageBoxA"),
        pe.DirImport.get_funcvirt('USER32.dll', 'MessageBoxA'))

# Print and graph firsts blocks before patching it
for block in asmcfg.blocks:
    print block
예제 #6
0
 def __init__(self, *args, **kwargs):
     super(jitter_ppc32b, self).__init__(ir_ppc32b(asmblock.AsmSymbolPool()),
                                         *args, **kwargs)
     self.vm.set_big_endian()