示例#1
0
def _tag_decryptor_calls(decryptor_func='decrypt_and_expand', encBlockArray=0xb94c78):
  faddr = idc.LocByName(decryptor_func) if type(decryptor_func) == type('str') else decryptor_func
  seen = set()

  for xref in idautils.CodeRefsTo(faddr, 0):

    if xref in seen:
      continue
    seen.add(xref)

    print 'trying to xref to call @0x%x' % (xref)
    fg = bnrev.FunctionGraph(xref)
    for i in fg.nodes[xref].incoming:
      try:
        print 'trying to find eax for call to %s @ 0x%x' % (decryptor_func, i)
        arg = calculate.calc(i, fg)[bnrev.eax]

        if not isinstance(arg, symbolic.Number):
          print 'found a non number: %s' % (arg,)
          continue
        else:
          addr = encBlockArray + (8 * int(arg.n))
          print 'adding dref 0x%x -> 0x%x' % (i, addr)
          idaapi.add_dref(i, addr, idaapi.dr_I)
      except:
        pass
示例#2
0
def add_refs():
    global refs
    
    for (ea, target_addr, target_name) in refs:
        if target_name and len(target_name) != 0:
            idaapi.set_cmt(ea, "%s - 0x%X" % (target_name, ea + 4), False)
        else:
            idaapi.set_cmt(ea, "0x%X - 0x%X" % (target_addr, ea + 4), False)
        idaapi.add_dref(ea, target_addr, idc.dr_O)
示例#3
0
文件: codatify.py 项目: lopessec/ida
    def _fix_data_offsets(self):
        ea = 0
        count = 0

        print "Fixing unresolved offset xrefs...",

        while ea != idaapi.BADADDR:
            (ea, n) = idaapi.find_notype(ea, idaapi.SEARCH_DOWN)
            if idaapi.decode_insn(ea):
                for i in range(0, len(idaapi.cmd.Operands)):
                    op = idaapi.cmd.Operands[i]
                    if op.type == idaapi.o_imm and idaapi.getseg(op.value):
                        idaapi.add_dref(ea, op.value, (idaapi.dr_O | idaapi.XREF_USER))
                        count += 1

        print "created %d new data xrefs" % count
示例#4
0
def new_operators_to_ida_db(marx_module):
    for new_op in marx_module.new_operators.itervalues():
        comment = Comment(new_op.address)
        if new_op.class_hierarchy:
            # Check if there is already a comment, do nothing if there is already a comment
            if not comment:
                MakeComm(
                    new_op.address,
                    "New operator - Size: {:d}, ".format(new_op.size) +
                    "ClassHierarchy_{:d}".format(
                        new_op.class_hierarchy.number))

            # For each vtable of an object which could be constructed by this new operator
            for vtable in new_op.class_hierarchy.vtables:
                # Add references from new operator address to vtable address
                add_dref(new_op.address, vtable.address, dr_O)
        else:
            # Check if there is already a comment, do nothing if there is already a comment
            if not comment:
                MakeComm(
                    new_op.address,
                    "New operator - Size: {:d}, no class info available".
                    format(new_op.size))
示例#5
0
    def add_method_xref(self, xref):
        msg("Adding cross reference to method implementation for %s\n" %
            get_func_name(self.method_pointer))

        #TODO: clean this up so it's more clear how we're parsing and patching the instruction
        #TODO: handle other potential instructions that could place a method selref into a register
        #TODO: sanity check what instruction we're actually working with before blindly deciding
        #       it's a 7-byte mov instruction

        add_dref(xref.frm, self.method_pointer, dr_I | XREF_USER)

        #offset is a rip-relative offset that gets added to rip and dereferenced
        #when this instruction is executed, rip will be pointing to the next instruction
        #meaning it has been incremented by 7 (the length of the mov instruction)
        offset = self.method_pointer - xref.frm - self.X86_64_MOV_INSTRUCTION_SIZE

        #this replaces  mov RSI, &selector with:
        #               mov RSI, &method
        #xref.frm is the address of the mov instruction
        #+3 (4th byte of the instruction)
        #is where the RIP-relative operand is that
        #will get dereferenced as a pointer
        patch_dword(xref.frm + 3, offset)
        return ObjcMethodXref(xref.frm, self.method_pointer, xref.to)
