Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
Public Member Functions | Public Attributes | List of all members
miasm2.ir.symbexec.symbexec Class Reference
+ Inheritance diagram for miasm2.ir.symbexec.symbexec:
+ Collaboration diagram for miasm2.ir.symbexec.symbexec:

Public Member Functions

def __init__
 
def find_mem_by_addr
 
def eval_ExprId
 
def eval_ExprInt
 
def eval_ExprMem
 
def eval_expr_visit
 
def eval_expr
 
def modified_regs
 
def modified_mems
 
def modified
 
def dump_id
 
def dump_mem
 
def rest_slice
 
def substract_mems
 
def get_mem_overlapping
 
def eval_ir_expr
 
def eval_ir
 
def emulbloc
 
def emul_ir_bloc
 
def emul_ir_blocs
 
def del_mem_above_stack
 

Public Attributes

 symbols
 
 func_read
 
 func_write
 
 ir_arch
 
 expr_simp
 

Detailed Description

Definition at line 83 of file symbexec.py.

Constructor & Destructor Documentation

def miasm2.ir.symbexec.symbexec.__init__ (   self,
  ir_arch,
  known_symbols,
  func_read = None,
  func_write = None,
  sb_expr_simp = expr_simp 
)

Definition at line 88 of file symbexec.py.

88 
89  sb_expr_simp=expr_simp):
90  self.symbols = symbols()
91  for k, v in known_symbols.items():
92  self.symbols[k] = v
93  self.func_read = func_read
94  self.func_write = func_write
95  self.ir_arch = ir_arch
96  self.expr_simp = sb_expr_simp

Member Function Documentation

def miasm2.ir.symbexec.symbexec.del_mem_above_stack (   self,
  sp 
)

Definition at line 446 of file symbexec.py.

447  def del_mem_above_stack(self, sp):
448  sp_val = self.symbols[sp]
449  for mem_ad, (mem, _) in self.symbols.symbols_mem.items():
450  # print mem_ad, sp_val
451  diff = self.eval_expr(mem_ad - sp_val, {})
452  diff = expr_simp(diff)
453  if not isinstance(diff, m2_expr.ExprInt):
454  continue
455  m = expr_simp(diff.msb())
456  if m.arg == 1:
457  del self.symbols[mem]
458 

+ Here is the call graph for this function:

def miasm2.ir.symbexec.symbexec.dump_id (   self)

Definition at line 263 of file symbexec.py.

264  def dump_id(self):
265  ids = self.symbols.symbols_id.keys()
266  ids.sort()
267  for i in ids:
268  if i in self.ir_arch.arch.regs.regs_init and \
269  i in self.symbols.symbols_id and \
270  self.symbols.symbols_id[i] == self.ir_arch.arch.regs.regs_init[i]:
271  continue
272  print i, self.symbols.symbols_id[i]

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.dump_mem (   self)

Definition at line 273 of file symbexec.py.

274  def dump_mem(self):
275  mems = self.symbols.symbols_mem.values()
276  mems.sort()
277  for m, v in mems:
278  print m, v
def miasm2.ir.symbexec.symbexec.emul_ir_bloc (   self,
  myir,
  ad,
  step = False 
)

Definition at line 430 of file symbexec.py.

431  def emul_ir_bloc(self, myir, ad, step=False):
432  b = myir.get_bloc(ad)
433  if b is not None:
434  ad = self.emulbloc(b, step=step)
435  return ad

+ Here is the call graph for this function:

def miasm2.ir.symbexec.symbexec.emul_ir_blocs (   self,
  myir,
  ad,
  lbl_stop = None,
  step = False 
)

Definition at line 436 of file symbexec.py.

437  def emul_ir_blocs(self, myir, ad, lbl_stop=None, step=False):
438  while True:
439  b = myir.get_bloc(ad)
440  if b is None:
441  break
442  if b.label == lbl_stop:
443  break
444  ad = self.emulbloc(b, step=step)
445  return ad

+ Here is the call graph for this function:

def miasm2.ir.symbexec.symbexec.emulbloc (   self,
  bloc_ir,
  step = False 
)

Definition at line 421 of file symbexec.py.

422  def emulbloc(self, bloc_ir, step=False):
423  for ir in bloc_ir.irs:
424  self.eval_ir(ir)
425  if step:
426  print '_' * 80
427  self.dump_id()
428  eval_cache = dict(self.symbols.items())
429  return self.eval_expr(self.ir_arch.IRDst, eval_cache)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_expr (   self,
  e,
  eval_cache = None 
)

