Example #1
0
def method2dot(mx,
               tainted1=None,
               tainted2=None,
               tainted3=None,
               annotation=None,
               variables=None,
               variables_total=None,
               colors={}):
    """
        Export analysis method to dot format

        @param mx : MethodAnalysis object
        @param colors : MethodAnalysis object

        @rtype : dot format buffer (it is a subgraph (dict))
    """

    tainted1 = tainted1 or {}
    tainted2 = tainted2 or {}
    tainted3 = tainted3 or {}
    annotation = annotation or {}
    variables = variables or {}
    variables_total = variables_total or {}

    colors = colors or {
        "true_branch": "green",
        "false_branch": "red",
        "default_branch": "purple",
        "jump_branch": "blue",
        "bg_idx": "lightgray",
        "idx": "blue",
        "bg_start_idx": "yellow",
        "bg_instruction": "lightgray",
        "instruction_name": "black",
        "instructions_operands": "yellow",
        "raw": "red",
        "string": "red",
        "literal": "green",
        "offset": "#4000FF",
        "method": "#DF3A01",
        "field": "#088A08",
        "type": "#0000FF",
        "registers_range": ("#999933", "#6666FF")
    }

    node_tpl = "\nstruct_%s [label=<\n<TABLE BORDER=\"2\" CELLBORDER=\"0\" CELLSPACING=\"3\" >\n%s</TABLE>>];\n"  #STYLE=\"ROUNDED\"
    #                                                                                                                               v first tainting stuff       v second tainting stuff                       v third tainting stuff                     v annotation             v variables
    label_tpl = "<TR><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%x</FONT> </TD><TD ALIGN=\"RIGHT\" BGCOLOR=\"%s\"> %s </TD><TD ALIGN=\"RIGHT\" BGCOLOR=\"%s\"> %s </TD><TD ALIGN=\"RIGHT\" BGCOLOR=\"%s\"> %s </TD><TD ALIGN=\"RIGHT\"> %s </TD><TD ALIGN=\"LEFT\"> %s </TD><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%s </FONT> %s </TD></TR>\n"
    link_tpl = "<TR><TD PORT=\"%s\"></TD></TR>\n"

    edges_html = ""
    blocks_html = ""

    method = mx.get_method()
    sha256 = hashlib.sha256(
        "%s%s%s" %
        (mx.get_method().get_class_name(), mx.get_method().get_name(),
         mx.get_method().get_descriptor())).hexdigest()

    registers = {}
    if method.get_code():
        for i in range(method.get_code().get_registers_size()):
            registers[i] = 0

    #for DVMBasicMethodBlock in mx.basic_blocks.gets():
    #    ins_idx = DVMBasicMethodBlock.start

    # loop over method instructions
    #    for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions():
    #        operands = DVMBasicMethodBlockInstruction.get_operands(ins_idx)
    #        for register in operands:
    #            if register[0] == 0:
    #                if register[1] not in registers:
    #                    registers[register[1]] = 0
    #                registers[register[1]] += 1

    if registers:
        registers_colors = color_range(colors["registers_range"][0],
                                       colors["registers_range"][1],
                                       len(registers))
        for i in registers:
            registers[i] = registers_colors.pop(0)

    new_links = []

    params = []
    method_information = method.get_information()
    if method_information:
        if "params" in method_information:
            for register, _ in method_information["params"]:
                params.append('v' + str(register))

    for DVMBasicMethodBlock in mx.basic_blocks.gets():
        ins_idx = DVMBasicMethodBlock.start
        block_id = hashlib.md5(sha256 + DVMBasicMethodBlock.name).hexdigest()

        content = link_tpl % 'header'

        for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions(
        ):
            if DVMBasicMethodBlockInstruction.get_op_value(
            ) == 0x2b or DVMBasicMethodBlockInstruction.get_op_value() == 0x2c:
                new_links.append(
                    (DVMBasicMethodBlock, ins_idx,
                     DVMBasicMethodBlockInstruction.get_ref_off() * 2 +
                     ins_idx))
            elif DVMBasicMethodBlockInstruction.get_op_value() == 0x26:
                new_links.append(
                    (DVMBasicMethodBlock, ins_idx,
                     DVMBasicMethodBlockInstruction.get_ref_off() * 2 +
                     ins_idx))

            operands = DVMBasicMethodBlockInstruction.get_operands(ins_idx)
            output = ", ".join(mx.get_vm().get_operand_html(
                i, registers, colors, escape, textwrap.wrap) for i in operands)

            if ins_idx in tainted1:
                output_tainted1 = ", ".join(
                    [i for i in tainted1[ins_idx][1] if i not in params])
                params_tainted1 = [
                    i for i in tainted1[ins_idx][1] if i in params
                ]
                if output_tainted1 and params_tainted1:
                    output_tainted1 += " | "
                if params_tainted1:
                    output_tainted1 += "<FONT color=\"red\">" + ", ".join(
                        params_tainted1) + "</FONT>"
            else:
                output_tainted1 = ''

            if ins_idx in tainted2:
                output_tainted2 = ", ".join(
                    [i for i in tainted2[ins_idx][1] if i not in params])
                params_tainted2 = [
                    i for i in tainted2[ins_idx][1] if i in params
                ]
                if output_tainted2 and params_tainted2:
                    output_tainted2 += " | "
                if params_tainted2:
                    output_tainted2 += "<FONT color=\"red\">" + ", ".join(
                        params_tainted2) + "</FONT>"
            else:
                output_tainted2 = ''

            if ins_idx in tainted3:
                output_tainted3 = ", ".join(
                    [i for i in tainted3[ins_idx][1] if i not in params])
                params_tainted3 = [
                    i for i in tainted3[ins_idx][1] if i in params
                ]
                if output_tainted3 and params_tainted3:
                    output_tainted3 += " | "
                if params_tainted3:
                    output_tainted3 += "<FONT color=\"red\">" + ", ".join(
                        params_tainted3) + "</FONT>"
            else:
                output_tainted3 = ''

            if ins_idx in annotation:
                temp = []
                for bla, lol in annotation[ins_idx].items():
                    temp.append("%s: %s" % (bla, ", ".join(lol)))
                output_annotation = "; ".join(temp)
            else:
                output_annotation = ''

            if ins_idx in variables:
                output_variables = ", ".join(sorted(variables[ins_idx]))
            else:
                output_variables = ''

            formatted_operands = DVMBasicMethodBlockInstruction.get_formatted_operands(
            )
            if formatted_operands:
                output += " ; %s" % str(formatted_operands)

            bg_idx = colors["bg_idx"]
            if ins_idx == 0 and "bg_start_idx" in colors:
                bg_idx = colors["bg_start_idx"]

            content += label_tpl % (
                bg_idx, colors["idx"], ins_idx, colors["bg_instruction"],
                output_tainted1, colors["bg_instruction"], output_tainted2,
                colors["bg_instruction"], output_tainted3, output_annotation,
                output_variables, colors["bg_instruction"],
                colors["instruction_name"],
                DVMBasicMethodBlockInstruction.get_name(), output)

            ins_idx += DVMBasicMethodBlockInstruction.get_length()
            last_instru = DVMBasicMethodBlockInstruction

        # all blocks from one method parsed
        # updating dot HTML content
        content += link_tpl % 'tail'
        blocks_html += node_tpl % (block_id, content)

        # Block edges color treatment (conditional branchs colors)
        val = colors["true_branch"]
        if len(DVMBasicMethodBlock.childs) > 1:
            val = colors["false_branch"]
        elif len(DVMBasicMethodBlock.childs) == 1:
            val = colors["jump_branch"]

        values = None
        if (last_instru.get_op_value() == 0x2b or last_instru.get_op_value()
                == 0x2c) and len(DVMBasicMethodBlock.childs) > 1:
            val = colors["default_branch"]
            values = ["default"]
            values.extend(
                DVMBasicMethodBlock.get_special_ins(
                    ins_idx - last_instru.get_length()).get_values())

        # updating dot edges
        for DVMBasicMethodBlockChild in DVMBasicMethodBlock.childs:
            label_edge = ""

            if values:
                label_edge = values.pop(0)

            child_id = hashlib.md5(
                sha256 + DVMBasicMethodBlockChild[-1].name).hexdigest()
            edges_html += "struct_%s:tail -> struct_%s:header  [penwidth=\"2\",color=\"%s\", label=\"%s\"];\n" % (
                block_id, child_id, val, label_edge)
            # color switch
            if val == colors["false_branch"]:
                val = colors["true_branch"]
            elif val == colors["default_branch"]:
                val = colors["true_branch"]

        exception_analysis = DVMBasicMethodBlock.get_exception_analysis()
        if exception_analysis:
            for exception_elem in exception_analysis.exceptions:
                exception_block = exception_elem[-1]
                if exception_block:
                    exception_id = hashlib.md5(
                        sha256 + exception_block.name).hexdigest()
                    edges_html += "struct_%s:tail -> struct_%s:header  [penwidth=\"2\",color=\"%s\", label=\"%s\"];\n" % (
                        block_id, exception_id, "black", exception_elem[0])

    for link in new_links:
        DVMBasicMethodBlock = link[0]
        DVMBasicMethodBlockChild = mx.basic_blocks.get_basic_block(link[2])

        if DVMBasicMethodBlockChild:
            block_id = hashlib.md5(sha256 +
                                   DVMBasicMethodBlock.name).hexdigest()
            child_id = hashlib.md5(sha256 +
                                   DVMBasicMethodBlockChild.name).hexdigest()

            edges_html += "struct_%s:tail -> struct_%s:header  [penwidth=\"2\",color=\"%s\", label=\"data(0x%x) to @0x%x\", style=\"dashed\"];\n" % (
                block_id, child_id, "yellow", link[1], link[2])

    method_label = method.get_class_name() + "." + method.get_name(
    ) + "->" + method.get_descriptor()

    method_information = method.get_information()
    if method_information:
        method_label += "\\nLocal registers v%d ... v%d" % (
            method_information["registers"][0],
            method_information["registers"][1])
        if "params" in method_information:
            for register, rtype in method_information["params"]:
                method_label += "\\nparam v%d = %s" % (register, rtype)
        method_label += "\\nreturn = %s" % (method_information["return"])
        method_label += "\\nTypes:\\n"
        for k, v in variables_total.items():
            method_label += "%s: %s\\n" % (k, ", ".join(v))
        method_label += "\\nMarked at -1:"
        if tainted1.get(-1):
            method_label += "\\nBackward: %s" % ", ".join(tainted1.get(-1)[1])
        if tainted2.get(-1):
            method_label += "\\nForward: %s" % ", ".join(tainted2.get(-1)[1])
        if tainted3.get(-1):
            method_label += "\\nCombined: %s" % ", ".join(tainted3.get(-1)[1])

    return {'name': method_label, 'nodes': blocks_html, 'edges': edges_html}
