Пример #1
0
    def process(self, doAST=False):
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            if doAST:
                self.ast = JSONWriter(None, self).get_ast()
            else:
                self.writer = Writer(None, self)
                self.writer.write_method()
            return

        # Construct the CFG
        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        use_defs, def_uses = build_def_use(graph, self.lparams)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)

        # FIXME var_to_name need to contain the created tmp variables.
        # This seems to be a workaround, we add them into the list manually
        for var, i in def_uses:
            if not isinstance(var, int):
                self.var_to_name[var] = var.upper()

        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        split_if_nodes(graph)
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        simplify(graph)
        graph.compute_rpo()

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/pre-structured')

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/structured')

        if doAST:
            self.ast = JSONWriter(graph, self).get_ast()
        else:
            self.writer = Writer(graph, self)
            self.writer.write_method()
Пример #2
0
    def process(self, doAST=False):
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            if doAST:
                self.ast = JSONWriter(None, self).get_ast()
            else:
                self.writer = Writer(None, self)
                self.writer.write_method()
            return

        # Construct the CFG
        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        use_defs, def_uses = build_def_use(graph, self.lparams)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)

        # FIXME var_to_name need to contain the created tmp variables.
        # This seems to be a workaround, we add them into the list manually
        for var, i in def_uses:
            if not isinstance(var, int):
                self.var_to_name[var] = var.upper()

        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        split_if_nodes(graph)
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        simplify(graph)
        graph.compute_rpo()

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/pre-structured')

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/structured')

        if doAST:
            self.ast = JSONWriter(graph, self).get_ast()
        else:
            self.writer = Writer(graph, self)
            self.writer.write_method()
Пример #3
0
 def testSplitVariablesGCD(self, group_variables_mock):
     group = {'a': [([-1], [0])],
              'b': [([-2], [1])],
              'c': [([0, 6], [2, 5, 6, 7, 8])],
              'd': [([1], [3, 4, 5, 6, 7])],
              'ret': [([3, 8], [9])]}
     group_variables_mock.return_value = group
     dataflow.split_variables(
         mock.sentinel, [0, 1, 2, 3, 4], mock.sentinel, mock.sentinel)
Пример #4
0
 def testSplitVariablesGCD(self, group_variables_mock):
     group = {'a': [([-1], [0])],
              'b': [([-2], [1])],
              'c': [([0, 6], [2, 5, 6, 7, 8])],
              'd': [([1], [3, 4, 5, 6, 7])],
              'ret': [([3, 8], [9])]}
     group_variables_mock.return_value = group
     dataflow.split_variables(
         mock.sentinel, [0, 1, 2, 3, 4], mock.sentinel, mock.sentinel)
Пример #5
0
    def testSplitVariablesIfBool(self, group_variables_mock):
        group = {
            0: [([0], [5, 7]), ([4, 5, 7], [8])],
            1: [([6], [7])],
            2: [([-1], [1, 6])],
            3: [([-2], [2, 3])]
        }
        group_variables_mock.return_value = group
        param1_mock = mock.Mock()
        param2_mock = mock.Mock()
        var0_mock = mock.Mock()
        var1_mock = mock.Mock()
        lvars = {0: var0_mock, 1: var1_mock, 2: param1_mock, 3: param2_mock}
        du = {
            (0, 0): [7, 5],
            (0, 4): [8],
            (0, 5): [8],
            (0, 7): [8],
            (1, 6): [7],
            (2, -1): [6, 1],
            (3, -2): [2, 3]
        }
        ud = {
            (0, 5): [0],
            (0, 7): [0],
            (0, 8): [4, 5, 7],
            (1, 7): [6],
            (2, 1): [-1],
            (2, 6): [-1],
            (3, 2): [-2],
            (3, 3): [-2]
        }
        graph_mock = mock.Mock()
        dataflow.split_variables(graph_mock, lvars, du, ud)

        expected_du = {
            (1, 6): [7],
            (2, -1): [6, 1],
            (3, -2): [2, 3],
            (4, 0): [7, 5],
            (5, 4): [8],
            (5, 5): [8],
            (5, 7): [8]
        }
        expected_ud = {
            (1, 7): [6],
            (2, 1): [-1],
            (2, 6): [-1],
            (3, 2): [-2],
            (3, 3): [-2],
            (4, 5): [0],
            (4, 7): [0],
            (5, 8): [4, 5, 7]
        }
        self.assertEqual(du, expected_du)
        self.assertEqual(ud, expected_ud)
Пример #6
0
    def testSplitVariablesIfBool(self, group_variables_mock):
        group = {
            0: [([0], [5, 7]), ([4, 5, 7], [8])],
            1: [([6], [7])],
            2: [([-1], [1, 6])],
            3: [([-2], [2, 3])]
        }
        group_variables_mock.return_value = group
        param1_mock = mock.Mock()
        param2_mock = mock.Mock()
        var0_mock = mock.Mock()
        var1_mock = mock.Mock()
        lvars = {0: var0_mock, 1: var1_mock, 2: param1_mock, 3: param2_mock}
        du = {
            (0, 0): [7, 5],
            (0, 4): [8],
            (0, 5): [8],
            (0, 7): [8],
            (1, 6): [7],
            (2, -1): [6, 1],
            (3, -2): [2, 3]
        }
        ud = {
            (0, 5): [0],
            (0, 7): [0],
            (0, 8): [4, 5, 7],
            (1, 7): [6],
            (2, 1): [-1],
            (2, 6): [-1],
            (3, 2): [-2],
            (3, 3): [-2]
        }
        graph_mock = mock.Mock()
        dataflow.split_variables(graph_mock, lvars, du, ud)

        expected_du = {
            (1, 6): [7],
            (2, -1): [6, 1],
            (3, -2): [2, 3],
            (4, 0): [7, 5],
            (5, 4): [8],
            (5, 5): [8],
            (5, 7): [8]
        }
        expected_ud = {
            (1, 7): [6],
            (2, 1): [-1],
            (2, 6): [-1],
            (3, 2): [-2],
            (3, 3): [-2],
            (4, 5): [0],
            (4, 7): [0],
            (5, 8): [4, 5, 7]
        }
        self.assertEqual(du, expected_du)
        self.assertEqual(ud, expected_ud)