Definition at line 233 of file symbexec.py.

234  def eval_expr(self, e, eval_cache=None):
235  if eval_cache is None:
236  eval_cache = {}
237  r = e.visit(lambda x: self.eval_expr_visit(x, eval_cache))
238  return r

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_expr_visit (   self,
  e,
  eval_cache = None 
)

Definition at line 211 of file symbexec.py.

212  def eval_expr_visit(self, e, eval_cache=None):
213  if eval_cache is None:
214  eval_cache = {}
215  # print 'visit', e, e.is_term
216  if e.is_term:
217  return e
218  if e in eval_cache:
219  return eval_cache[e]
220  c = e.__class__
221  deal_class = {m2_expr.ExprId: self.eval_ExprId,
222  m2_expr.ExprInt: self.eval_ExprInt,
223  m2_expr.ExprMem: self.eval_ExprMem,
224  }
225  # print 'eval', e
226  if c in deal_class:
227  e = deal_class[c](e, eval_cache)
228  # print "ret", e
229  if not (isinstance(e, m2_expr.ExprId) or isinstance(e,
230  m2_expr.ExprInt)):
231  e.is_term = True
232  return e

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_ExprId (   self,
  e,
  eval_cache = None 
)

Definition at line 102 of file symbexec.py.

103  def eval_ExprId(self, e, eval_cache=None):
104  if eval_cache is None:
105  eval_cache = {}
106  if isinstance(e.name, asmbloc.asm_label) and e.name.offset is not None:
107  return m2_expr.ExprInt_from(e, e.name.offset)
108  if not e in self.symbols:
109  # raise ValueError('unknown symbol %s'% e)
110  return e
111  return self.symbols[e]

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_ExprInt (   self,
  e,
  eval_cache = None 
)

Definition at line 112 of file symbexec.py.

113  def eval_ExprInt(self, e, eval_cache=None):
114  return e

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_ExprMem (   self,
  e,
  eval_cache = None 
)

Definition at line 115 of file symbexec.py.

116  def eval_ExprMem(self, e, eval_cache=None):
117  if eval_cache is None:
118  eval_cache = {}
119  a_val = self.expr_simp(self.eval_expr(e.arg, eval_cache))
120  if a_val != e.arg:
121  a = self.expr_simp(m2_expr.ExprMem(a_val, size=e.size))
122  else:
123  a = e
124  if a in self.symbols:
125  return self.symbols[a]
126  tmp = None
127  # test if mem lookup is known
128  if a_val in self.symbols.symbols_mem:
129  tmp = self.symbols.symbols_mem[a_val][0]
130  if tmp is None:
131 
132  v = self.find_mem_by_addr(a_val)
133  if not v:
134  out = []
135  ov = self.get_mem_overlapping(a, eval_cache)
136  off_base = 0
137  ov.sort()
138  # ov.reverse()
139  for off, x in ov:
140  # off_base = off * 8
141  # x_size = self.symbols[x].size
142  if off >= 0:
143  m = min(a.size - off * 8, x.size)
144  ee = m2_expr.ExprSlice(self.symbols[x], 0, m)
145  ee = self.expr_simp(ee)
146  out.append((ee, off_base, off_base + m))
147  off_base += m
148  else:
149  m = min(a.size - off * 8, x.size)
150  ee = m2_expr.ExprSlice(self.symbols[x], -off * 8, m)
151  ff = self.expr_simp(ee)
152  new_off_base = off_base + m + off * 8
153  out.append((ff, off_base, new_off_base))
154  off_base = new_off_base
155  if out:
156  missing_slice = self.rest_slice(out, 0, a.size)
157  for sa, sb in missing_slice:
158  ptr = self.expr_simp(
159  a_val + m2_expr.ExprInt_from(a_val, sa / 8)
160  )
161  mm = m2_expr.ExprMem(ptr, size=sb - sa)
162  mm.is_term = True
163  mm.is_simp = True
164  out.append((mm, sa, sb))
165  out.sort(key=lambda x: x[1])
166  # for e, sa, sb in out:
167  # print str(e), sa, sb
168  ee = m2_expr.ExprSlice(m2_expr.ExprCompose(out), 0, a.size)
169  ee = self.expr_simp(ee)
170  return ee
171  if self.func_read and isinstance(a.arg, m2_expr.ExprInt):
172  return self.func_read(a)
173  else:
174  # XXX hack test
175  a.is_term = True
176  return a
177  # bigger lookup
178  if a.size > tmp.size:
179  rest = a.size
180  ptr = a_val
181  out = []
182  ptr_index = 0
183  while rest:
184  v = self.find_mem_by_addr(ptr)
185  if v is None:
186  # raise ValueError("cannot find %s in mem"%str(ptr))
187  val = m2_expr.ExprMem(ptr, 8)
188  v = val
189  diff_size = 8
190  elif rest >= v.size:
191  val = self.symbols[v]
192  diff_size = v.size
193  else:
194  diff_size = rest
195  val = self.symbols[v][0:diff_size]
196  val = (val, ptr_index, ptr_index + diff_size)
197  out.append(val)
198  ptr_index += diff_size
199  rest -= diff_size
200  ptr = self.expr_simp(
201  self.eval_expr(
202  m2_expr.ExprOp('+', ptr,
203  m2_expr.ExprInt_from(ptr, v.size / 8)),
204  eval_cache)
205  )
206  e = self.expr_simp(m2_expr.ExprCompose(out))
207  return e
208  # part lookup
209  tmp = self.expr_simp(m2_expr.ExprSlice(self.symbols[tmp], 0, a.size))
210  return tmp

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_ir (   self,
  ir 
)

