Beispiel #1
0
def assemble_at(addr, code):
    code_to_assemble = code.split(";")
    res, assembled_code = idautils.Assemble(addr, code_to_assemble)
    if not res:
        raise ValueError("Impossible to assemble <{0}> at <{1}>".format(code, hex(addr)))
    full_assembled_code = "".join(assembled_code)
    return midap.Buffer(addr, len(code)).patch([ord(x) for x in full_assembled_code])
def FindInstructions(instr, asm_where=None):
    """
    Finds instructions/opcodes
    @return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
    """
    if not asm_where:
        # get first segment
        seg = ida_segment.get_first_seg()
        asm_where = seg.start_ea if seg else ida_idaapi.BADADDR
        if asm_where == ida_idaapi.BADADDR:
            return (False, "No segments defined")

    # regular expression to distinguish between opcodes and instructions
    re_opcode = re.compile('^[0-9a-f]{2} *', re.I)

    # split lines
    lines = instr.split(";")

    # all the assembled buffers (for each instruction)
    bufs = []
    for line in lines:
        if re_opcode.match(line):
            # convert from hex string to a character list then join the list to form one string
            buf = bytes(bytearray([int(x, 16) for x in line.split()]))
        else:
            # assemble the instruction
            ret, buf = idautils.Assemble(asm_where, line)
            if not ret:
                return (False, "Failed to assemble:" + line)
        # add the assembled buffer
        bufs.append(buf)

    # join the buffer into one string
    buf = b''.join(bufs)

    # take total assembled instructions length
    tlen = len(buf)

    # convert from binary string to space separated hex string
    bin_str = ' '.join(
        ["%02X" % (ord(x) if sys.version_info.major < 3 else x) for x in buf])

    # find all binary strings
    print("Searching for: [%s]" % bin_str)
    ea = ida_ida.cvar.inf.min_ea
    ret = []
    while True:
        ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16,
                                    ida_search.SEARCH_DOWN)
        if ea == ida_idaapi.BADADDR:
            break
        ret.append(ea)
        ida_kernwin.msg(".")
        ea += tlen
    if not ret:
        return (False, "Could not match [%s]" % bin_str)
    ida_kernwin.msg("\n")
    return (True, ret)
Beispiel #3
0
    def assemble(self, ea, asm, save_state=True, opt_fix=True, opt_nop=True):
        """ Assemble into memory """
        #Fixup the assemble
        if opt_fix:
            regvars = self._getregvars(ea)
            parts_arr = [self.PART_RE.split(i) for i in asm]
            asm = []
            for parts in parts_arr:
                asm.append(self._fixup(parts, regvars))

        #Assemble to a string
        success, data = idautils.Assemble(ea, asm)
        if not success:
            return success, data
        blob = ''.join(data)

        if len(blob) > instr_size(ea):
            if idaapi.askyn_c(
                    0,
                    "The assembled instruction is bigger than the current instruction. This will clobber following instructions. Continue?"
            ) != 1:
                return

        #Pad the blob with nops
        if opt_nop:
            nsuccess, nop_instr = idautils.Assemble(ea, 'nop')
            if not nsuccess:
                return nsuccess, nop_instr

            i = ea
            while i < ea + len(blob):
                i += instr_size(i)
            #Only pad if we trashed the next instruction
            sz_diff = (i - (ea + len(blob))) / len(nop_instr)
            blob += nop_instr * sz_diff

        #Write out the data
        old = read_data(ea, len(blob))
        if save_state:
            self._pushundo([(ea, old)])
            self.redo_buffer = []
        write_data(ea, blob)
        return success, old
Beispiel #4
0
    def nopxrefs(self, ea):
        """ Nop out all xrefs to a function """
        nsuccess, nop_instr = idautils.Assemble(ea, 'nop')
        if not nsuccess:
            return nsuccess, nop_instr

        xrefs = idautils.XrefsTo(ea)
        buf = []
        for i in xrefs:
            success, old = self.assemble(i.frm, ['nop'], False)
            if not success: continue

            buf.append((ea, old))
        self._pushundo(buf)
        self.redo_buffer = []
Beispiel #5
0
def patch_call(va, new_nm):
    """Patch the call at @va to target @new_nm.

    Args:
        va (numbers.Integral): Address of the call site
        new_nm (str): Name of the new call destination

    Returns:
        bool: True if successful
    """
    is_call = idc.print_insn_mnem(va) == 'call'

    if is_call:
        opno = 0
        new_asm = 'call %s' % (new_nm)
    else:
        logger.warn('Not a call instruction at %s' % (phex(va)))
        return False

    # Already done?
    if idc.print_operand(va, opno) == new_nm:
        return True

    ok, code = idautils.Assemble(va, new_asm)

    if not ok:
        logger.warn('Failed assembling %s: %s' % (phex(va), new_asm))
        return False

    orig_opcode_len = idc.get_item_size(va)
    new_code_len = len(code)

    if orig_opcode_len < new_code_len:
        logger.warn('Not enough room or wrong opcode type to patch %s: %s' %
                    (phex(va), new_asm))
        return False

    # If we actually have too much room, then add filler
    if orig_opcode_len > new_code_len:
        delta = orig_opcode_len - new_code_len
        code += '\x90' * delta

    idaapi.patch_bytes(va, code)

    return True
def assemble(ea, what):
    succ, code = idautils.Assemble(ea, what)
    if not succ:
        raise Exception("failed to assemble " + what)
    return code
Beispiel #7
0
 def nopout(self, ea, sz):
     """ NOP out a section of memory """
     nsuccess, nop_instr = idautils.Assemble(ea, 'nop')
     if not nsuccess:
         return nsuccess, nop_instr
     return self.assemble(ea, ['nop'] * (sz / len(nop_instr)))