Package vivisect :: Package symboliks :: Module effects
[hide private]
[frames] | no frames]

Source Code for Module vivisect.symboliks.effects

  1  import vivisect.symboliks.functions as vsym_funcs 
  2   
  3  from vivisect.symboliks.common import * 
  4  from vivisect.symboliks.constraints import * 
  5   
  6  EFFTYPE_DEBUG        = 0 
  7  EFFTYPE_SETVAR       = 1 
  8  EFFTYPE_READMEM      = 2 
  9  EFFTYPE_WRITEMEM     = 3 
 10  EFFTYPE_CALLFUNC     = 4 
 11  EFFTYPE_CONSTRAIN    = 5 
 12   
13 -class SymbolikEffect:
14 ''' 15 A single symbolik effect... 16 ''' 17 efftype = None 18
19 - def __init__(self, va):
20 self.va = va
21
22 - def __ne__(self, other):
23 return not self.__eq__(other)
24
25 - def __eq__(self, other):
26 raise Exception('%s must implement __eq__!' % (self.__class__.__name__,))
27
28 - def reduce(self, emu=None):
29 raise Exception('%s must implement reduce()!' % (self.__class__.__name__))
30
31 - def walkTree(self, cb, ctx=None, walktag=None):
32 raise Exception('%s must implement walkTree()!' % (self.__class__.__name__))
33
34 - def applyEffect(self, emu):
35 raise Exception('%s must implement applyEffect!' % (self.__class__.__name__,))
36
37 -class DebugEffect(SymbolikEffect):
38 ''' 39 DebugEffect is used to represent an NOP effect that we want logged. 40 Example: DebugEffect is created for instructions that are unsupported. 41 42 return DebugEffect(op.va, "%s Needs %s" % (self.__class__.__name__, repr(op))) 43 ''' 44 efftype = EFFTYPE_DEBUG 45
46 - def __init__(self, va, msg):
47 SymbolikEffect.__init__(self, va) 48 self.msg = msg
49
50 - def __repr__(self):
51 return 'DebugEffect(0x%.8x, %s)' % (self.va, self.msg)
52
53 - def __str__(self):
54 return '%s' % self.msg
55
56 - def __eq__(self, other):
57 if other == None: 58 return False 59 if self.__class__ != other.__class__: 60 return False 61 if not self.msg == other.msg: 62 return False 63 64 return True
65
66 - def walkTree(self, cb, ctx=None, walktag=None):
67 pass
68
69 - def reduce(self, emu=None):
70 pass
71
72 - def applyEffect(self, emu):
73 return self
74
75 -class SetVariable(SymbolikEffect):
76 77 efftype = EFFTYPE_SETVAR 78
79 - def __init__(self, va, varname, symobj):
80 SymbolikEffect.__init__(self, va) 81 self.varname = varname 82 self.symobj = symobj
83
84 - def __repr__(self):
85 return 'SetVariable(0x%.8x, %s, %s)' % (self.va, repr(self.varname), repr(self.symobj))
86
87 - def __str__(self):
88 return '%s = %s' % (self.varname, str(self.symobj))
89
90 - def __eq__(self, other):
91 if other == None: 92 return False 93 if self.__class__ != other.__class__: 94 return False 95 if not self.varname == other.varname: 96 return False 97 if not self.symobj == other.symobj: 98 return False 99 100 return True
101
102 - def walkTree(self, cb, ctx=None, walktag=None):
103 self.symobj.walkTree(cb, ctx=ctx, walktag=walktag) 104 self.symobj = cb(self.symobj, ctx)
105
106 - def reduce(self, emu=None):
107 self.symobj = self.symobj.reduce(emu=emu)
108
109 - def applyEffect(self, emu):
110 symobj = self.symobj.update(emu) 111 emu.setSymVariable(self.varname, symobj) 112 return SetVariable(self.va, self.varname, symobj)
113
114 -class ReadMemory(SymbolikEffect):
115 116 efftype = EFFTYPE_READMEM 117
118 - def __init__(self, va, symaddr, symsize):
119 SymbolikEffect.__init__(self, va) 120 self.symaddr = symaddr 121 self.symsize = symsize
122
123 - def __repr__(self):
124 t = (self.va, repr(self.symaddr), repr(self.symsize)) 125 return 'ReadMemory( 0x%.8x, %s, %s )' % t
126
127 - def __str__(self):
128 return '[ %s : %s ]' % (str(self.symaddr), str(self.symsize))
129
130 - def __eq__(self, other):
131 if other == None: 132 return False 133 if self.__class__ != other.__class__: 134 return False 135 if not self.symaddr == other.symaddr: 136 return False 137 if not self.symsize == other.symsize: 138 return False 139 140 return True
141
142 - def walkTree(self, cb, ctx=None, walktag=None):
143 self.symaddr.walkTree(cb, ctx=ctx, walktag=walktag) 144 self.symsize.walkTree(cb, ctx=ctx, walktag=walktag) 145 self.symaddr = cb(self.symaddr, ctx) 146 self.symsize = cb(self.symsize, ctx)
147
148 - def reduce(self, emu=None):
149 self.symaddr = self.symaddr.reduce(emu=emu) 150 self.symsize = self.symsize.reduce(emu=emu)
151
152 - def applyEffect(self, emu):
153 symaddr = self.symaddr.update(emu) 154 symsize = self.symsize.update(emu) 155 return ReadMemory(self.va, symaddr, symsize)
156
157 -class WriteMemory(SymbolikEffect):
158 159 efftype = EFFTYPE_WRITEMEM 160
161 - def __init__(self, va, symaddr, symsize, symval):
162 SymbolikEffect.__init__(self, va) 163 self.symval = symval 164 self.symaddr = symaddr 165 self.symsize = symsize
166
167 - def __repr__(self):
168 t = (self.va, repr(self.symaddr), repr(self.symsize), repr(self.symval)) 169 return 'WriteMemory( 0x%.8x, %s, %s, %s)' % t
170
171 - def __str__(self):
172 t = (str(self.symaddr), str(self.symsize), str(self.symval)) 173 return '[ %s : %s ] = %s' % t
174
175 - def __eq__(self, other):
176 if other == None: 177 return False 178 if self.__class__ != other.__class__: 179 return False 180 if not self.symval == other.symval: 181 return False 182 if not self.symaddr == other.symaddr: 183 return False 184 if not self.symsize == other.symsize: 185 return False 186 187 return True
188
189 - def walkTree(self, cb, ctx=None, walktag=None):
190 self.symval.walkTree(cb, ctx=ctx, walktag=walktag) 191 self.symaddr.walkTree(cb, ctx=ctx, walktag=walktag) 192 self.symsize.walkTree(cb, ctx=ctx, walktag=walktag) 193 194 self.symval = cb(self.symval, ctx) 195 self.symaddr = cb(self.symaddr, ctx) 196 self.symsize = cb(self.symsize, ctx)
197
198 - def reduce(self, emu=None):
199 self.symaddr = self.symaddr.reduce(emu=emu) 200 self.symsize = self.symsize.reduce(emu=emu) 201 self.symval = self.symval.reduce(emu=emu)
202
203 - def applyEffect(self, emu):
204 symaddr = self.symaddr.update(emu) 205 symsize = self.symsize.update(emu) 206 symval = self.symval.update(emu) 207 emu.writeSymMemory(symaddr, symval) 208 return WriteMemory(self.va, symaddr, symsize, symval)
209
210 -class CallFunction(SymbolikEffect):
211 ''' 212 This effect represents a procedural branch. They are recorded specially 213 because they may have effect on the overall system even though their 214 outputs are not stored. 215 216 NOTE: argsyms will be None while we haven't had a definition to use.. 217 ''' 218 219 efftype = EFFTYPE_CALLFUNC 220
221 - def __init__(self, va, funcsym, argsyms=None):
222 SymbolikEffect.__init__(self, va) 223 self.funcsym = funcsym 224 self.argsyms = argsyms
225
226 - def __repr__(self):
227 return 'CallFunction( 0x%.8x, %s, %s )' % (self.va, repr(self.funcsym), repr(self.argsyms))
228
229 - def __str__(self):
230 argstr = '?' 231 if self.argsyms != None: 232 argstr = ','.join( str(x) for x in self.argsyms ) 233 return '%s(%s)' % (self.funcsym, argstr)
234
235 - def __eq__(self, other):
236 if other == None: 237 return False 238 if self.__class__ != other.__class__: 239 return False 240 if not self.funcsym == other.funcsym: 241 return False 242 if not self.argsyms == other.argsyms: 243 return False 244 245 return True
246
247 - def walkTree(self, cb, ctx=None, walktag=None):
248 self.funcsym.walkTree(cb, ctx=ctx, walktag=walktag) 249 x = [ arg.walkTree(cb, ctx=ctx, walktag=walktag) for arg in self.argsyms ] 250 251 self.funcsym = cb(self.funcsym, ctx) 252 self.argsyms = [ cb(arg, ctx) for arg in self.argsyms ]
253
254 - def reduce(self, emu=None):
255 self.funcsym = self.funcsym.reduce(emu=emu) 256 if self.argsyms != None: 257 self.argsyms = [ x.reduce(emu=emu) for x in self.argsyms ]
258
259 - def applyEffect(self, emu):
260 funcsym = self.funcsym.update(emu) 261 262 # If we have argsyms, the function's work has been broken out 263 # already (probably by applying effects once already...) 264 if self.argsyms != None: 265 argsyms = [ x.update(emu) for x in self.argsyms ] 266 return CallFunction(self.va, funcsym, argsyms) 267 268 # Without argsyms, we are probably a call who is being applied to 269 # an emulator for the first time! Let the emulator handle it... 270 argsyms = emu.applyFunctionCall(funcsym) 271 return CallFunction(self.va, funcsym, argsyms)
272
273 -class ConstrainPath(SymbolikEffect):
274 275 efftype = EFFTYPE_CONSTRAIN 276
277 - def __init__(self, va, addrsym, cons):
278 SymbolikEffect.__init__(self, va) 279 self.addrsym = addrsym 280 self.cons = cons
281
282 - def walkTree(self, cb, ctx=None, walktag=None):
283 self.cons.walkTree(cb, ctx=ctx, walktag=walktag) 284 self.cons = cb(self.cons, ctx)
285
286 - def reduce(self, emu=None):
287 self.addrsym = self.addrsym.reduce(emu=emu) 288 self.cons = self.cons.reduce(emu=emu)
289
290 - def __repr__(self):
291 return 'ConstrainPath( 0x%.8x, %s, %s )' % (self.va, repr(self.addrsym), repr(self.cons))
292
293 - def __str__(self):
294 return 'if (%s)' % (str(self.cons),)
295
296 - def __eq__(self, other):
297 if other == None: 298 return False 299 if self.__class__ != other.__class__: 300 return False 301 if not self.addrsym == other.addrsym: 302 return False 303 if not self.cons == other.cons: 304 return False 305 306 return True
307
308 - def applyEffect(self, emu):
309 addrsym = self.addrsym.update(emu) 310 cons = self.cons.update(emu) 311 return ConstrainPath(self.va, addrsym, cons)
312