Definition at line 399 of file symbexec.py.

400  def eval_ir(self, ir):
401  mem_dst = []
402  # src_dst = [(x.src, x.dst) for x in ir]
403  src_dst = self.eval_ir_expr(ir)
404  eval_cache = dict(self.symbols.items())
405  for dst, src in src_dst:
406  if isinstance(dst, m2_expr.ExprMem):
407  mem_overlap = self.get_mem_overlapping(dst, eval_cache)
408  for _, base in mem_overlap:
409  diff_mem = self.substract_mems(base, dst)
410  del self.symbols[base]
411  for new_mem, new_val in diff_mem:
412  new_val.is_term = True
413  self.symbols[new_mem] = new_val
414  src_o = self.expr_simp(src)
415  # print 'SRCo', src_o
416  # src_o.is_term = True
417  self.symbols[dst] = src_o
418  if isinstance(dst, m2_expr.ExprMem):
419  mem_dst.append(dst)
420  return mem_dst

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.eval_ir_expr (   self,
  exprs 
)

Definition at line 369 of file symbexec.py.

370  def eval_ir_expr(self, exprs):
371  pool_out = {}
372 
373  eval_cache = dict(self.symbols.items())
374 
375  for e in exprs:
376  if not isinstance(e, m2_expr.ExprAff):
377  raise TypeError('not affect', str(e))
378 
379  src = self.eval_expr(e.src, eval_cache)
380  if isinstance(e.dst, m2_expr.ExprMem):
381  a = self.eval_expr(e.dst.arg, eval_cache)
382  a = self.expr_simp(a)
383  # search already present mem
384  tmp = None
385  # test if mem lookup is known
386  tmp = m2_expr.ExprMem(a, e.dst.size)
387  dst = tmp
388  if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
389  self.func_write(self, dst, src, pool_out)
390  else:
391  pool_out[dst] = src
392 
393  elif isinstance(e.dst, m2_expr.ExprId):
394  pool_out[e.dst] = src
395  else:
396  raise ValueError("affected zarb", str(e.dst))
397 
398  return pool_out.items()

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.find_mem_by_addr (   self,
  e 
)

Definition at line 97 of file symbexec.py.

97 
98  def find_mem_by_addr(self, e):
99  if e in self.symbols.symbols_mem:
100  return self.symbols.symbols_mem[e][0]
101  return None

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.get_mem_overlapping (   self,
  e,
  eval_cache = None 
)

Definition at line 341 of file symbexec.py.

342  def get_mem_overlapping(self, e, eval_cache=None):
343  if eval_cache is None:
344  eval_cache = {}
345  if not isinstance(e, m2_expr.ExprMem):
346  raise ValueError('mem overlap bad arg')
347  ov = []
348  # suppose max mem size is 64 bytes, compute all reachable addresses
349  to_test = []
350  base_ptr = self.expr_simp(e.arg)
351  for i in xrange(-7, e.size / 8):
352  ex = self.expr_simp(
353  self.eval_expr(base_ptr + m2_expr.ExprInt_from(e.arg, i),
354  eval_cache))
355  to_test.append((i, ex))
356 
357  for i, x in to_test:
358  if not x in self.symbols.symbols_mem:
359  continue
360  ex = self.expr_simp(self.eval_expr(e.arg - x, eval_cache))
361  if not isinstance(ex, m2_expr.ExprInt):
362  raise ValueError('ex is not ExprInt')
363  ptr_diff = int32(ex.arg)
364  if ptr_diff >= self.symbols.symbols_mem[x][1].size / 8:
365  # print "too long!"
366  continue
367  ov.append((i, self.symbols.symbols_mem[x][0]))
368  return ov

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.modified (   self,
  init_state = None 
)