示例#6
0
def recoverBlock(F, startEA, need_trampolines):
    b = Block(startEA)
    curEA = startEA

    # TODO: link some metadata to any block to keep track
    #       of this table, because the indirect jmp
    #       may be in a follower block and not directly in
    #       the block where the address is loaded
    likelyJmpTable = None

    while True:
        insn_t = idautils.DecodeInstruction(curEA)
        if insn_t is None:
            if idc.Byte(curEA) == 0xCC:
                b.endEA = curEA+1
                return b
            else:
                sys.stdout.write("WARNING: Couldn't decode insn at: {0:x}. Ending block.\n".format(curEA))
                b.endEA = curEA
                return b

        # check for xrefs
        j = 0
        for op in insn_t:
            # if it is a MEM operand
            if op.type == idaapi.o_mem and inValidSegment(op.addr):
                if isCall(curEA):
                    if isInternalCode(op.addr):
                            idaapi.add_cref(curEA, op.addr, idaapi.fl_CN)
                    else:
                            idaapi.add_dref(curEA, op.addr, idaapi.dr_R)
                elif isUnconditionalJump(curEA) or isConditionalJump(curEA):
                    if isInternalCode(op.addr):
                            idaapi.add_cref(curEA, op.addr, idaapi.fl_JN)
                    else:
                            idaapi.add_dref(curEA, op.addr, idaapi.dr_R)
                else:
                    if j == 0:
                        idaapi.add_dref(curEA, op.addr, idaapi.dr_W)
                    else:
                        idaapi.add_dref(curEA, op.addr, idaapi.dr_R)

            j += 1

        nextEA = curEA+insn_t.size

        crefs = idautils.CodeRefsFrom(curEA, 1)

        # get curEA follows
        follows = [cref for cref in crefs]
        if isJmpTable(curEA):
            # this is a jmptable (according to IDA)
            # XXX: we assume jmp tables found by IDA don't overlap
            #      with others
            jmpentries = set()
            jmpt = handleJmpTable(None, F, curEA, jmpentries)
            follows = list(jmpentries.union(set(follows)))

            JMPTABLES.add(jmpt)
        elif isIndirectJmp(curEA) and likelyJmpTable is not None:
            # this is an indirect jmp and in the same block there
            # was a mov to take the address of a "likely" jmptable
            for ref in likelyJmpTable.entries():
                need_trampolines.add(ref)
            follows = list(set(likelyJmpTable.entries() + follows))

            JMPTABLES.add(likelyJmpTable)
            likelyJmpTable = None
        elif isLikeLoadJmpTable(curEA):
            # this is an instruction which take the address of a
            # switch table (or something we *think* is a jmp table)
            likelyJmpTable = handleLikeLoadJmpTable(curEA, F)

        if isRepPrefix(curEA):
            sys.stdout.write("Found rep prefix at {0:#x}\n".format(curEA))
            b.succs.append(nextEA)
            b.succs.append(curEA)
            b.endEA = nextEA
            return b

        if isDataInst(curEA):
            sys.stdout.write("Found data in middle of code at {0:#x}\n".format(curEA))
            b.endEA = curEA
            return b

        if isCall(curEA):
            sys.stdout.write("Found call\n")
            fcrefs = idautils.CodeRefsFrom(curEA, 0)
            ffollows = [cref for cref in fcrefs]

            if len(ffollows) == 0 or idaapi.func_does_return(ffollows[0]):
                b.succs.append(nextEA)

            b.endEA = nextEA
            return b

        if isInt(curEA):
            sys.stdout.write("Found int\n")
            b.endEA = nextEA
            b.succs.append(nextEA)
            return b

        if (follows == [nextEA] and not isUnconditionalJump(curEA)) or isCall(curEA):
            # read next instruction
            curEA = nextEA
        # check if we need to make a new block
        elif len(follows) == 0:
            # this is a ret, no follows
            b.endEA = nextEA
            return b
        else:
            # this block has several follow blocks
            b.endEA = nextEA
            for f in follows:
                # do not decode external code refs
                if not isExternalReference(f):
                    b.succs.append(f)
            return b
示例#7
0
def add_ref(frm, to):
    idaapi.add_dref(frm, to, idaapi.dr_R)
    idaapi.add_dref(to, frm, idaapi.dr_R)