Example #2
0
def method2dot(mx,
               backward,
               forward,
               combined,
               annotations,
               types,
               types_total,
               colors={}):
    """
        Export analysis method to dot format

        @param mx : MethodAnalysis object
        @param colors : MethodAnalysis object

        @rtype : dot format buffer (it is a subgraph (dict))
    """

    colors = colors or {
        "true_branch": "green",
        "false_branch": "red",
        "default_branch": "purple",
        "jump_branch": "blue",
        "bg_idx": "lightgray",
        "idx": "blue",
        "bg_start_idx": "yellow",
        "bg_instruction": "lightgray",
        "instruction_name": "black",
        "instructions_operands": "yellow",
        "raw": "red",
        "string": "red",
        "literal": "green",
        "offset": "#4000FF",
        "method": "#DF3A01",
        "field": "#088A08",
        "type": "#0000FF",
        "registers_range": ("#999933", "#6666FF")
    }

    node_tpl = "\nstruct_%s [label=<\n<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"3\">\n%s</TABLE>>];\n"
    label_tpl = "<TR><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%x</FONT> </TD><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%s </FONT> %s </TD><td bgcolor=\"lightgray\">%s</td><td bgcolor=\"lightgray\">%s</td><td bgcolor=\"lightgray\">%s</td><td bgcolor=\"lightgray\">%s</td></TR>\n"
    link_tpl = "<TR><TD PORT=\"%s\"></TD></TR>\n"

    edges_html = ""
    blocks_html = ""

    method = mx.get_method()
    sha256 = hashlib.sha256(
        "%s%s%s" %
        (mx.get_method().get_class_name(), mx.get_method().get_name(),
         mx.get_method().get_descriptor())).hexdigest()

    registers = {}
    if method.get_code():
        for DVMBasicMethodBlock in mx.basic_blocks.gets():
            for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions(
            ):
                operands = DVMBasicMethodBlockInstruction.get_operands(0)
                for register in operands:
                    if register[0] == 0:
                        if register[1] not in registers:
                            registers[register[1]] = 0
                        registers[register[1]] += 1


