Exemplo n.º 1
0
 def codeRefs(func):
     resultData,resultCode = [],[]
     for ea in iterate(func):
         if len(database.down(ea)) == 0:
             insn = idaapi.ua_mnem(ea)
             if insn and insn.startswith('call'):
                 resultCode.append((ea, 0))
             continue
         resultData.extend( (ea,x) for x in database.dxdown(ea) )
         resultCode.extend( (ea,x) for x in database.cxdown(ea) if func.startEA == x or not contains(func,x) )
     return resultData,resultCode
Exemplo n.º 2
0
 def codeRefs(ea):
     fn = top(ea)
     resultData,resultCode = [],[]
     for l,r in chunks(fn):
         for ea in database.iterate(l,r):
             if len(database.down(ea)) == 0:
                 insn = idaapi.ua_mnem(ea)
                 if insn and insn.startswith('call'):
                     resultCode.append((ea, 0))
                 continue
             resultData.extend( (ea,x) for x in database.dxdown(ea) )
             resultCode.extend( (ea,x) for x in database.cxdown(ea) if not contains(fn,x) )
         continue
     return resultData,resultCode
Exemplo n.º 3
0
def makecall(ea=None, target=None):
    """Output the function call at `ea` and its arguments with the address they originated from.

    If `target` is specified, then assume that the instruction is
    calling `target` instead of the target address that the call
    is referencing.
    """
    ea = current.address() if ea is None else ea
    if not func.contains(ea, ea):
        return None

    if database.config.bits() != 32:
        raise RuntimeError("{:s}.makecall({!r}, {!r}) : Unable to determine arguments for {:s} due to {:d}-bit calling convention.".format(__name__, ea, target, database.disasm(ea), database.config.bits()))

    if target is None:
        # scan down until we find a call that references something
        chunk, = ((l, r) for l, r in func.chunks(ea) if l <= ea <= r)
        result = []
        while (len(result) < 1) and ea < chunk[1]:
            # FIXME: it's probably not good to just scan for a call
            if not database.instruction(ea).startswith('call '):
                ea = database.next(ea)
                continue
            result = database.cxdown(ea)
            if len(result) == 0: raise TypeError("{:s}.makecall({!r}, {!r}) : Unable to determine number of arguments.".format(__name__, ea, target))

        if len(result) != 1:
            raise ValueError("{:s}.makecall({!r}, {!r}) : An invalid number of targets was returned for the call at {:#x}. The call targets that were returned are {!r}.".format(__name__, ea, result))
        fn, = result
    else:
        fn = target

    try:
        result = []
        for offset, name, size in func.arguments(fn):
            left = database.address.prevstack(ea, offset + database.config.bits() // 8)
            # FIXME: if left is not an assignment or a push, find last assignment
            result.append((name, left))
    except internal.exceptions.OutOfBoundsError:
        raise internal.exceptions.OutOfBoundserror("{:s}.makecall({!r}, {!r}) : Unable to get arguments for target function.".format(__name__, ea, target))

    # FIXME: replace these crazy list comprehensions with something more comprehensible.
#    result = ["{:s}={:s}".format(name, instruction.op_repr(ea, 0)) for name, ea in result]
    result = ["({:#x}){:s}={:s}".format(ea, name, ':'.join(instruction.op_repr(database.address.prevreg(ea, instruction.op_value(ea, 0), write=True), n) for n in instruction.opsi_read(database.address.prevreg(ea, instruction.op_value(ea, 0), write=True))) if instruction.op_type(ea, 0) == 'reg' else instruction.op_repr(ea, 0)) for name, ea in result]

    try:
        return "{:s}({:s})".format(internal.declaration.demangle(func.name(func.by_address(fn))), ','.join(result))
    except:
        pass
    return "{:s}({:s})".format(internal.declaration.demangle(database.name(fn)), ','.join(result))
Exemplo n.º 4
0
 def codeRefs(ea):
     fn = top(ea)
     resultData,resultCode = [],[]
     for l,r in chunks(fn):
         for ea in database.iterate(l,r):
             if len(database.down(ea)) == 0:
                 insn = idaapi.ua_mnem(ea)
                 if insn and insn.startswith('call'):
                     resultCode.append((ea, 0))
                 continue
             resultData.extend( (ea,x) for x in database.dxdown(ea) )
             resultCode.extend( (ea,x) for x in database.cxdown(ea) if not contains(fn,x) )
         continue
     return resultData,resultCode
Exemplo n.º 5
0
def makecall(ea=None, target=None):
    """Output the function call at `ea` and its arguments with the address they originated from.

    If `target` is specified, then assume that the instruction is
    calling `target` instead of the target address that the call
    is referencing.
    """
    ea = current.address() if ea is None else ea
    if not func.contains(ea, ea):
        return None

    if database.config.bits() != 32:
        raise RuntimeError("{:s}.makecall({!r}, {!r}) : Unable to determine arguments for {:s} due to {:d}-bit calling convention.".format(__name__, ea, target, database.disasm(ea), database.config.bits()))

    if target is None:
        # scan down until we find a call that references something
        chunk, = ((l, r) for l, r in func.chunks(ea) if l <= ea <= r)
        result = []
        while (len(result) < 1) and ea < chunk[1]:
            # FIXME: it's probably not good to just scan for a call
            if not database.instruction(ea).startswith('call '):
                ea = database.next(ea)
                continue
            result = database.cxdown(ea)
            if len(result) == 0: raise TypeError("{:s}.makecall({!r}, {!r}) : Unable to determine number of arguments.".format(__name__, ea, target))

        if len(result) != 1:
            raise ValueError("{:s}.makecall({!r}, {!r}) : An invalid number of targets was returned for the call at {:#x}. The call targets that were returned are {!r}.".format(__name__, ea, result))
        fn, = result
    else:
        fn = target

    try:
        result = []
        for offset, name, size in func.arguments(fn):
            left = database.address.prevstack(ea, offset+database.config.bits()/8)
            # FIXME: if left is not an assignment or a push, find last assignment
            result.append((name, left))
    except internal.exceptions.OutOfBoundsError:
        raise internal.exceptions.OutOfBoundserror("{:s}.makecall({!r}, {!r}) : Unable to get arguments for target function.".format(__name__, ea, target))

    # FIXME: replace these crazy list comprehensions with something more comprehensible.
#    result = ["{:s}={:s}".format(name, instruction.op_repr(ea, 0)) for name, ea in result]
    result = ["({:#x}){:s}={:s}".format(ea, name, ':'.join(instruction.op_repr(database.address.prevreg(ea, instruction.op_value(ea, 0), write=1), n) for n in instruction.ops_read(database.address.prevreg(ea, instruction.op_value(ea, 0), write=1))) if instruction.op_type(ea, 0) == 'reg' else instruction.op_repr(ea, 0)) for name, ea in result]

    try:
        return "{:s}({:s})".format(internal.declaration.demangle(func.name(func.by_address(fn))), ','.join(result))
    except:
        pass
    return "{:s}({:s})".format(internal.declaration.demangle(database.name(fn)), ','.join(result))
Exemplo n.º 6
0
    def iterate(self, pc, options):
        if self.provider.segStart(pc) == 0xFFFFFFFF:
            raise ValueError('F*****g IDA')
        
        # if its a call, get the xrefs from it
        # XXX: removed ia32 from public release
        #if ia32.isCall(insn):

        proc = self.provider.getArch()

        if proc == "pc":
            call_mnem = "call"
        elif proc == "arm" or proc == "ppc":
            call_mnem = "bl"
        elif proc == "mips":
            call_mnem = "jalr"
        
        # XXX gotta add support for jmps that go outside a function
        if call_mnem in self.provider.getMnem(pc).lower():

            xrefs_from = database.cxdown(pc)  
            func_top = function.top(pc)
            for x in xrefs_from:
                if self.provider.isCode(self.provider.getFlags(x)):
                    xref_top = function.top(x)
                    context = options['database'].c(func_top)
                    content = context.address(pc)
                    content.edge((x, x))
    
        try:
            endEA = self.provider.funcEnd(pc)
        except:
            return

        if endEA == pc:
            return
         
        # removed as we aren't in private release 
        # hlt instruction 
        #if insn[1] == "\xf4":
        #    return

        return
Exemplo n.º 7
0
 def cxDown(self, ea):
     return database.cxdown(ea)
Exemplo n.º 8
0
def isImportRef(ea):
    return len(database.dxdown(ea)) == len(
        database.cxdown(ea)) and len(database.cxdown(ea)) > 0
Exemplo n.º 9
0
def isGlobalRef(ea):
    '''Return True if the specified instruction references data (like a global)'''
    return len(database.dxdown(ea)) > len(database.cxdown(ea))
Exemplo n.º 10
0
 def cxDown(self, ea):
     return database.cxdown(ea)
Exemplo n.º 11
0
def makecall(ea=None, target=None):
    ea = current.address() if ea is None else ea
    if not function.contains(ea, ea):
        return None

    if database.config.bits() != 32:
        raise RuntimeError(
            "{:s}.makecall({!r},{!r}) : Unable to determine arguments for {:s} due to {:d}-bit calling convention."
            .format(__name__, ea, target, database.disasm(ea),
                    database.config.bits()))

    if target is None:
        # scan down until we find a call that references something
        chunk, = ((l, r) for l, r in function.chunks(ea) if l <= ea <= r)
        result = []
        while (len(result) < 1) and ea < chunk[1]:
            # FIXME: it's probably not good to just scan for a call
            if not database.instruction(ea).startswith('call '):
                ea = database.next(ea)
                continue
            result = database.cxdown(ea)
            if len(result) == 0:
                raise TypeError(
                    "{:s}.makecall({!r},{!r}) : Unable to determine number of arguments"
                    .format(__name__, ea, target))

        if len(result) != 1:
            raise ValueError(
                "{:s}.makecall({!r},{!r}) : Too many targets for call at {:x} : {!r}"
                .format(__name__, ea, result))
        fn, = result
    else:
        fn = target

    try:
        result = []
        for offset, name, size in function.arguments(fn):
            left, _ = function.stack_window(
                ea, offset + database.config.bits() / 8)
            # FIXME: if left is not an assignment or a push, find last assignment
            result.append((name, left))
    except LookupError:
        raise LookupError(
            "{:s}.makecall({!r},{!r}) : Unable to get arguments for target function"
            .format(__name__, ea, target))

    # FIXME: replace these crazy list comprehensions with something more comprehensible.


#    result = ["{:s}={:s}".format(name,ins.op_repr(ea, 0)) for name,ea in result]
    result = [
        "({:x}){:s}={:s}".format(
            ea, name, ':'.join(
                ins.op_repr(
                    database.address.prevreg(ea, ins.op_value(ea, 0), write=1),
                    n)
                for n in ins.ops_read(
                    database.address.prevreg(ea, ins.op_value(ea, 0), write=1))
            ) if ins.op_type(ea, 0) == 'reg' else ins.op_repr(ea, 0))
        for name, ea in result
    ]

    try:
        return "{:s}({:s})".format(
            internal.declaration.demangle(
                function.name(function.by_address(fn))), ','.join(result))
    except:
        pass
    return "{:s}({:s})".format(
        internal.declaration.demangle(database.name(fn)), ','.join(result))