I have large PE file (C++), which has lots of indirect function calls using vtable and jmp dword.How can I generate a call tree for such functions ? (like with IDA User xrefs chart menu).Here is an example of disassembled code:UPX1:2401135C sub_2401135C proc near                  ; CODE XREF: sub_2401263C+CpUPX1:2401135C                                         ; StartAddress+21p ...UPX1:2401135C test    eax, eaxUPX1:2401135E jz      short locret_2401136AUPX1:24011360 call    ds:off_24057054UPX1:24011366 or      eax, eaxUPX1:24011368 jnz     short loc_2401136BUPX1:2401136AUPX1:2401136A locret_2401136A:                        ; CODE XREF: sub_2401135C+2jUPX1:2401136A retnUPX1:2401136B ; ---------------------------------------------------------------------------UPX1:2401136BUPX1:2401136B loc_2401136B:                           ; CODE XREF: sub_2401135C+CjUPX1:2401136B mov     al, 2UPX1:2401136D jmp     sub_2401141CUPX1:2401136D sub_2401135C endpUser xref chart can show only call ds:off_24057054 branch if I will include data xrefs. What can I do to see the jmp sub_2401141C branch ?
How can i generate function call tree in IDA for non-standart function calls?
ida
In these cases the target of the calls is generated at runtime and can not be determined statically (with very few exceptions). You need to record this information while running the binary and incorporate the extra info into your IDB by using the AddCodeXref API or alike.If you don't want to write your own thing, this plugin can assist you in doing that and more: funcapEDITIn the case of jmp subxxx the target of the jump is well defined. You could programatically go throught the whole binary, extract the target of the jump and add the cross reference. I hacked something together, give it a try.def is_external_jmp(ins_ea):        True for JMPs between functions.    NN_JMP (86): jmp sub_xxx (0xE9 + offset) or jmp loc_xxx (0xE9 + offset)            decode_insn(ins_ea)    if cmd.itype == NN_jmp:        # HACK: GetOperandValue returns the target        # address, not the offset (as I would expect)        target = GetOperandValue(ins_ea, 0)        (s, e) = current_function_boundaries(ins_ea)        if target < s or target > e:            # Not within the current function            return True    return Falsedef current_function_boundaries(ea=None):        Convenience function    @returns: boundaries or None        if not ea:        ea = ScreenEA()    f = get_func(ea)    if not f:        # Probably called outside a function        return (None, None)    else:        return (f.startEA, f.endEA)def main():    for f_ea in Functions():        for ins_ea in FuncItems(f_ea):            if is_external_jmp(ins):                # One of these jmp sub_xxx                target = GetOperandValue(ins_ea, 0)                AddCodeXref(ins_ea, target, fl_CN)if __name__ == '__main__':    main()