2 import get_expr_mem, get_list_rw, ExprId, ExprInt
14 Create data flow for an irbloc using raw IR expressions
19 for i, exprs
in enumerate(irb.irs):
21 current_nodes.update(out_nodes)
25 for nodes_r, nodes_w
in list_rw:
26 for n
in nodes_r.union(nodes_w):
36 o_r = n.arg.get_r(mem_read=
False, cst_read=
True)
38 if n_r
in current_nodes:
39 node_n_r = current_nodes[n_r]
42 current_nodes[n_r] = node_n_r
43 in_nodes[n_r] = node_n_r
44 flow_graph.add_uniq_edge(node_n_r, node_n_w)
47 for nodes_r, nodes_w
in list_rw:
49 if n_r
in current_nodes:
50 node_n_r = current_nodes[n_r]
53 current_nodes[n_r] = node_n_r
54 in_nodes[n_r] = node_n_r
56 flow_graph.add_node(node_n_r)
59 out_nodes[n_w] = node_n_w
62 flow_graph.add_node(node_n_w)
63 flow_graph.add_uniq_edge(node_n_r, node_n_w)
64 irb.in_nodes = in_nodes
65 irb.out_nodes = out_nodes
70 Create data flow for an irbloc using symbolic execution
77 for r
in ir_arch.arch.regs.all_regs_ids:
79 x = ExprId(r.name, r.size)
83 sb =
symbexec(ir_arch, dict(symbols_init))
90 for n_w
in sb.symbols:
93 if n_w
in symbols_init
and symbols_init[n_w] == v:
95 read_values = v.get_r(cst_read=
True)
99 for n_r
in read_values:
100 if n_r
in current_nodes:
101 node_n_r = current_nodes[n_r]
104 current_nodes[n_r] = node_n_r
105 in_nodes[n_r] = node_n_r
107 out_nodes[n_w] = node_n_w
108 flow_graph.add_uniq_edge(node_n_r, node_n_w)
110 irb.in_nodes = in_nodes
111 irb.out_nodes = out_nodes
115 lbl, current_nodes, exec_nodes = todo
119 current_nodes = dict(current_nodes)
122 if not lbl
in ir_arch.blocs:
123 print "cannot find bloc!!", lbl
125 irb = ir_arch.blocs[lbl]
128 for n_r, node_n_r
in irb.in_nodes.items():
129 if not n_r
in current_nodes:
132 flow_graph.add_uniq_edge(current_nodes[n_r], node_n_r)
136 if link_exec_to_data:
137 for n_x_r
in exec_nodes:
138 for n_r, node_n_r
in irb.in_nodes.items():
139 if not n_x_r
in current_nodes:
141 if isinstance(n_r, ExprInt):
143 flow_graph.add_uniq_edge(current_nodes[n_x_r], node_n_r)
146 for n_w, node_n_w
in irb.out_nodes.items():
147 current_nodes[n_w] = node_n_w
150 x_nodes = tuple(sorted(list(irb.dst.get_r())))
153 for lbl_dst
in ir_arch.g.successors(irb.label):
154 todo.add((lbl_dst, tuple(current_nodes.items()), x_nodes))
165 todo = set(ir_arch.blocs.keys())
168 irb = ir_arch.blocs[lbl]
169 for lbl_son
in ir_arch.g.successors(irb.label):
170 if not lbl_son
in ir_arch.blocs:
171 print "cannot find bloc!!", lbl
173 irb_son = ir_arch.blocs[lbl_son]
174 for n_r
in irb_son.in_nodes:
175 if n_r
in irb.out_nodes:
177 if not isinstance(n_r, ExprId):
186 node_n_w = irb.label, len(irb.lines), n_r
187 irb.out_nodes[n_r] = node_n_w
188 if not n_r
in irb.in_nodes:
189 irb.in_nodes[n_r] = irb.label, 0, n_r
190 node_n_r = irb.in_nodes[n_r]
192 for lbl_p
in ir_arch.g.predecessors(irb.label):
195 flow_graph.add_uniq_edge(node_n_r, node_n_w)
202 todo.add((irb_0, (), ()))
216 This algorithm will do symbolic execution on a function, trying to propagate
217 states between basic blocs in order to extract inter-blocs dataflow. The
218 algorithm tries to merge states from blocs with multiple parents.
220 There is no real magic here, loops and complex merging will certainly fail.
233 variables = dict(state.symbols.items())
236 b = self.ir_arch.get_bloc(ad)
238 raise ValueError(
"unknown bloc! %s" % ad)
245 variables = variables.items()
247 s = parent, ad, tuple(sorted(variables))
250 if s in self.states_var_done:
253 if not ad in self.stateby_ad:
254 self.stateby_ad[ad] = set()
255 self.stateby_ad[ad].add(state_var)
261 if not ad in self.cpt:
265 def get_next_min(self):
267 for state in self.todo:
269 if not ad in state_by_ad:
271 state_by_ad[ad].append(state)
272 print "XX", [len(x) for x in state_by_ad.values()]
273 state_by_ad = state_by_ad.items()
274 state_by_ad.sort(key=lambda x:len(x[1]))
275 state_by_ad.reverse()
276 return state_by_ad.pop()[1][0]
280 state = self.todo.pop()
284 if len(self.
todo) == 0:
287 print "symbexec watchdog!"
296 parent, ad, s = state
297 self.states_done.add(state)
298 self.states_var_done.add(state)
305 return parent, ad, sb
def intra_bloc_flow_symbexec