Definition at line 257 of file symbexec.py.

258  def modified(self, init_state=None):
259  for r in self.modified_regs(init_state):
260  yield r
261  for m in self.modified_mems(init_state):
262  yield m

+ Here is the call graph for this function:

def miasm2.ir.symbexec.symbexec.modified_mems (   self,
  init_state = None 
)

Definition at line 251 of file symbexec.py.

252  def modified_mems(self, init_state=None):
253  mems = self.symbols.symbols_mem.values()
254  mems.sort()
255  for m, _ in mems:
256  yield m

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.modified_regs (   self,
  init_state = None 
)

Definition at line 239 of file symbexec.py.

240  def modified_regs(self, init_state=None):
241  if init_state is None:
242  init_state = self.ir_arch.arch.regs.regs_init
243  ids = self.symbols.symbols_id.keys()
244  ids.sort()
245  for i in ids:
246  if i in init_state and \
247  i in self.symbols.symbols_id and \
248  self.symbols.symbols_id[i] == init_state[i]:
249  continue
250  yield i

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.rest_slice (   self,
  slices,
  start,
  stop 
)

Definition at line 279 of file symbexec.py.

280  def rest_slice(self, slices, start, stop):
281  o = []
282  last = start
283  for _, a, b in slices:
284  if a == last:
285  last = b
286  continue
287  o.append((last, a))
288  last = b
289  if last != stop:
290  o.append((b, stop))
291  return o

+ Here is the caller graph for this function:

def miasm2.ir.symbexec.symbexec.substract_mems (   self,
  a,
  b 
)

Definition at line 292 of file symbexec.py.

293  def substract_mems(self, a, b):
294  ex = b.arg - a.arg
295  ex = self.expr_simp(self.eval_expr(ex, {}))
296  if not isinstance(ex, m2_expr.ExprInt):
297  return None
298  ptr_diff = int(int32(ex.arg))
299  out = []
300  if ptr_diff < 0:
301  # [a ]
302  #[b ]XXX
303  sub_size = b.size + ptr_diff * 8
304  if sub_size >= a.size:
305  pass
306  else:
307  ex = m2_expr.ExprOp('+', a.arg,
308  m2_expr.ExprInt_from(a.arg, sub_size / 8))
309  ex = self.expr_simp(self.eval_expr(ex, {}))
310 
311  rest_ptr = ex
312  rest_size = a.size - sub_size
313 
314  val = self.symbols[a][sub_size:a.size]
315  out = [(m2_expr.ExprMem(rest_ptr, rest_size), val)]
316  else:
317  #[a ]
318  # XXXX[b ]YY
319 
320  #[a ]
321  # XXXX[b ]
322 
323  out = []
324  # part X
325  if ptr_diff > 0:
326  val = self.symbols[a][0:ptr_diff * 8]
327  out.append((m2_expr.ExprMem(a.arg, ptr_diff * 8), val))
328  # part Y
329  if ptr_diff * 8 + b.size < a.size:
330 
331  ex = m2_expr.ExprOp('+', b.arg,
332  m2_expr.ExprInt_from(b.arg, b.size / 8))
333  ex = self.expr_simp(self.eval_expr(ex, {}))
334 
335  rest_ptr = ex
336  rest_size = a.size - (ptr_diff * 8 + b.size)
337  val = self.symbols[a][ptr_diff * 8 + b.size:a.size]
338  out.append((m2_expr.ExprMem(ex, val.size), val))
339  return out

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

miasm2.ir.symbexec.symbexec.expr_simp

Definition at line 95 of file symbexec.py.

miasm2.ir.symbexec.symbexec.func_read

Definition at line 92 of file symbexec.py.

miasm2.ir.symbexec.symbexec.func_write

Definition at line 93 of file symbexec.py.

miasm2.ir.symbexec.symbexec.ir_arch

Definition at line 94 of file symbexec.py.

miasm2.ir.symbexec.symbexec.symbols

Definition at line 89 of file symbexec.py.


The documentation for this class was generated from the following file: