Beispiel #1
0
        def cut_path(g, e, force_start_e=-1):
            els = grp_endloops[g]
            newp = Paths(self.gph)
            all_finish_by_jump = True

            for k, p in els.paths.items():

                if force_start_e != -1:
                    start = index(p, force_start_e)
                else:
                    start = prev_cut_idx[k]

                stop = -1 if e == -1 else index(p, e)
                if stop == -1:
                    stop = len(p)

                if force_start_e == -1:
                    prev_cut_idx[k] = start

                loop_idx = -1
                if stop == len(p):
                    loop_idx = els.__get_loop_idx(k)

                if start == 0 and stop == len(p):
                    p2 = p
                else:
                    p2 = p[start:stop]

                if not p2:
                    continue

                newp.add_path(k, p2, loop_idx)

                # If it's an internal loop, we don't have to check
                # if the last instruction is a jump.
                if els.__is_looping(k, last_loop_idx):
                    continue

                # Check if the last instruction is a jump and
                # go to the endpoint.
                if p[stop - 1] in self.gph_link_out:
                    nxt = self.gph_link_out[p[stop - 1]]
                    # TODO need to check cond jumps ?
                    if not(len(nxt) == 1 and \
                            p[stop-1] in self.gph_uncond_jumps_set and \
                            nxt[BRANCH_NEXT] == e):
                        all_finish_by_jump = False
                else:
                    # It's a return, there is nothing after. It must be
                    # in the future dict 'next_no_jump'.
                    all_finish_by_jump = False

            return newp, all_finish_by_jump
Beispiel #2
0
        def cut_path(g, e, force_start_e=-1):
            els = grp_endloops[g]
            newp = Paths(self.gph)
            all_finish_by_jump = True

            for k, p in els.paths.items():

                if force_start_e != -1:
                    start = index(p, force_start_e)
                else:
                    start = prev_cut_idx[k]

                stop = -1 if e == -1 else index(p, e)
                if stop == -1: 
                    stop = len(p)

                if force_start_e == -1:
                    prev_cut_idx[k] = start

                loop_idx = -1
                if stop == len(p):
                    loop_idx = els.__get_loop_idx(k)

                if start == 0 and stop == len(p):
                    p2 = p
                else:
                    p2 = p[start:stop]

                if not p2:
                    continue

                newp.add_path(k, p2, loop_idx)

                # If it's an internal loop, we don't have to check
                # if the last instruction is a jump.
                if els.__is_looping(k, last_loop_idx):
                    continue

                # Check if the last instruction is a jump and
                # go to the endpoint.
                if p[stop-1] in self.gph_link_out:
                    nxt = self.gph_link_out[p[stop-1]]
                    # TODO need to check cond jumps ?
                    if not(len(nxt) == 1 and \
                            p[stop-1] in self.gph_uncond_jumps_set and \
                            nxt[BRANCH_NEXT] == e):
                        all_finish_by_jump = False
                else:
                    # It's a return, there is nothing after. It must be
                    # in the future dict 'next_no_jump'.
                    all_finish_by_jump = False

            return newp, all_finish_by_jump
Beispiel #3
0
    def __rec_explore(self, paths, p, new):
        myk = self.__key_path_count
        self.__key_path_count += 1
        paths.paths[myk] = p
        p_set = set(p) # optimization search

        while new in self.link_out:
            if new in p_set:
                # loop detected
                idx_node = p.index(new)
                l = p[idx_node:]
                l_idx = index(self.loops, l)

                if l_idx == -1:
                    l_idx = len(self.loops)
                    self.loops.append(l)
                    self.loops_set.append(set(l))

                paths.looping[myk] = l_idx
                return

            else:
                p.append(new)
                p_set.add(new)
                nxt = self.link_out[new]

                # much faster than: is_cond_jump(self.dis.code[new])
                if len(nxt) == 2:
                    self.__rec_explore(paths, list(p), nxt[BRANCH_NEXT_JUMP])

                new = nxt[BRANCH_NEXT]

        p.append(new)