示例#8
0
def parse_str_ptr(addr):
    if idc.GetMnem(addr) != 'mov':
        return False

    # Validate that the string offset actually exists inside the binary
    if idc.get_segm_name(idc.GetOperandValue(addr, 1)) is None:
        return False

    # Check the operands' type:
    # - first one must be a register;
    # - second one must be a memory address
    if idc.GetOpType(addr, 0) != 1 or idc.GetOpType(addr, 1) != 2:
        return False

    addr_2 = idc.FindCode(addr, idaapi.SEARCH_DOWN)
    # same operands' type for addr_2
    if idc.GetMnem(addr_2) != 'mov' or idc.GetOpType(
            addr_2, 0) != 1 or idc.GetOpType(addr_2, 1) != 2:
        return False

    opnd_val_1 = idc.GetOperandValue(addr, 1)
    opnd_val_2 = idc.GetOperandValue(addr_2, 1)
    opnd_diff = opnd_val_1 - opnd_val_2
    # The 2 operands, one of addr of string length, another one is the addr of string pointer
    # and they must be side by side
    if opnd_diff != common.ADDR_SZ and opnd_diff != -common.ADDR_SZ:
        return False

    if opnd_diff > 0:
        str_len_addr, str_ptr_addr = opnd_val_1, opnd_val_2
    else:
        str_len_addr, str_ptr_addr = opnd_val_2, opnd_val_1

    str_len = common.read_mem(str_len_addr)
    str_ptr = common.read_mem(str_ptr_addr)
    str_addr = common.read_mem(str_ptr)

    # set max str len
    if str_len > 64:
        return False

    if 'rodata' not in idc.get_segm_name(
            str_ptr) and 'text' not in idc.get_segm_name(str_ptr):
        return False

    common._debug("------------------------------")
    common._debug("Possible str ptr:")
    common._debug("Code addr: 0x%x , str_ptr_addr: 0x%x , str_len_addr: 0x%x" %
                  (addr, str_ptr_addr, str_len_addr))
    common._debug("str_addr: 0x%x , str_len: 0x%x" % (str_ptr, str_len))
    #if create_string(str_addr, str_len):
    if str_len > 1:
        if idc.MakeStr(str_ptr, str_ptr + str_len):
            idaapi.autoWait()
            if opnd_diff > 0:
                idc.MakeComm(addr, "length: %d" % str_len)
                idaapi.add_dref(addr_2, str_ptr, idaapi.dr_O)
            else:
                idc.MakeComm(addr_2, "length: %d" % str_len)
                idaapi.add_dref(addr, str_ptr, idaapi.dr_O)
            idaapi.autoWait()
            return True

    return False
 def on_matched_item(self, item, ctx: PatternContext):
     obj = ctx.get_expr('xref_me')
     if obj.obj_ea >= 0 and obj.obj_ea <= 0x100000:
         idaapi.add_dref(obj.ea, obj.obj_ea, idaapi.dr_O)
     return False
示例#10
0
 def add_data(ea, target, write=False):
     flowtype = idaapi.dr_W if write else idaapi.dr_R
     idaapi.add_dref(ea, target, flowtype | idaapi.XREF_USER)
     return target in xref.data_down(ea)
    if addr & 1:
        addr -= 1
        idaapi.split_sreg_range(addr, idaapi.str2reg("T"), 1, idaapi.SR_user)
    else:
        idaapi.split_sreg_range(addr, idaapi.str2reg("T"), 0, idaapi.SR_user)

    if idaapi.create_insn(addr):
        if idc.add_func(addr):
            if name != "":
                idaapi.set_name(addr, name, idaapi.SN_FORCE)
        return True

    return False


ea = here()
i = 0

while True:
    func_ea = idaapi.get_dword(ea + 4 + i * 8)

    if not define_func(func_ea):
        break

    idaapi.add_dref(ea, func_ea, idaapi.dr_R)

    i += 1

print i
示例#12
0
 def add_data(ea, target, write=False):
     flowtype = idaapi.dr_W if write else idaapi.dr_R
     idaapi.add_dref(ea, target, flowtype | idaapi.XREF_USER)
     return target in xref.data_down(ea)