Package Peach :: Package Mutators :: Module blob
[hide private]

Source Code for Module Peach.Mutators.blob

  1   
  2  ''' 
  3  Mutators that operate on blob types. 
  4   
  5  @author: Michael Eddington 
  6  @version: $Id$ 
  7  ''' 
  8   
  9  # 
 10  # Copyright (c) 2008 Michael Eddington 
 11  # 
 12  # Permission is hereby granted, free of charge, to any person obtaining a copy  
 13  # of this software and associated documentation files (the "Software"), to deal 
 14  # in the Software without restriction, including without limitation the rights  
 15  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
 16  # copies of the Software, and to permit persons to whom the Software is  
 17  # furnished to do so, subject to the following conditions: 
 18  # 
 19  # The above copyright notice and this permission notice shall be included in     
 20  # all copies or substantial portions of the Software. 
 21  # 
 22  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
 23  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
 24  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
 25  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
 26  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 27  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
 28  # SOFTWARE. 
 29  # 
 30   
 31  # Authors: 
 32  #   Michael Eddington (mike@phed.org) 
 33   
 34  # $Id$ 
 35   
 36  import sys, os, time 
 37  from Peach.Generators.block import * 
 38  from Peach.Generators.data import * 
 39  from Peach.Generators.dictionary import * 
 40  from Peach.Generators.flipper import * 
 41  from Peach.Generators.static import Static, _StaticFromTemplate, _StaticCurrentValueFromDom 
 42  from Peach.Transformers.encode import WideChar 
 43  from Peach import Transformers 
 44  from Peach.Generators.data import * 
 45  from Peach.Generators.flipper import * 
 46  from Peach.Generators.static import _StaticFromTemplate 
 47  from Peach.mutator import * 
 48  from Peach.group import * 
 49  from Peach.Engine.common import * 
 50   