Beispiel #4
0
    def __rec_explore(self, paths, p, new):
        myk = self.__key_path_count
        self.__key_path_count += 1
        paths.paths[myk] = p
        p_set = set(p)  # optimization search

        while new in self.link_out:
            if new in p_set:
                # loop detected
                idx_node = p.index(new)
                l = p[idx_node:]
                l_idx = index(self.loops, l)

                if l_idx == -1:
                    l_idx = len(self.loops)
                    self.loops.append(l)
                    self.loops_set.append(set(l))

                paths.looping[myk] = l_idx
                return

            else:
                p.append(new)
                p_set.add(new)
                nxt = self.link_out[new]

                # much faster than: is_cond_jump(self.dis.code[new])
                if len(nxt) == 2:
                    self.__rec_explore(paths, list(p), nxt[BRANCH_NEXT_JUMP])

                new = nxt[BRANCH_NEXT]

        p.append(new)
Beispiel #5
0
        def save_step(k, addr, create):
            nonlocal new_paths, moved

            try:
                # This path is looping if index doesn't fail

                idx_node = self.paths.paths[k].index(addr)

                l = self.paths.paths[k][idx_node:]
                l_idx = index(self.loops, l)

                if l_idx == -1:
                    l_idx = len(self.loops)
                    self.loops.append(l)
                    self.loops_set.append(set(l))

                if create:
                    idx_new_path = len(self.paths.paths) + len(new_paths)
                    self.paths.looping[idx_new_path] = l_idx
                    new_paths.append(list(self.paths.paths[k]))
                else:
                    self.paths.looping[k] = l_idx

            except ValueError:
                moved = True
                if create:
                    new_paths.append(self.paths.paths[k] + [addr])
                else:
                    self.paths.paths[k].append(addr)
Beispiel #6
0
    def goto_addr(self, addr):
        to_remove = []
        for k, p in self.paths.items():
            idx = index(p, addr)
            if idx != -1:
                self.paths[k] = p[idx:]
            else:
                to_remove.append(k)

        all_removed = len(to_remove) == len(self.paths)

        for k in to_remove:
            self.__del_path(k)

        return all_removed
Beispiel #7
0
    def goto_addr(self, addr):
        to_remove = []
        for k, p in self.paths.items():
            idx = index(p, addr)
            if idx != -1:
                self.paths[k] = p[idx:]
            else:
                to_remove.append(k)

        all_removed = len(to_remove) == len(self.paths)

        for k in to_remove:
            self.__del_path(k)

        return all_removed
Beispiel #8
0
    def dump(self, addr, lines):
        i_init = index(self.code_idx, addr)
        end = min(len(self.code_idx), i_init + lines)

        # set jumps color
        i = i_init
        while i < end:
            inst = self.code[self.code_idx[i]]
            if is_jump(inst) and inst.operands[0].type == X86_OP_IMM:
                pick_color(inst.operands[0].value.imm)
            i += 1

        i = i_init
        while i < end:
            inst = self.code[self.code_idx[i]]
            if inst.address in self.binary.reverse_symbols:
                print_symbol(inst.address)
                print()
            print_inst(inst, 0)
            i += 1
Beispiel #9
0
    def __is_in_curr_loop(self, loop):
        # Assume that current paths is a loop
        curr_loop = self.first()

        if loop[0] != curr_loop:
            return False

        # Check if all address of loop are in paths
        if not all(addr in self for addr in loop):
            return False

        # Check if the loop is in the right order
        for p in self.paths.values():
            last_idx = -1
            for addr in loop:
                idx = index(p, addr)
                if idx == -1:
                    break
                elif idx < last_idx:
                    return False
                else:
                    last_idx = idx

        return True
Beispiel #10
0
    def __is_in_curr_loop(self, loop):
        # Assume that current paths is a loop
        curr_loop = self.first()

        if loop[0] != curr_loop:
            return False

        # Check if all address of loop are in paths
        if not all(addr in self for addr in loop):
            return False

        # Check if the loop is in the right order
        for p in self.paths.values():
            last_idx = -1
            for addr in loop:
                idx = index(p, addr)
                if idx == -1:
                    break
                elif idx < last_idx:
                    return False
                else:
                    last_idx = idx

        return True