Package bap :: Module bir
[hide private]
[frames] | no frames]

Source Code for Module bap.bir

  1  #!/usr/bin/env python 
  2   
  3  """BIR - BAP Intermediate Representation""" 
  4   
  5  from collections import Sequence,Mapping 
  6  from .adt import * 
  7  from .bil import * 
8 9 10 -class Project(ADT) :
11 """A collection of data associated with a disassembled program""" 12 @property
13 - def attrs(self) :
14 """A dictionary of attributes that are global to a project. 15 16 Example: 17 >>> file = proj.attrs['filename'] 18 """ 19 return self.arg[0]
20 21 @property
22 - def sections(self) :
23 """code and data sections of a file. 24 25 Often a binary is split into several named sections. This is 26 the mapping from names (that varies by particular, underlying 27 file format, and data, that represents the section) 28 29 Example: 30 31 >>> code = proj.sections['.text'] 32 """ 33 return self.arg[1]
34 35 @property
36 - def memmap(self) :
37 """a mapping from memory regions to arbitrary attributes. 38 39 Some facts may be discovered about a particular memory region 40 and attributed to it. 41 """ 42 return self.arg[2]
43 44 @property
45 - def program(self) :
46 """a program in BAP Intermediate Representation (BIR)""" 47 return self.arg[3]
48
49 -class Term(ADT) :
50 """Term(id,attrs,...) a program term. 51 52 Every term has a dictionary of attributes, associated with it, and 53 a unique term identifier. 54 """ 55 @property
56 - def id(self) :
57 "term.id() -> Tid(id,name)" 58 return self.arg[0]
59 60 @property
61 - def attrs(self) : return self.arg[1]
62
63 -class Program(Term) :
64 """Program(id,attrs,Subs(s1,s2,..,sN)) 65 A program is a term that contains a set of subroutines.""" 66 67 @property
68 - def subs(self) : return self.arg[2]
69
70 -class Sub(Term) :
71 """Sub(id,Attrs(...),name,Args(...),Blks(...)) 72 A subroutine has a sequence of arguments and basic blocks 73 """ 74 75 @property
76 - def name(self) :
77 "subroutine name" 78 return self.arg[2]
79 80 @property
81 - def args(self) :
82 "a list of subroutine arguments" 83 return self.arg[3]
84 85 @property
86 - def blks(self) :
87 "subroutine basic blocks, the first is the entry" 88 return self.arg[4]
89
90 -class Arg(Term) :
91 """Arg(id,attrs,lhs,rhs,intent=None) - a subroutine argument""" 92 93 @property
94 - def var(self) :
95 """a variable associated with the argument, e.g., 96 97 >>> main = proj.subs.find('main') 98 >>> main.args[0].var.name 99 'main_argc' 100 101 """ 102 return self.arg[2]
103 104 @property
105 - def exp(self) :
106 "a BIL expression associated with the argument" 107 return self.arg[3]
108 109 @property
110 - def intent(self) :
111 "an instance of Intent class or None if unknown" 112 None if len(self.arg) == 4 else self.arg[4]
113
114 -class Blk(Term) :
115 """Blk(id,attrs,(p1,..,pL),(d1,..,dM),(j1,..,jN)) 116 A basic block is a sequence of phi-nodes, defintions and jumps. 117 """ 118 @property
119 - def phis(self) :
120 "phi-nodes" 121 return self.arg[2]
122 @property
123 - def defs(self) :
124 "definitions" 125 return self.arg[3]
126 @property
127 - def jmps(self) :
128 "jumps" 129 return self.arg[4]
130
131 -class Def(Term) :
132 "Def(id,attrs,Var(lhs),Exp(rhs)) assign rhs to lhs" 133 @property
134 - def lhs(self) :
135 "an assigned variable" 136 return self.arg[2]
137 @property
138 - def rhs(self) :
139 "value expression" 140 return self.arg[3]
141
142 143 -class Jmp(Term) :
144 "Jmp(id,attrs,cond,target) base class for jump terms" 145 @property
146 - def cond(self) :
147 "guard condition" 148 return self.arg[2]
149 150 @property
151 - def target(self) :
152 "jump target" 153 return self.arg[3]
154
155 -class Goto(Jmp) :
156 "Goto(id,attrs,cond,target) control flow local to a subroutine" 157 pass
158
159 -class Call(Jmp) :
160 """Call(id,attrs,(calee,returns)) 161 a transfer of control flow to another subroutine""" 162 163 @property
164 - def calee(self) :
165 "call destination" 166 return self.target[0]
167 168 @property
169 - def returns(self) :
170 "a basic block to which a call will return if ever" 171 return self.target[1] if len(self.target[1]) == 2 else None
172
173 -class Ret(Jmp) :
174 "Ret(id,attrs,label) - return from a call" 175 pass
176
177 -class Exn(Jmp) :
178 "Exn(id,attrs,(number,next)) - CPU exception" 179 @property
180 - def number(self) :
181 "exception number" 182 return self.target[0]
183 184 @property
185 - def next(self) :
186 """next instruction to be executed after the 187 exception handler finishes""" 188 return self.target[1]
189
190 -class Label(ADT) : pass
191
192 -class Direct(Label) :
193 "Direct(tid) a statically known target of a jump" 194 pass
195
196 -class Indirect(Label) :
197 "Indirect(exp) indirect jump that is computed at runtime" 198 pass
199
200 -class Intent(ADT) :
201 "argument intention" 202 pass
203 -class In(Intent) :
204 "input argument" 205 pass
206 -class Out(Intent) :
207 "output argument" 208 pass
209 -class Both(Intent) :
210 "input/output argument" 211 pass
212
213 -class Phi(Term) :
214 """Phi(id,attrs,lhs,Values(b1,..,bM))) a term whose value 215 depends on chosen control flow path""" 216 @property
217 - def lhs(self) :
218 "defined variable" 219 return self.arg[2]
220 221 @property
222 - def value(self) :
223 """a mapping from the tid of the preceeding block to 224 an expression that defines a value of phi-node""" 225 return self.arg[3]
226
227 -class Def(Term) :
228 "Def(id,attrs,lhs,rhs) - assignment" 229 @property
230 - def lhs(self) :
231 "program variable to be assigned" 232 return self.arg[2]
233 234 @property
235 - def rhs(self) :
236 "value expression" 237 return self.arg[3]
238
239 240 -class Attrs(Map) :
241 "A mapping from attribute names to attribute values" 242 pass
243
244 -class Attr(ADT) :
245 """Attribute is a pair of attribute name and value, 246 both represented with str""" 247 pass
248
249 -class Values(Map) :
250 """A set of possible values, taken by a phi-node. 251 252 It is a mapping from the tid of a preceeding block, 253 to an expression that denotes a value. 254 """ 255 pass
256
257 -class Tid(ADT) :
258 """Tid(id,name=None) term unique identifier. 259 260 name is an optional human readable identifier, that 261 doesn't affect the identity. 262 263 """ 264
265 - def __init__(self,*args):
266 super(Tid,self).__init__(*args) 267 noname = not isinstance(self.arg, tuple) 268 self.number = self.arg if noname else self.arg[0] 269 self.name = None if noname else self.arg[1]
270
271 - def __cmp__(self, other):
272 return cmp(self.number, other.number)
273
274 - def __hash__(self):
275 return hash(self.number)
276
277 -class Subs(Seq) :
278 "a set of subroutines" 279 pass
280
281 -class Args(Seq) :
282 "sequence of arguments" 283 pass
284 -class Blks(Seq) :
285 "sequence of basic blocks" 286 pass
287 -class Phis(Seq) :
288 "sequence of phi-nodes" 289 pass
290 -class Defs(Seq) :
291 "sequence of definitions" 292 pass
293 -class Jmps(Seq) :
294 "sequence of jump terms" 295 pass
296
297 -class Memmap(Seq) :
298 "sequence of memory annotations " 299 pass
300
301 -class Region(ADT) :
302 "Region(beg,end) a pair of addresses, that denote a memory region" 303 @property
304 - def beg(self) : return self.arg[0]
305 306 @property
307 - def end(self) : return self.arg[1]
308
309 -class Section(ADT,Sequence) :
310 """A contiguous piece of memory in a process image""" 311 312 @property
313 - def name(self) :
314 "name associated with the section" 315 return self.arg[0]
316 317 @property
318 - def beg(self) :
319 "starting address" 320 return self.arg[1]
321 322 @property
323 - def data(self) :
324 "an array of bytes" 325 return self.arg[2]
326 327 @property
328 - def end(self) :
329 "an address of last byte" 330 return self.beg + len(self.data)
331
332 - def __getitem__(self,i) :
333 return self.data.__getitem__(i)
334
335 - def __len__(self) :
336 return self.data.__len__()
337
338 -class Sections(ADT,Mapping) :
339 " a mapping from names to sections"
340 - def __init__(self, *args):
341 super(Sections, self).__init__(args) 342 self.elements = dict((x.name,x) for x in args[0])
343
344 - def __getitem__(self,i) :
345 return self.elements.__getitem__(i)
346
347 - def __len__(self) :
348 return self.elements.__len__()
349
350 - def __iter__(self) :
351 return self.elements.__iter__()
352
353 -class Annotation(ADT) :
354 """Annotation(Region(beg,end), Attr(name,value)) 355 356 Each annotation denotes an association between a memory region and 357 some arbitrary property, denoted with an attribute. 358 """ 359 pass
360
361 -def parse_addr(str):
362 return int(str.split(':')[0],16)
363
364 -def loads(s):
365 "loads bir object from string" 366 return eval(s)
367