51 -class DWORDSliderMutator(Mutator):
52 ''' 53 Slides a DWORD through the blob. 54 55 @author Chris Clark 56 ''' 57
58 - def __init__(self, peach):
59 Mutator.__init__(self) 60 61 self.name = "DWORDSliderMutator" 62 self._peach = peach 63 64 self._stateMasterCount = -1 65 self._masterGroup = GroupSequence() 66 self._masterCount = 0 67 self._countThread = None 68 self._countGroup = GroupSequence() 69 self._actions = [] 70 71 # All active groups 72 self._activeGroups = [] 73 74 # Hashtable, key is element, value is [group, generator] 75 self._generatorMap = {} 76 self._countGeneratorMap = {}
77
78 - def isFinite(self):
79 ''' 80 Some mutators could contine forever, this 81 should indicate. 82 ''' 83 return True
84
85 - def reset(self):
86 ''' 87 Reset mutator 88 ''' 89 90 self._masterGroup = GroupSequence() 91 self._activeGroups = [] 92 self._generatorMap = {} 93 self._masterCount = 0 94 self._actions = []
95
96 - def next(self):
97 ''' 98 Goto next mutation. When this is called 99 the state machine is updated as needed. 100 ''' 101 102 try: 103 # Check if we set our state and need 104 # to skip ahead. We need todo this in 105 # next() to assure we have all our action 106 # templates added into our masterGroup 107 if self._stateMasterCount > -1: 108 for cnt in xrange(self._masterCount, self._stateMasterCount): 109 self._masterGroup.next() 110 self._masterCount += 1 111 self._stateMasterCount = -1 112 else: 113 self._masterGroup.next() 114 self._masterCount += 1 115 116 except GroupCompleted: 117 raise MutatorCompleted()
118
119 - def getState(self):
120 ''' 121 Return a binary string that contains 122 any information about current state of 123 Mutator. This state information should be 124 enough to let the same mutator "restart" 125 and continue when setState() is called. 126 ''' 127 128 # Ensure a minor overlap of testing 129 str(self._masterCount - 2) 130 try: 131 self.next() 132 except: 133 pass
134
135 - def setState(self, state):
136 ''' 137 Set the state of this object. Should put us 138 back in the same place as when we said 139 "getState()". 140 ''' 141 if state == None: 142 return 143 144 self._stateMasterCount = int(state)
145
146 - def getCount(self):
147 if self._countThread != None and self._countThread.hasCountEvent.isSet(): 148 self._count = self._countThread.count 149 self._countThread = None 150 self._countGroup = None 151 self._countGeneratorMap = None 152 153 return self._count
154
155 - def calculateCount(self):
156 157 count = 0 158 try: 159 while True: 160 count += 1 161 self._countGroup.next() 162 163 except GroupCompleted: 164 pass 165 166 return count
167
168 - def _getStringElements(self, node):
169 170 elements = [] 171 172 for e in node._children: 173 if e.elementType == 'blob' and not e.isStatic: 174 elements.append(e) 175 for child in e: 176 if isinstance(child, Hint) and child.name == 'DWORDSliderMutator' and child.value == 'off': 177 elements.remove(e) 178 break 179 180 if e.hasChildren: 181 for ee in self._getStringElements(e): 182 elements.append(ee) 183 184 return elements
185 186 ##################################################### 187 # Callbacks when Action needs a value 188
189 - def getActionValue(self, action):
190 191 if action not in self._actions: 192 193 # Walk data tree and locate each string type. 194 stringElements = self._getStringElements(action.template) 195 self._generatorMap[action] = {} 196 self._countGeneratorMap[action] = {} 197 198 for e in stringElements: 199 group = Group() 200 gen = SequentialDWORDSlider(None, e.getValue()) 201 gen = WithDefault(group, _StaticFromTemplate(action, e), gen) 202 self._masterGroup.append(group) 203 self._generatorMap[action][e.getFullnameInDataModel()] = gen 204 205 group = Group() 206 gen = SequentialDWORDSlider(None, e.getValue()) 207 gen = WithDefault(group, _StaticFromTemplate(action, e), gen) 208 self._countGroup.append(group) 209 self._countGeneratorMap[action][e.getFullnameInDataModel()] = gen 210 211 self._actions.append(action) 212 213 # Set values 214 for key in self._generatorMap[action].keys(): 215 self._getElementByName(action.template, key).setValue(self._generatorMap[action][key].getValue()) 216 217 return action.template.getValue()
218
219 - def getActionParamValue(self, action):
220 return self.getActionValue(action)
221
222 - def getActionChangeStateValue(self, action, value):
223 return value
224 225 226 ##################################################### 227 # Event callbacks for state machine 228
229 - def onStateStart(self, state):
230 pass
231
232 - def onStateComplete(self, state):
233 pass
234
235 - def onActionStart(self, action):
236 pass
237
238 - def onActionComplete(self, action):
239 pass
240
241 - def onStateMachineStart(self, stateMachine):
242 pass
243
244 - def onStateMachineComplete(self, stateMachine):
245 246 # Lets calc our count if we haven't already 247 if self._count == -1 and self._countThread == None: 248 self._countThread = MutatorCountCalculator(self) 249 self._countThread.start() 250 251 elif self._countThread != None: 252 if self._countThread.hasCountEvent.isSet(): 253 self._count = self._countThread.count 254 self._countThread = None 255 self._countGroup = None 256 self._countGeneratorMap = None
257 258
259 -class BitFlipperMutator(Mutator):
260 ''' 261 Flip a % of total bits in blob. Default % is 20. 262 ''' 263
264 - def __init__(self, peach):
265 Mutator.__init__(self) 266 267 self.name = "BitFlipperMutator" 268 self._peach = peach 269 270 self._stateMasterCount = -1 271 self._masterGroup = GroupSequence() 272 self._masterCount = 0 273 self._countThread = None 274 self._countGroup = GroupSequence() 275 self._actions = [] 276 277 # All active groups 278 self._activeGroups = [] 279 280 # Hashtable, key is element, value is [group, generator] 281 self._generatorMap = {} 282 self._countGeneratorMap = {}
283
284 - def isFinite(self):
285 ''' 286 Some mutators could contine forever, this 287 should indicate. 288 ''' 289 return True
290
291 - def reset(self):
292 ''' 293 Reset mutator 294 ''' 295 296 self._masterGroup = GroupSequence() 297 self._activeGroups = [] 298 self._generatorMap = {} 299 self._masterCount = 0 300 self._actions = []
301
302 - def next(self):
303 ''' 304 Goto next mutation. When this is called 305 the state machine is updated as needed. 306 ''' 307 308 try: 309 # Check if we set our state and need 310 # to skip ahead. We need todo this in 311 # next() to assure we have all our action 312 # templates added into our masterGroup 313 if self._stateMasterCount > -1: 314 for cnt in xrange(self._stateMasterCount): 315 self._masterGroup.next() 316 self._masterCount += 1 317 self._stateMasterCount = -1 318 else: 319 self._masterGroup.next() 320 self._masterCount += 1 321 322 except GroupCompleted: 323 raise MutatorCompleted()
324
325 - def getState(self):
326 ''' 327 Return a binary string that contains 328 any information about current state of 329 Mutator. This state information should be 330 enough to let the same mutator "restart" 331 and continue when setState() is called. 332 ''' 333 334 # Ensure a minor overlap of testing 335 return str(self._masterCount - 2)
336
337 - def setState(self, state):
338 ''' 339 Set the state of this object. Should put us 340 back in the same place as when we said 341 "getState()". 342 ''' 343 self.reset() 344 self._stateMasterCount = int(state)
345
346 - def getCount(self):
347 if self._countThread != None and self._countThread.hasCountEvent.isSet(): 348 self._count = self._countThread.count 349 self._countThread = None 350 self._countGroup = None 351 self._countGeneratorMap = None 352 353 return self._count
354
355 - def calculateCount(self):
356 357 count = 0 358 try: 359 while True: 360 count += 1 361 self._countGroup.next() 362 363 except GroupCompleted: 364 pass 365 366 return count
367
368 - def _getStringElements(self, node):
369 370 elements = [] 371 372 for e in node._children: 373 if e.elementType == 'blob' and not e.isStatic: 374 elements.append(e) 375 376 if e.hasChildren: 377 for ee in self._getStringElements(e): 378 elements.append(ee) 379 380 return elements
381
382 - def _getN(self, node):
383 ''' 384 Gets N by checking node for hint, or returnign default 385 ''' 386 387 n = None 388 389 for c in node._children: 390 if isinstance(c, Hint) and c.name == 'BitFlipperMutator-N': 391 try: 392 n = int(c.value) 393 except: 394 raise PeachException("Expected numerical value for Hint named [%s]" % c.name) 395 396 return n
397 398 ##################################################### 399 # Callbacks when Action needs a value 400
401 - def getActionValue(self, action):
402 403 if action not in self._actions: 404 405 # Walk data tree and locate each string type. 406 stringElements = self._getStringElements(action.template) 407 self._generatorMap[action] = {} 408 self._countGeneratorMap[action] = {} 409 410 for e in stringElements: 411 group = Group() 412 413 if self._getN(e) != None: 414 gen = PartialFlipper(None, e.getValue(),self._getN(e)) 415 else: 416 gen = PartialFlipper(None, e.getValue()) 417 418 gen = WithDefault(group, _StaticFromTemplate(action, e), gen) 419 self._masterGroup.append(group) 420 self._generatorMap[action][e.getFullnameInDataModel()] = gen 421 422 423 # Counter 424 425 group = Group() 426 427 if self._getN(e) != None: 428 gen = PartialFlipper(None, e.getValue(),self._getN(e)) 429 else: 430 gen = PartialFlipper(None, e.getValue()) 431 432 gen = WithDefault(group, _StaticFromTemplate(action, e), gen) 433 self._countGroup.append(group) 434 self._countGeneratorMap[action][e.getFullnameInDataModel()] = gen 435 436 self._actions.append(action) 437 438 # Set values 439 for key in self._generatorMap[action].keys(): 440 self._getElementByName(action.template, key).setValue(self._generatorMap[action][key].getValue()) 441 442 return action.template.getValue()
443
444 - def getActionParamValue(self, action):
445 return self.getActionValue(action)
446
447 - def getActionChangeStateValue(self, action, value):
448 return value
449 450 451 ##################################################### 452 # Event callbacks for state machine 453
454 - def onStateStart(self, state):
455 pass
456
457 - def onStateComplete(self, state):
458 pass
459
460 - def onActionStart(self, action):
461 pass
462
463 - def onActionComplete(self, action):
464 pass
465
466 - def onStateMachineStart(self, stateMachine):
467 pass
468
469 - def onStateMachineComplete(self, stateMachine):
470 471 # Lets calc our count if we haven't already 472 if self._count == -1 and self._countThread == None: 473 self._countThread = MutatorCountCalculator(self) 474 self._countThread.start() 475 476 elif self._countThread != None: 477 if self._countThread.hasCountEvent.isSet(): 478 self._count = self._countThread.count 479 self._countThread = None 480 self._countGroup = None 481 self._countGeneratorMap = None
482 483 484 # end 485