Пример #1
0
 def get_targets(self,node,parent):
     pc = self.prog.cpu.PC()
     n = node
     mpc = pc
     while True:
         m = n.data.map.use((pc,n.data.address))
         mpc = m(mpc)
         T = _target(mpc,node).expand()
         if len(T)>0: return T
         try:
             n = n.N(-1)[0] # get first parent node (parent arg is unused)
         except IndexError:
             break # we are at function entry node
     # create func nodes:
     xpc = []
     if n.data.misc[code.tag.FUNC_START]:
         if node.data.misc[code.tag.FUNC_END]:
             n.data.misc[code.tag.FUNC_START] += 1
         try:
             fsym = n.data.misc['callers'][0].data.misc['to'].ref
         except (IndexError,TypeError,AttributeError):
             fsym = 'f'
         func = code.func(n.c,name="%s:%s"%(fsym,n.name))
         logger.verbose("function %s created"%func)
         if mpc._is_mem and len(mpc.mods)>0:
             pol = '(assume_no_aliasing)' if self.policy['frame-aliasing']==False else ''
             logger.verbose("pc is memory aliased in %s %s"%(str(func),pol))
             if self.policy['frame-aliasing']==False: mpc.mods = []
         func.map[pc] = mpc
         for cn in n.data.misc['callers']:
             cnpc = cn.data.map.use((pc,cn.data.address))(mpc)
             f = cfg.node(func)
             e = cn.c.add_edge(cfg.link(cn,f))
             xpc.extend(_target(cnpc,e.v[1]).expand())
         n.data.misc['func'] = func
     else:
         xpc.extend(_target(mpc,node).expand())
     return xpc
Пример #2
0
 def getcfg(self,loc=None):
     from collections import OrderedDict,defaultdict
     D = OrderedDict()
     C = defaultdict(lambda: [])
     for b in self.iterblocks(loc):
         n = cfg.node(b)
         D[n.data.address] = n
     # now we have collected an overapprox. of all blocks,
     # lets link those "super-blocks" together:
     while len(D)>0:
         k,n = D.popitem(last=False)
         # add node (does nothing if n is already in G)
         n = self.G.add_vertex(n)
         b = n.data
         # find its links:
         if b.misc['func_call']:
             aret = b.misc['retto']+0
             nret = D.get(aret,None) or self.G.get_with_address(aret)
             if nret is not None:
                 e = cfg.link(n,nret)
                 self.G.add_edge(e)
                 ato  = b.misc['to']
                 if ato is not 0: C[ato+0].append((e,'func_call'))
         elif b.misc['func_goto'] and b.misc['to'] is not 0:
             ato = b.misc['to']+0
             nto = D.get(ato,None) or self.G.get_with_address(ato)
             if nto is not None:
                 e = cfg.link(n,nto)
                 self.G.add_edge(e)
             else:
                 C[ato].append((n,'to'))
             if b.misc['cond']:
                 ato = n.data.support[1]
                 nto = D.get(ato,None) or self.G.get_with_address(ato)
                 if nto is not None:
                     e = cfg.link(n,nto,data=b.misc['cond'][1])
                     self.G.add_edge(e)
                 else:
                     C[ato].append((n,b.misc['cond']))
     # now all super-blocks have been processed, but some may need
     # to be cut, lets handle those missed targets:
     while len(C)>0:
         ato,L = C.popitem()
         n = cfg.node(next(self.iterblocks(ato)))
         n = self.G.add_vertex(n)
         for (p,why) in L:
             if why is 'func_call':
                 if n.data.misc['callers']:
                     n.data.misc['callers'].append(p)
                 else:
                     n.data.misc['callers']=[p]
             else:
                 e = cfg.link(p,n)
                 self.G.add_edge(e)
     # finally create func objects and insert nodes:
     for n in self.G.V():
         if n.data.misc['callers']:
             n.data.misc['func'] = f = code.func(n.c)
             calls = []
             for e in n.data.misc['callers']:
                 fn = cfg.node(f)
                 p = e.v[0]
                 p.c.add_edge(cfg.link(p,fn))
                 p.c.add_edge(cfg.link(fn,e.v[1]))
                 p.c.remove_edge(e)
                 calls.append(p)
             n.data.misc['callers'] = calls
     return self.G
Пример #3
0
 def get_targets(self,node,parent):
     pc = self.prog.cpu.PC()
     alf = code.mapper.assume_no_aliasing
     code.mapper.assume_no_aliasing = not self.policy['frame-aliasing']
     # try fforward first:
     T = fforward.get_targets(self,node,parent)
     if len(T)>0:
         code.mapper.assume_no_aliasing = alf
         return T
     # create func object:
     f = code.func(node.c)
     m = f.backward(node)
     if m is None:
         logger.verbose('dead end at %s'%node.name)
     else:
         m = m.use((pc,f.address))
         # get pc @ node:
         mpc = m(pc)
         T = _target(mpc,node).expand()
         # if a target is defined here, it means that func cfg is not completed
         # so we can return now :
         if len(T)>0:
             code.mapper.assume_no_aliasing = alf
             return T
     # otherwise if func cfg is complete compute pc out of function callers:
     xpc = []
     # check if a leaf is still going to be explored
     for x in f.cfg.leaves():
         if x in (s.parent for s in self.spool):
             code.mapper.assume_no_aliasing = alf
             return xpc
     # f is now fully explored so we can "return" to callers:
     logger.info('lbackward: function %s done'%f)
     # cleanup spool:
     for t in self.spool:
         if t.parent.c is f.cfg: t.dirty=True
     # if needed compute the full map:
     if f.misc['partial']: m = f.makemap()
     f.map = m
     self.prog.codehelper(func=f)
     mpc = f.map(pc)
     roots = filter(lambda n: n.data.misc[code.tag.FUNC_START],f.cfg.sV)
     if len(roots)<=0:
         code.mapper.assume_no_aliasing = alf
         return xpc
     if len(roots)>1:
         logger.verbose('lbackward: multiple entries into function %s ?!'%f)
     nroot = roots[0]
     nroot.data.misc['func'] = f
     try:
         fsym = nroot.data.misc['callers'][0].data.misc['to'].ref
     except (IndexError,TypeError,AttributeError):
         fsym = 'f'
     f.name = "%s:%s"%(fsym,nroot.name)
     for cn in nroot.data.misc['callers']:
         cnpc = cn.data.map.use((pc,cn.data.address))(mpc)
         fn = cfg.node(f)
         e = cn.c.add_edge(cfg.link(cn,fn))
         xpc.extend(_target(cnpc,e.v[1]).expand())
     code.mapper.assume_no_aliasing = alf
     return xpc