#        for i in range(method.get_code().get_registers_size()):
#            registers[i] = 0

    if registers:
        registers_colors = color_range(colors["registers_range"][0],
                                       colors["registers_range"][1],
                                       len(registers))
        for i in registers:
            registers[i] = registers_colors.pop(0)

    new_links = []

    for DVMBasicMethodBlock in mx.basic_blocks.gets():
        ins_idx = DVMBasicMethodBlock.start
        block_id = hashlib.md5(sha256 +
                               DVMBasicMethodBlock.get_name()).hexdigest()

        content = link_tpl % 'header'

        for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions(
        ):
            if DVMBasicMethodBlockInstruction.get_op_value(
            ) == 0x2b or DVMBasicMethodBlockInstruction.get_op_value() == 0x2c:
                new_links.append(
                    (DVMBasicMethodBlock, ins_idx,
                     DVMBasicMethodBlockInstruction.get_ref_off() * 2 +
                     ins_idx))
            elif DVMBasicMethodBlockInstruction.get_op_value() == 0x26:
                new_links.append(
                    (DVMBasicMethodBlock, ins_idx,
                     DVMBasicMethodBlockInstruction.get_ref_off() * 2 +
                     ins_idx))

            operands = DVMBasicMethodBlockInstruction.get_operands(ins_idx)
            output = ", ".join(mx.get_vm().get_operand_html(
                i, registers, colors, escape, textwrap.wrap) for i in operands)

            formatted_operands = DVMBasicMethodBlockInstruction.get_formatted_operands(
            )
            if formatted_operands:
                output += " ; %s" % str(formatted_operands)

            bg_idx = colors["bg_idx"]
            if ins_idx == 0 and "bg_start_idx" in colors:
                bg_idx = colors["bg_start_idx"]

            #print annotations.get(ins_idx)

            content += label_tpl % (
                bg_idx, colors["idx"], ins_idx, colors["bg_instruction"],
                colors["instruction_name"],
                DVMBasicMethodBlockInstruction.get_name(), output,
                printhelper(forward, ins_idx), printhelper(
                    backward, ins_idx), printhelper(combined, ins_idx),
                printhelperannotations(annotations, ins_idx))

            ins_idx += DVMBasicMethodBlockInstruction.get_length()
            last_instru = DVMBasicMethodBlockInstruction

        # all blocks from one method parsed
        # updating dot HTML content
        content += link_tpl % 'tail'
        blocks_html += node_tpl % (block_id, content)

        # Block edges color treatment (conditional branchs colors)
        val = colors["true_branch"]
        if len(DVMBasicMethodBlock.childs) > 1:
            val = colors["false_branch"]
        elif len(DVMBasicMethodBlock.childs) == 1:
            val = colors["jump_branch"]

        values = None
        if (last_instru.get_op_value() == 0x2b or last_instru.get_op_value()
                == 0x2c) and len(DVMBasicMethodBlock.childs) > 1:
            val = colors["default_branch"]
            values = ["default"]
            values.extend(
                DVMBasicMethodBlock.get_special_ins(
                    ins_idx - last_instru.get_length()).get_values())

        # updating dot edges
        for DVMBasicMethodBlockChild in DVMBasicMethodBlock.childs:
            label_edge = ""

            if values:
                label_edge = values.pop(0)

            child_id = hashlib.md5(
                sha256 + DVMBasicMethodBlockChild[-1].get_name()).hexdigest()
            edges_html += "struct_%s:tail -> struct_%s:header  [color=\"%s\", label=\"%s\"];\n" % (
                block_id, child_id, val, label_edge)
            # color switch
            if val == colors["false_branch"]:
                val = colors["true_branch"]
            elif val == colors["default_branch"]:
                val = colors["true_branch"]

        exception_analysis = DVMBasicMethodBlock.get_exception_analysis()
        if exception_analysis:
            for exception_elem in exception_analysis.exceptions:
                exception_block = exception_elem[-1]
                if exception_block:
                    exception_id = hashlib.md5(
                        sha256 + exception_block.get_name()).hexdigest()
                    edges_html += "struct_%s:tail -> struct_%s:header  [color=\"%s\", label=\"%s\"];\n" % (
                        block_id, exception_id, "black", exception_elem[0])

    for link in new_links:
        DVMBasicMethodBlock = link[0]
        DVMBasicMethodBlockChild = mx.basic_blocks.get_basic_block(link[2])

        if DVMBasicMethodBlockChild:
            block_id = hashlib.md5(sha256 +
                                   DVMBasicMethodBlock.get_name()).hexdigest()
            child_id = hashlib.md5(
                sha256 + DVMBasicMethodBlockChild.get_name()).hexdigest()

            edges_html += "struct_%s:tail -> struct_%s:header  [color=\"%s\", label=\"data(0x%x) to @0x%x\", style=\"dashed\"];\n" % (
                block_id, child_id, "yellow", link[1], link[2])

    method_label = method.get_class_name() + "." + method.get_name(
    ) + "->" + method.get_descriptor()

    method_information = method.get_information()
    if method_information:
        method_label += "\\nLocal registers v%d ... v%d" % (
            method_information["registers"][0],
            method_information["registers"][1])
        if "params" in method_information:
            for register, rtype in method_information["params"]:
                method_label += "\\nparam v%d = %s" % (register, rtype)
        method_label += "\\nreturn = %s" % (method_information["return"])

    return {'name': method_label, 'nodes': blocks_html, 'edges': edges_html}
Example #3
0
def method2dot(mx, colors={}):
    """
        Export analysis method to dot format

        @param mx : MethodAnalysis object
        @param colors : MethodAnalysis object

        @rtype : dot format buffer (it is a subgraph (dict))
    """

    colors = colors or {"true_branch": "green",
                        "false_branch": "red",
                        "default_branch": "purple",
                        "jump_branch": "blue",
                        "bg_idx": "lightgray",
                        "idx": "blue",
                        "bg_start_idx": "yellow",
                        "bg_instruction": "lightgray",
                        "instruction_name": "black",
                        "instructions_operands": "yellow",

                        "raw": "red",
                        "string": "red",
                        "literal": "green",
                        "offset": "#4000FF",
                        "method": "#DF3A01",
                        "field": "#088A08",
                        "type": "#0000FF",

                        "registers_range": ("#999933", "#6666FF")
                        }

    node_tpl = "\nstruct_%s [label=<\n<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"3\">\n%s</TABLE>>];\n"
    label_tpl = "<TR><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%x</FONT> </TD><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%s </FONT> %s </TD></TR>\n"
    link_tpl = "<TR><TD PORT=\"%s\"></TD></TR>\n"

    edges_html = ""
    blocks_html = ""

    method = mx.get_method()
    sha256 = hashlib.sha256("%s%s%s" % (mx.get_method().get_class_name(), mx.get_method().get_name(), mx.get_method().get_descriptor())).hexdigest()

    registers = {}
    if method.get_code():
        for DVMBasicMethodBlock in mx.basic_blocks.gets():
            for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions():
                operands = DVMBasicMethodBlockInstruction.get_operands(0)
                for register in operands:
                    if register[0] == 0:
                        if register[1] not in registers:
                            registers[register[1]] = 0
                        registers[register[1]] += 1
#        for i in range(method.get_code().get_registers_size()):
#            registers[i] = 0

    if registers:
        registers_colors = color_range(colors["registers_range"][0],
                                       colors["registers_range"][1],
                                       len(registers))
        for i in registers:
            registers[i] = registers_colors.pop(0)

    new_links = []

    for DVMBasicMethodBlock in mx.basic_blocks.gets():
        ins_idx = DVMBasicMethodBlock.start
        block_id = hashlib.md5(sha256 + DVMBasicMethodBlock.get_name()).hexdigest()

        content = link_tpl % 'header'

        for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions():
            if DVMBasicMethodBlockInstruction.get_op_value() == 0x2b or DVMBasicMethodBlockInstruction.get_op_value() == 0x2c:
                new_links.append((DVMBasicMethodBlock, ins_idx, DVMBasicMethodBlockInstruction.get_ref_off() * 2 + ins_idx))
            elif DVMBasicMethodBlockInstruction.get_op_value() == 0x26:
                new_links.append((DVMBasicMethodBlock, ins_idx, DVMBasicMethodBlockInstruction.get_ref_off() * 2 + ins_idx))

            operands = DVMBasicMethodBlockInstruction.get_operands(ins_idx)
            output = ", ".join(mx.get_vm().get_operand_html(i, registers, colors, escape, textwrap.wrap) for i in operands)

            formatted_operands = DVMBasicMethodBlockInstruction.get_formatted_operands()
            if formatted_operands:
                output += " ; %s" % str(formatted_operands)

            bg_idx = colors["bg_idx"]
            if ins_idx == 0 and "bg_start_idx" in colors:
                bg_idx = colors["bg_start_idx"]

            content += label_tpl % (bg_idx,
                                    colors["idx"],
                                    ins_idx,
                                    colors["bg_instruction"],
                                    colors["instruction_name"],
                                    DVMBasicMethodBlockInstruction.get_name(),
                                    output)

            ins_idx += DVMBasicMethodBlockInstruction.get_length()
            last_instru = DVMBasicMethodBlockInstruction

        # all blocks from one method parsed
        # updating dot HTML content
        content += link_tpl % 'tail'
        blocks_html += node_tpl % (block_id, content)

        # Block edges color treatment (conditional branchs colors)
        val = colors["true_branch"]
        if len(DVMBasicMethodBlock.childs) > 1:
            val = colors["false_branch"]
        elif len(DVMBasicMethodBlock.childs) == 1:
            val = colors["jump_branch"]

        values = None
        if (last_instru.get_op_value() == 0x2b or last_instru.get_op_value() == 0x2c) and len(DVMBasicMethodBlock.childs) > 1:
            val = colors["default_branch"]
            values = ["default"]
            values.extend(DVMBasicMethodBlock.get_special_ins(ins_idx - last_instru.get_length()).get_values())

        # updating dot edges
        for DVMBasicMethodBlockChild in DVMBasicMethodBlock.childs:
            label_edge = ""

            if values:
                label_edge = values.pop(0)

            child_id = hashlib.md5(sha256 + DVMBasicMethodBlockChild[-1].get_name()).hexdigest()
            edges_html += "struct_%s:tail -> struct_%s:header  [color=\"%s\", label=\"%s\"];\n" % (block_id, child_id, val, label_edge)
            # color switch
            if val == colors["false_branch"]:
                val = colors["true_branch"]
            elif val == colors["default_branch"]:
                val = colors["true_branch"]

        exception_analysis = DVMBasicMethodBlock.get_exception_analysis()
        if exception_analysis:
            for exception_elem in exception_analysis.exceptions:
                exception_block = exception_elem[-1]
                if exception_block:
                    exception_id = hashlib.md5(sha256 + exception_block.get_name()).hexdigest()
                    edges_html += "struct_%s:tail -> struct_%s:header  [color=\"%s\", label=\"%s\"];\n" % (block_id, exception_id, "black", exception_elem[0])

    for link in new_links:
        DVMBasicMethodBlock = link[0]
        DVMBasicMethodBlockChild = mx.basic_blocks.get_basic_block(link[2])

        if DVMBasicMethodBlockChild:
            block_id = hashlib.md5(sha256 + DVMBasicMethodBlock.get_name()).hexdigest()
            child_id = hashlib.md5(sha256 + DVMBasicMethodBlockChild.get_name()).hexdigest()

            edges_html += "struct_%s:tail -> struct_%s:header  [color=\"%s\", label=\"data(0x%x) to @0x%x\", style=\"dashed\"];\n" % (block_id, child_id, "yellow", link[1], link[2])

    method_label = method.get_class_name() + "." + method.get_name() + "->" + method.get_descriptor()

    method_information = method.get_information()
    if method_information:
        method_label += "\\nLocal registers v%d ... v%d" % (method_information["registers"][0], method_information["registers"][1])
        if "params" in method_information:
            for register, rtype in method_information["params"]:
                method_label += "\\nparam v%d = %s" % (register, rtype)
        method_label += "\\nreturn = %s" % (method_information["return"])

    return {'name': method_label,
            'nodes': blocks_html,
            'edges': edges_html}
Example #4
0
def method2dot(mx, colors={}):
    """
        Export analysis method to dot format

        @param mx : MethodAnalysis object
        @param colors : MethodAnalysis object

        @rtype : dot format buffer (it is a subgraph (dict))
    """

    colors = colors or {
        'true_branch': 'green',
        'false_branch': 'red',
        'default_branch': 'purple',
        'jump_branch': 'blue',
        'bg_idx': 'lightgray',
        'idx': 'blue',
        'bg_start_idx': 'yellow',
        'bg_instruction': 'lightgray',
        'instruction_name': 'black',
        'instructions_operands': 'yellow',
        'raw': 'red',
        'string': 'red',
        'literal': 'green',
        'offset': '#4000FF',
        'method': '#DF3A01',
        'field': '#088A08',
        'type': '#0000FF',
        'registers_range': ('#999933', '#6666FF'),
    }

    node_tpl = \
        '''
struct_%s [label=<
<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="3">
%s</TABLE>>];
'''
    label_tpl = \
        '<TR><TD ALIGN="LEFT" BGCOLOR="%s"> <FONT FACE="Times-Bold" color="%s">%x</FONT> </TD><TD ALIGN="LEFT" BGCOLOR="%s"> <FONT FACE="Times-Bold" color="%s">%s </FONT> %s </TD></TR>\n'
    link_tpl = '<TR><TD PORT="%s"></TD></TR>\n'

    edges_html = ''
    blocks_html = ''

    method = mx.get_method_novm()
    sha256 = hashlib.sha256(
        '%s%s%s' % (mx.get_method_novm().get_class_name(),
                    mx.get_method_novm().get_name(),
                    mx.get_method_novm().get_descriptor())).hexdigest()

    registers = {}
    if method.get_code():
        for DVMBasicMethodBlock in mx.basic_blocks.gets():
            for DVMBasicMethodBlockInstruction in \
                DVMBasicMethodBlock.get_instructions():
                operands = \
                    DVMBasicMethodBlockInstruction.get_operands(0)
                for register in operands:
                    if register[0] == 0:
                        if register[1] not in registers:
                            registers[register[1]] = 0
                        registers[register[1]] += 1


#        for i in range(method.get_code().get_registers_size()):
#            registers[i] = 0

    if registers:
        registers_colors = color_range(colors['registers_range'][0],
                                       colors['registers_range'][1],
                                       len(registers))
        for i in registers:
            registers[i] = registers_colors.pop(0)

    new_links = []

    for DVMBasicMethodBlock in mx.basic_blocks.gets():
        ins_idx = DVMBasicMethodBlock.start
        block_id = hashlib.md5(sha256 +
                               DVMBasicMethodBlock.get_name()).hexdigest()

        content = link_tpl % 'header'

        for DVMBasicMethodBlockInstruction in \
            DVMBasicMethodBlock.get_instructions():
            if DVMBasicMethodBlockInstruction.get_op_value() == 0x2b \
                or DVMBasicMethodBlockInstruction.get_op_value() \
                == 0x2c:
                new_links.append(
                    (DVMBasicMethodBlock, ins_idx,
                     DVMBasicMethodBlockInstruction.get_ref_off() * 2 +
                     ins_idx))
            elif DVMBasicMethodBlockInstruction.get_op_value() == 0x26:
                new_links.append(
                    (DVMBasicMethodBlock, ins_idx,
                     DVMBasicMethodBlockInstruction.get_ref_off() * 2 +
                     ins_idx))

            operands = \
                DVMBasicMethodBlockInstruction.get_operands(ins_idx)
            output = ', '.join(mx.get_vm().get_operand_html(
                i, registers, colors, escape, textwrap.wrap) for i in operands)

            formatted_operands = \
                DVMBasicMethodBlockInstruction.get_formatted_operands()
            if formatted_operands:
                output += ' ; %s' % str(formatted_operands)

            bg_idx = colors['bg_idx']
            if ins_idx == 0 and 'bg_start_idx' in colors:
                bg_idx = colors['bg_start_idx']

            content += label_tpl % (
                bg_idx,
                colors['idx'],
                ins_idx,
                colors['bg_instruction'],
                colors['instruction_name'],
                DVMBasicMethodBlockInstruction.get_name(),
                output,
            )

            ins_idx += DVMBasicMethodBlockInstruction.get_length()
            last_instru = DVMBasicMethodBlockInstruction

        # all blocks from one method parsed
        # updating dot HTML content

        content += link_tpl % 'tail'
        blocks_html += node_tpl % (block_id, content)

        # Block edges color treatment (conditional branchs colors)

        val = colors['true_branch']
        if len(DVMBasicMethodBlock.childs) > 1:
            val = colors['false_branch']
        elif len(DVMBasicMethodBlock.childs) == 1:
            val = colors['jump_branch']

        values = None
        if (last_instru.get_op_value() == 0x2b
            or last_instru.get_op_value() == 0x2c) \
            and len(DVMBasicMethodBlock.childs) > 1:
            val = colors['default_branch']
            values = ['default']
            values.extend(
                DVMBasicMethodBlock.get_special_ins(
                    ins_idx - last_instru.get_length()).get_values())

        # updating dot edges

        for DVMBasicMethodBlockChild in DVMBasicMethodBlock.childs:
            label_edge = ''

            if values:
                label_edge = values.pop(0)

            child_id = hashlib.md5(
                sha256 + DVMBasicMethodBlockChild[-1].get_name()).hexdigest()
            edges_html += \
                'struct_%s:tail -> struct_%s:header  [color="%s", label="%s"];\n' \
                % (block_id, child_id, val, label_edge)

            # color switch

            if val == colors['false_branch']:
                val = colors['true_branch']
            elif val == colors['default_branch']:
                val = colors['true_branch']

        exception_analysis = \
            DVMBasicMethodBlock.get_exception_analysis()
        if exception_analysis:
            for exception_elem in exception_analysis.exceptions:
                exception_block = exception_elem[-1]
                if exception_block:
                    exception_id = hashlib.md5(
                        sha256 + exception_block.get_name()).hexdigest()
                    edges_html += \
                        'struct_%s:tail -> struct_%s:header  [color="%s", label="%s"];\n' \
                        % (block_id, exception_id, 'black',
                           exception_elem[0])

    for link in new_links:
        DVMBasicMethodBlock = link[0]
        DVMBasicMethodBlockChild = \
            mx.basic_blocks.get_basic_block(link[2])

        if DVMBasicMethodBlockChild:
            block_id = hashlib.md5(sha256 +
                                   DVMBasicMethodBlock.get_name()).hexdigest()
            child_id = hashlib.md5(
                sha256 + DVMBasicMethodBlockChild.get_name()).hexdigest()

            edges_html += \
                'struct_%s:tail -> struct_%s:header  [color="%s", label="data(0x%x) to @0x%x", style="dashed"];\n' \
                % (block_id, child_id, 'yellow', link[1], link[2])

    method_label = method.get_class_name() + '.' + method.get_name() \
        + '->' + method.get_descriptor()

    method_information = method.get_information()
    if method_information:
        method_label += '\\nLocal registers v%d ... v%d' \
            % (method_information['registers'][0],
               method_information['registers'][1])
        if 'params' in method_information:
            for (register, rtype) in method_information['params']:
                method_label += '\\nparam v%d = %s' % (register, rtype)
        method_label += '\\nreturn = %s' % method_information['return']

    return {'name': method_label, 'nodes': blocks_html, 'edges': edges_html}
Example #5
0
def method2dot(mx, colors={}):
    """
        Export analysis method to dot format

        @param mx : MethodAnalysis object
        @param colors : MethodAnalysis object

        @rtype : dot format buffer (it is a subgraph (dict))
    """

    colors = colors or {
        'true_branch': 'green',
        'false_branch': 'red',
        'default_branch': 'purple',
        'jump_branch': 'blue',
        'bg_idx': 'lightgray',
        'idx': 'blue',
        'bg_start_idx': 'yellow',
        'bg_instruction': 'lightgray',
        'instruction_name': 'black',
        'instructions_operands': 'yellow',
        'raw': 'red',
        'string': 'red',
        'literal': 'green',
        'offset': '#4000FF',
        'method': '#DF3A01',
        'field': '#088A08',
        'type': '#0000FF',
        'registers_range': ('#999933', '#6666FF'),
        }

    node_tpl = \
        '''
struct_%s [label=<
<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="3">
%s</TABLE>>];
'''
    label_tpl = \
        '<TR><TD ALIGN="LEFT" BGCOLOR="%s"> <FONT FACE="Times-Bold" color="%s">%x</FONT> </TD><TD ALIGN="LEFT" BGCOLOR="%s"> <FONT FACE="Times-Bold" color="%s">%s </FONT> %s </TD></TR>\n'
    link_tpl = '<TR><TD PORT="%s"></TD></TR>\n'

    edges_html = ''
    blocks_html = ''

    method = mx.get_method_novm()
    sha256 = hashlib.sha256('%s%s%s'
                            % (mx.get_method_novm().get_class_name(),
                            mx.get_method_novm().get_name(),
                            mx.get_method_novm().get_descriptor())).hexdigest()

    registers = {}
    if method.get_code():
        for DVMBasicMethodBlock in mx.basic_blocks.gets():
            for DVMBasicMethodBlockInstruction in \
                DVMBasicMethodBlock.get_instructions():
                operands = \
                    DVMBasicMethodBlockInstruction.get_operands(0)
                for register in operands:
                    if register[0] == 0:
                        if register[1] not in registers:
                            registers[register[1]] = 0
                        registers[register[1]] += 1

#        for i in range(method.get_code().get_registers_size()):
#            registers[i] = 0

    if registers:
        registers_colors = color_range(colors['registers_range'][0],
                colors['registers_range'][1], len(registers))
        for i in registers:
            registers[i] = registers_colors.pop(0)

    new_links = []

    for DVMBasicMethodBlock in mx.basic_blocks.gets():
        ins_idx = DVMBasicMethodBlock.start
        block_id = hashlib.md5(sha256
                               + DVMBasicMethodBlock.get_name()).hexdigest()

        content = link_tpl % 'header'

        for DVMBasicMethodBlockInstruction in \
            DVMBasicMethodBlock.get_instructions():
            if DVMBasicMethodBlockInstruction.get_op_value() == 0x2b \
                or DVMBasicMethodBlockInstruction.get_op_value() \
                == 0x2c:
                new_links.append((DVMBasicMethodBlock, ins_idx,
                                 DVMBasicMethodBlockInstruction.get_ref_off()
                                 * 2 + ins_idx))
            elif DVMBasicMethodBlockInstruction.get_op_value() == 0x26:
                new_links.append((DVMBasicMethodBlock, ins_idx,
                                 DVMBasicMethodBlockInstruction.get_ref_off()
                                 * 2 + ins_idx))

            operands = \
                DVMBasicMethodBlockInstruction.get_operands(ins_idx)
            output = ', '.join(mx.get_vm().get_operand_html(i,
                               registers, colors, escape,
                               textwrap.wrap) for i in operands)

            formatted_operands = \
                DVMBasicMethodBlockInstruction.get_formatted_operands()
            if formatted_operands:
                output += ' ; %s' % str(formatted_operands)

            bg_idx = colors['bg_idx']
            if ins_idx == 0 and 'bg_start_idx' in colors:
                bg_idx = colors['bg_start_idx']

            content += label_tpl % (
                bg_idx,
                colors['idx'],
                ins_idx,
                colors['bg_instruction'],
                colors['instruction_name'],
                DVMBasicMethodBlockInstruction.get_name(),
                output,
                )

            ins_idx += DVMBasicMethodBlockInstruction.get_length()
            last_instru = DVMBasicMethodBlockInstruction

        # all blocks from one method parsed
        # updating dot HTML content

        content += link_tpl % 'tail'
        blocks_html += node_tpl % (block_id, content)

        # Block edges color treatment (conditional branchs colors)

        val = colors['true_branch']
        if len(DVMBasicMethodBlock.childs) > 1:
            val = colors['false_branch']
        elif len(DVMBasicMethodBlock.childs) == 1:
            val = colors['jump_branch']

        values = None
        if (last_instru.get_op_value() == 0x2b
            or last_instru.get_op_value() == 0x2c) \
            and len(DVMBasicMethodBlock.childs) > 1:
            val = colors['default_branch']
            values = ['default']
            values.extend(DVMBasicMethodBlock.get_special_ins(ins_idx
                          - last_instru.get_length()).get_values())

        # updating dot edges

        for DVMBasicMethodBlockChild in DVMBasicMethodBlock.childs:
            label_edge = ''

            if values:
                label_edge = values.pop(0)

            child_id = hashlib.md5(sha256
                                   + DVMBasicMethodBlockChild[-1].get_name()).hexdigest()
            edges_html += \
                'struct_%s:tail -> struct_%s:header  [color="%s", label="%s"];\n' \
                % (block_id, child_id, val, label_edge)

            # color switch

            if val == colors['false_branch']:
                val = colors['true_branch']
            elif val == colors['default_branch']:
                val = colors['true_branch']

        exception_analysis = \
            DVMBasicMethodBlock.get_exception_analysis()
        if exception_analysis:
            for exception_elem in exception_analysis.exceptions:
                exception_block = exception_elem[-1]
                if exception_block:
                    exception_id = hashlib.md5(sha256
                            + exception_block.get_name()).hexdigest()
                    edges_html += \
                        'struct_%s:tail -> struct_%s:header  [color="%s", label="%s"];\n' \
                        % (block_id, exception_id, 'black',
                           exception_elem[0])

    for link in new_links:
        DVMBasicMethodBlock = link[0]
        DVMBasicMethodBlockChild = \
            mx.basic_blocks.get_basic_block(link[2])

        if DVMBasicMethodBlockChild:
            block_id = hashlib.md5(sha256
                                   + DVMBasicMethodBlock.get_name()).hexdigest()
            child_id = hashlib.md5(sha256
                                   + DVMBasicMethodBlockChild.get_name()).hexdigest()

            edges_html += \
                'struct_%s:tail -> struct_%s:header  [color="%s", label="data(0x%x) to @0x%x", style="dashed"];\n' \
                % (block_id, child_id, 'yellow', link[1], link[2])

    method_label = method.get_class_name() + '.' + method.get_name() \
        + '->' + method.get_descriptor()

    method_information = method.get_information()
    if method_information:
        method_label += '\\nLocal registers v%d ... v%d' \
            % (method_information['registers'][0],
               method_information['registers'][1])
        if 'params' in method_information:
            for (register, rtype) in method_information['params']:
                method_label += '\\nparam v%d = %s' % (register, rtype)
        method_label += '\\nreturn = %s' % method_information['return']

    return {'name': method_label, 'nodes': blocks_html,
            'edges': edges_html}
def method2dot(mx, tainted1=None, tainted2=None, tainted3=None, annotation=None, variables=None, variables_total=None, colors={}):
    """
        Export analysis method to dot format

        @param mx : MethodAnalysis object
        @param colors : MethodAnalysis object

        @rtype : dot format buffer (it is a subgraph (dict))
    """
    
    tainted1 = tainted1 or {}
    tainted2 = tainted2 or {}
    tainted3 = tainted3 or {}
    annotation = annotation or {}
    variables = variables or {}
    variables_total = variables_total or {}
    
    colors = colors or {"true_branch": "green",
                        "false_branch": "red",
                        "default_branch": "purple",
                        "jump_branch": "blue",
                        "bg_idx": "lightgray",
                        "idx": "blue",
                        "bg_start_idx": "yellow",
                        "bg_instruction": "lightgray",
                        "instruction_name": "black",
                        "instructions_operands": "yellow",

                        "raw": "red",
                        "string": "red",
                        "literal": "green",
                        "offset": "#4000FF",
                        "method": "#DF3A01",
                        "field": "#088A08",
                        "type": "#0000FF",

                        "registers_range": ("#999933", "#6666FF")
                        }

    node_tpl = "\nstruct_%s [label=<\n<TABLE BORDER=\"2\" CELLBORDER=\"0\" CELLSPACING=\"3\" >\n%s</TABLE>>];\n"#STYLE=\"ROUNDED\"
    #                                                                                                                               v first tainting stuff       v second tainting stuff                       v third tainting stuff                     v annotation             v variables    
    label_tpl = "<TR><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%x</FONT> </TD><TD ALIGN=\"RIGHT\" BGCOLOR=\"%s\"> %s </TD><TD ALIGN=\"RIGHT\" BGCOLOR=\"%s\"> %s </TD><TD ALIGN=\"RIGHT\" BGCOLOR=\"%s\"> %s </TD><TD ALIGN=\"RIGHT\"> %s </TD><TD ALIGN=\"LEFT\"> %s </TD><TD ALIGN=\"LEFT\" BGCOLOR=\"%s\"> <FONT FACE=\"Times-Bold\" color=\"%s\">%s </FONT> %s </TD></TR>\n"
    link_tpl = "<TR><TD PORT=\"%s\"></TD></TR>\n"

    edges_html = ""
    blocks_html = ""

    method = mx.get_method()
    sha256 = hashlib.sha256("%s%s%s" % (mx.get_method().get_class_name(), mx.get_method().get_name(), mx.get_method().get_descriptor())).hexdigest()

    registers = {}
    if method.get_code():
        for i in range(method.get_code().get_registers_size()):
            registers[i] = 0

    #for DVMBasicMethodBlock in mx.basic_blocks.gets():
    #    ins_idx = DVMBasicMethodBlock.start

        # loop over method instructions
    #    for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions():
    #        operands = DVMBasicMethodBlockInstruction.get_operands(ins_idx)
    #        for register in operands:
    #            if register[0] == 0:
    #                if register[1] not in registers:
    #                    registers[register[1]] = 0
    #                registers[register[1]] += 1

    if registers:
        registers_colors = color_range(colors["registers_range"][0],
                                       colors["registers_range"][1],
                                       len(registers))
        for i in registers:
            registers[i] = registers_colors.pop(0)

    new_links = []
    
    params = []
    method_information = method.get_information()
    if method_information:
        if "params" in method_information:
            for register, _ in method_information["params"]:
                params.append('v'+str(register))

    for DVMBasicMethodBlock in mx.basic_blocks.gets():
        ins_idx = DVMBasicMethodBlock.start
        block_id = hashlib.md5(sha256 + DVMBasicMethodBlock.name).hexdigest()

        content = link_tpl % 'header'

        for DVMBasicMethodBlockInstruction in DVMBasicMethodBlock.get_instructions():
            if DVMBasicMethodBlockInstruction.get_op_value() == 0x2b or DVMBasicMethodBlockInstruction.get_op_value() == 0x2c:
                new_links.append((DVMBasicMethodBlock, ins_idx, DVMBasicMethodBlockInstruction.get_ref_off() * 2 + ins_idx))
            elif DVMBasicMethodBlockInstruction.get_op_value() == 0x26:
                new_links.append((DVMBasicMethodBlock, ins_idx, DVMBasicMethodBlockInstruction.get_ref_off() * 2 + ins_idx))

            operands = DVMBasicMethodBlockInstruction.get_operands(ins_idx)
            output = ", ".join(mx.get_vm().get_operand_html(i, registers, colors, escape, textwrap.wrap) for i in operands)
            
            if ins_idx in tainted1:
                output_tainted1 = ", ".join([i for i in tainted1[ins_idx][1] if i not in params])
                params_tainted1 = [i for i in tainted1[ins_idx][1] if i in params]
                if output_tainted1 and params_tainted1:
                    output_tainted1 += " | "
                if params_tainted1:
                    output_tainted1 += "<FONT color=\"red\">"+", ".join(params_tainted1)+"</FONT>"
            else:
                output_tainted1 = ''
            
            if ins_idx in tainted2:
                output_tainted2 = ", ".join([i for i in tainted2[ins_idx][1] if i not in params])
                params_tainted2 = [i for i in tainted2[ins_idx][1] if i in params]
                if output_tainted2 and params_tainted2:
                    output_tainted2 += " | "
                if params_tainted2:
                    output_tainted2 += "<FONT color=\"red\">"+", ".join(params_tainted2)+"</FONT>"
            else:
                output_tainted2 = ''
                
            if ins_idx in tainted3:
                output_tainted3 = ", ".join([i for i in tainted3[ins_idx][1] if i not in params])
                params_tainted3 = [i for i in tainted3[ins_idx][1] if i in params]
                if output_tainted3 and params_tainted3:
                    output_tainted3 += " | "
                if params_tainted3:
                    output_tainted3 += "<FONT color=\"red\">"+", ".join(params_tainted3)+"</FONT>"
            else:
                output_tainted3 = ''
                
            if ins_idx in annotation:
                temp = []
                for bla, lol in annotation[ins_idx].items():
                    temp.append("%s: %s" % (bla, ", ".join(lol)))
                output_annotation = "; ".join(temp)  
            else:
                output_annotation = ''
            
            if ins_idx in variables:
                output_variables = ", ".join(sorted(variables[ins_idx]))
            else:
                output_variables = ''

            formatted_operands = DVMBasicMethodBlockInstruction.get_formatted_operands()
            if formatted_operands:
                output += " ; %s" % str(formatted_operands)

            bg_idx = colors["bg_idx"]
            if ins_idx == 0 and "bg_start_idx" in colors:
                bg_idx = colors["bg_start_idx"]

            content += label_tpl % (bg_idx,
                                    colors["idx"],
                                    ins_idx,
                                    colors["bg_instruction"],
                                    output_tainted1,
                                    colors["bg_instruction"],
                                    output_tainted2,
                                    colors["bg_instruction"],
                                    output_tainted3,
                                    output_annotation,
                                    output_variables,
                                    colors["bg_instruction"],
                                    colors["instruction_name"],
                                    DVMBasicMethodBlockInstruction.get_name(),
                                    output)

            ins_idx += DVMBasicMethodBlockInstruction.get_length()
            last_instru = DVMBasicMethodBlockInstruction

        # all blocks from one method parsed
        # updating dot HTML content
        content += link_tpl % 'tail'
        blocks_html += node_tpl % (block_id, content)

        # Block edges color treatment (conditional branchs colors)
        val = colors["true_branch"]
        if len(DVMBasicMethodBlock.childs) > 1:
            val = colors["false_branch"]
        elif len(DVMBasicMethodBlock.childs) == 1:
            val = colors["jump_branch"]

        values = None
        if (last_instru.get_op_value() == 0x2b or last_instru.get_op_value() == 0x2c) and len(DVMBasicMethodBlock.childs) > 1:
            val = colors["default_branch"]
            values = ["default"]
            values.extend(DVMBasicMethodBlock.get_special_ins(ins_idx - last_instru.get_length()).get_values())

        # updating dot edges
        for DVMBasicMethodBlockChild in DVMBasicMethodBlock.childs:
            label_edge = ""

            if values:
                label_edge = values.pop(0)

            child_id = hashlib.md5(sha256 + DVMBasicMethodBlockChild[-1].name).hexdigest()
            edges_html += "struct_%s:tail -> struct_%s:header  [penwidth=\"2\",color=\"%s\", label=\"%s\"];\n" % (block_id, child_id, val, label_edge)
            # color switch
            if val == colors["false_branch"]:
                val = colors["true_branch"]
            elif val == colors["default_branch"]:
                val = colors["true_branch"]

        exception_analysis = DVMBasicMethodBlock.get_exception_analysis()
        if exception_analysis:
            for exception_elem in exception_analysis.exceptions:
                exception_block = exception_elem[-1]
                if exception_block:
                    exception_id = hashlib.md5(sha256 + exception_block.name).hexdigest()
                    edges_html += "struct_%s:tail -> struct_%s:header  [penwidth=\"2\",color=\"%s\", label=\"%s\"];\n" % (block_id, exception_id, "black", exception_elem[0])

    for link in new_links:
        DVMBasicMethodBlock = link[0]
        DVMBasicMethodBlockChild = mx.basic_blocks.get_basic_block(link[2])

        if DVMBasicMethodBlockChild:
            block_id = hashlib.md5(sha256 + DVMBasicMethodBlock.name).hexdigest()
            child_id = hashlib.md5(sha256 + DVMBasicMethodBlockChild.name).hexdigest()

            edges_html += "struct_%s:tail -> struct_%s:header  [penwidth=\"2\",color=\"%s\", label=\"data(0x%x) to @0x%x\", style=\"dashed\"];\n" % (block_id, child_id, "yellow", link[1], link[2])

    method_label = method.get_class_name() + "." + method.get_name() + "->" + method.get_descriptor()

    method_information = method.get_information()
    if method_information:
        method_label += "\\nLocal registers v%d ... v%d" % (method_information["registers"][0], method_information["registers"][1])
        if "params" in method_information:
            for register, rtype in method_information["params"]:
                method_label += "\\nparam v%d = %s" % (register, rtype)
        method_label += "\\nreturn = %s" % (method_information["return"])
        method_label += "\\nTypes:\\n"
        for k, v in variables_total.items():
            method_label += "%s: %s\\n" % (k, ", ".join(v))
        method_label += "\\nMarked at -1:"
        if tainted1.get(-1):
            method_label += "\\nBackward: %s" % ", ".join(tainted1.get(-1)[1])
        if tainted2.get(-1):
            method_label += "\\nForward: %s" %  ", ".join(tainted2.get(-1)[1])
        if tainted3.get(-1):
            method_label += "\\nCombined: %s" %  ", ".join(tainted3.get(-1)[1])

    return {'name': method_label,
            'nodes': blocks_html,
            'edges': edges_html}