Skip to content

Commit

Permalink
Experiment with flattening graphs for textual edit distance based match
Browse files Browse the repository at this point in the history
Signed-off-by: Nir Izraeli <nirizr@gmail.com>
  • Loading branch information
nirizr committed Feb 17, 2017
1 parent 42815ff commit fb07f5c
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions idaplugin/rematch/collectors/flat_graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import idaapi

from .vector import Vector


class FlatGraphVector(Vector):
type = 'flatgraph_editdistance'
type_version = 0

def __init__(self, *args, **kwargs):
super(FlatGraphVector, self).__init__(*args, **kwargs)
self.flow_chart = idaapi.FlowChart(idaapi.get_func(self.offset))
self.visited = set()
self.items = list[self.flow_chart.size]

def _bb_size(self, bb):
if bb.endEA > bb.startEA:
return bb.endEA - bb.startEA

raise ValueError("while flattening graph, a basicblock that ends before "
"it starts encountered at {:x}".format(self.offset))

def _bb_value(self, bb):
# TODO: this should be something that's uncorellated with the order of
# basic blocks
return self._bb_size(bb)

def _append_bbs(self, *bbs):
for bb in bbs:
self.items.append(self._bb_value(bb))

def _find_head(self):
def is_head(bb):
return len(bb.preds()) == 0

heads = filter(is_head, self.flow_chart)
if len(heads) == 1:
return heads[0]

msg = ("flattening graphs with head count other than 1 is not supported, "
"got {} head-count for {:x}".format(len(heads), self.offset))
raise ValueError(msg)

def _sort_siblings(self, siblings):
return sorted(siblings, key=self._bb_size)

def _recurse_bb(self, bb):
if bb in self.visited:
return []

self.visited.add(bb)
siblings = self._sort_siblings(bb.succs())
self._append_bbs(*siblings)

for sibling in siblings:
self._recurse_siblings(sibling)

def _data(self):
head = self._find_head()
self._recurse_bb(head)
return self.items

0 comments on commit fb07f5c

Please sign in to comment.