Пример #7
0
    def process(self, doAST=False):
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            if doAST:
                self.ast = JSONWriter(None, self).get_ast()
            else:
                self.writer = Writer(None, self)
                self.writer.write_method()
            return

        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        use_defs, def_uses = build_def_use(graph, self.lparams)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)

        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        split_if_nodes(graph)
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        simplify(graph)
        graph.compute_rpo()

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/pre-structured')

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/structured')

        if doAST:
            self.ast = JSONWriter(graph, self).get_ast()
        else:
            self.writer = Writer(graph, self)
            self.writer.write_method()
Пример #8
0
    def process(self, doAST=False):
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            if doAST:
                self.ast = JSONWriter(None, self).get_ast()
            else:
                self.writer = Writer(None, self)
                self.writer.write_method()
            return

        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        use_defs, def_uses = build_def_use(graph, self.lparams)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)

        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        split_if_nodes(graph)
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        simplify(graph)
        graph.compute_rpo()

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/pre-structured')

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/structured')

        if doAST:
            self.ast = JSONWriter(graph, self).get_ast()
        else:
            self.writer = Writer(graph, self)
            self.writer.write_method()
Пример #9
0
    def process(self):
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            self.writer = Writer(None, self)
            self.writer.write_method()
            return

        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        #idoms = graph.immediate_dominators()
        #DF = dominance_frontier(graph, idoms)
        use_defs, def_uses = build_def_use(graph, self.lparams)
        #phi_placement(graph, DF, self.var_to_name, use_defs, def_uses)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        # TODO: split_variables should update DU/UD
        use_defs, def_uses = build_def_use(graph, self.lparams)

        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)
        
        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        graph.split_if_nodes()
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        graph.simplify()
        graph.reset_rpo()

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph,
                                                    '/tmp/dad/structured')

        self.writer = Writer(graph, self)
        self.writer.write_method()
        del graph
Пример #10
0
    def process(self):
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            self.writer = Writer(None, self)
            self.writer.write_method()
            return

        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        #idoms = graph.immediate_dominators()
        #DF = dominance_frontier(graph, idoms)
        use_defs, def_uses = build_def_use(graph, self.lparams)
        #phi_placement(graph, DF, self.var_to_name, use_defs, def_uses)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        # TODO: split_variables should update DU/UD
        use_defs, def_uses = build_def_use(graph, self.lparams)

        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)

        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        graph.split_if_nodes()
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        graph.simplify()
        graph.reset_rpo()

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/structured')

        self.writer = Writer(graph, self)
        self.writer.write_method()
        del graph
Пример #11
0
    def process(self, doAST=False):
        """
        Processes the method and decompile the code.

        There are two modes of operation:

        1) Normal Decompilation to Java Code
        2) Decompilation into an abstract syntax tree (AST)

        The Decompilation is done twice. First, a rough decompilation is created,
        which is then optimized. Second, the optimized version is used to create the final version.

        :param doAST: generate AST instead of Java Code
        """
        logger.debug('METHOD : %s', self.name)

        # Native methods... no blocks.
        if self.start_block is None:
            logger.debug('Native Method.')
            if doAST:
                self.ast = JSONWriter(None, self).get_ast()
            else:
                self.writer = Writer(None, self)
                self.writer.write_method()
            return

        # Construct the CFG
        graph = construct(self.start_block, self.var_to_name, self.exceptions)
        self.graph = graph

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph, '/tmp/dad/blocks')

        use_defs, def_uses = build_def_use(graph, self.lparams)
        split_variables(graph, self.var_to_name, def_uses, use_defs)
        dead_code_elimination(graph, def_uses, use_defs)
        register_propagation(graph, def_uses, use_defs)
        resolve_variables_type(graph, self.var_to_name, def_uses, use_defs)
        new_instance_propgation(graph, def_uses, use_defs)  #for dummy
        setattr(graph, "group_var",
                group_variables(self.var_to_name, def_uses, use_defs))

        # FIXME var_to_name need to contain the created tmp variables.
        # This seems to be a workaround, we add them into the list manually
        for var, i in def_uses:
            if not isinstance(var, int):
                self.var_to_name[var] = var.upper()

        place_declarations(graph, self.var_to_name, def_uses, use_defs)
        del def_uses, use_defs
        # After the DCE pass, some nodes may be empty, so we can simplify the
        # graph to delete these nodes.
        # We start by restructuring the graph by spliting the conditional nodes
        # into a pre-header and a header part.
        split_if_nodes(graph)
        # We then simplify the graph by merging multiple statement nodes into
        # a single statement node when possible. This also delete empty nodes.

        simplify(graph)
        graph.compute_rpo()

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/pre-structured')

        identify_structures(graph, graph.immediate_dominators())

        if not __debug__:
            # TODO: use tempfile to create a correct tempfile (cross platform compatible)
            util.create_png(self.cls_name, self.name, graph,
                            '/tmp/dad/structured')

        if doAST:
            self.ast = JSONWriter(graph, self).get_ast()
        else:
            self.writer = Writer(graph, self)
            self.writer.write_method()