| Home | Trees | Indices | Help |
|
|---|
|
|
1 2 ''' 3 Mutator base classes and interfaces. 4 5 A Mutator implements a method of mutating data/state for a Peach 2 6 fuzzer. For example a mutator might change the state flow defined 7 by a Peach fuzzer. Another mutator might mutate data based on 8 known relationships. Another mutator might perform numerical type 9 tests against fields. 10 11 @author: Michael Eddington 12 @version: $Id: default.py 1131 2008-08-16 05:55:11Z meddingt $ 13 ''' 14 15 # 16 # Copyright (c) 2008 Michael Eddington 17 # 18 # Permission is hereby granted, free of charge, to any person obtaining a copy 19 # of this software and associated documentation files (the "Software"), to deal 20 # in the Software without restriction, including without limitation the rights 21 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 # copies of the Software, and to permit persons to whom the Software is 23 # furnished to do so, subject to the following conditions: 24 # 25 # The above copyright notice and this permission notice shall be included in 26 # all copies or substantial portions of the Software. 27 # 28 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 # SOFTWARE. 35 # 36 37 # Authors: 38 # Michael Eddington (mike@phed.org) 39 40 # $Id: default.py 1131 2008-08-16 05:55:11Z meddingt $ 41 42 import sys, os, time 43 #from parser import * 44 from Peach.Generators.block import * 45 from Peach.Generators.data import * 46 from Peach.Generators.dictionary import * 47 from Peach.Generators.flipper import * 48 from Peach.Generators.static import Static, _StaticFromTemplate, _StaticCurrentValueFromDom 49 from Peach.Transformers.encode import WideChar 50 from Peach import Transformers 51 from Peach.Generators.block import * 52 from Peach.Generators.data import * 53 from Peach.Generators.dictionary import * 54 from Peach.Generators.flipper import * 55 from Peach.Generators.static import Static, _StaticFromTemplate 56 from Peach.Transformers.encode import WideChar 57 from Peach.mutator import * 58 from Peach.group import * 59 from Peach.Engine.common import * 60 6163 ''' 64 Does not make any changes to data tree. This is 65 usually the first mutator applied to a fuzzing run 66 so the generated data can be verified. 67 ''' 68 72 79121 122 123 124 125 ###class GeneratorMutator(Mutator): 126 ### ''' 127 ### This is the default Peach 2 mutator. This 128 ### mutator uses the Peach 1 Generators to build 129 ### a standard complexity fuzzer that performs 130 ### type based fuzzing and basic relation based 131 ### fuzzing for size and count relations. 132 ### 133 ### This mutator is *not* state aware. 134 ### ''' 135 ### 136 ### def __init__(self, peach): 137 ### Mutator.__init__(self) 138 ### 139 ### self.name = "GeneratorMutator" 140 ### self._peach = peach 141 ### 142 ### self._stateMasterCount = -1 143 ### self._masterGroup = GroupSequence() 144 ### self._masterCount = 0 145 ### self._countThread = None 146 ### self._countGroup = GroupSequence() 147 ### 148 ### # All active groups 149 ### self._activeGroups = [] 150 ### 151 ### # Hashtable, key is template, value is [group, generator] 152 ### self._generatorMap = {} 153 ### self._countGeneratorMap = {} 154 ### 155 ### def isFinite(self): 156 ### ''' 157 ### Some mutators could contine forever, this 158 ### should indicate. 159 ### ''' 160 ### return True 161 ### 162 ### def reset(self): 163 ### ''' 164 ### Reset mutator 165 ### ''' 166 ### 167 ### self._masterGroup = GroupSequence() 168 ### self._activeGroups = [] 169 ### self._generatorMap = {} 170 ### self._masterCount = 0 171 ### 172 ### def next(self): 173 ### ''' 174 ### Goto next mutation. When this is called 175 ### the state machine is updated as needed. 176 ### ''' 177 ### 178 ### try: 179 ### # Check if we set our state and need 180 ### # to skip ahead. We need todo this in 181 ### # next() to assure we have all our action 182 ### # templates added into our masterGroup 183 ### if self._stateMasterCount > -1: 184 ### for cnt in xrange(self._stateMasterCount): 185 ### self._masterGroup.next() 186 ### self._masterCount += 1 187 ### self._stateMasterCount = -1 188 ### else: 189 ### self._masterGroup.next() 190 ### self._masterCount += 1 191 ### 192 ### except GroupCompleted: 193 ### raise MutatorCompleted() 194 ### 195 ### def getState(self): 196 ### ''' 197 ### Return a binary string that contains 198 ### any information about current state of 199 ### Mutator. This state information should be 200 ### enough to let the same mutator "restart" 201 ### and continue when setState() is called. 202 ### ''' 203 ### 204 ### # Ensure a minor overlap of testing 205 ### return str(self._masterCount - 2) 206 ### 207 ### def setState(self, state): 208 ### ''' 209 ### Set the state of this object. Should put us 210 ### back in the same place as when we said 211 ### "getState()". 212 ### ''' 213 ### self.reset() 214 ### self._stateMasterCount = int(state) 215 ### 216 ### def calculateCount(self): 217 ### 218 ### count = 0 219 ### try: 220 ### while True: 221 ### count += 1 222 ### self._countGroup.next() 223 ### 224 ### except GroupCompleted: 225 ### pass 226 ### 227 ### return count 228 ### 229 ### ##################################################### 230 ### # Callbacks when Action needs a value 231 ### 232 ### def getActionValue(self, action): 233 ### 234 ### if not self._generatorMap.has_key(action.template): 235 ### build = _BuildPeach(self._peach) 236 ### (group, gen, template) = build.getDefaultPeach(action.template, action.data) 237 ### self._generatorMap[action.template] = gen 238 ### self._activeGroups.append(group) 239 ### self._masterGroup.append(group) 240 ### 241 ### # For counting 242 ### (groupCnt, genCnt, templateCnt) = build.getDefaultPeach(action.template, action.data) 243 ### self._countGeneratorMap[action.template] = genCnt 244 ### self._countGroup.append(groupCnt) 245 ### 246 ### return self._generatorMap[action.template].getValue() 247 ### 248 ### def getActionParamValue(self, param): 249 ### 250 ### if not self._generatorMap.has_key(param.template): 251 ### build = _BuildPeach(self._peach) 252 ### (group, gen, template) = build.getDefaultPeach(param.template, param.data) 253 ### self._generatorMap[param.template] = gen 254 ### self._activeGroups.append(group) 255 ### self._masterGroup.append(group) 256 ### 257 ### # For counting 258 ### (groupCnt, genCnt, templateCnt) = build.getDefaultPeach(param.template, param.data) 259 ### self._countGeneratorMap[oaram.template] = genCnt 260 ### self._countGroup.append(groupCnt) 261 ### 262 ### return self._generatorMap[param.template].getValue() 263 ### 264 ### def getActionChangeStateValue(self, action, value): 265 ### return value 266 ### 267 ### ##################################################### 268 ### # Event callbacks for state machine 269 ### 270 ### def onStateStart(self, state): 271 ### pass 272 ### 273 ### def onStateComplete(self, state): 274 ### pass 275 ### 276 ### def onActionStart(self, action): 277 ### pass 278 ### 279 ### def onActionComplete(self, action): 280 ### pass 281 ### 282 ### def onStateMachineStart(self, stateMachine): 283 ### pass 284 ### 285 ### def onStateMachineComplete(self, stateMachine): 286 ### 287 ### # Lets calc our count if we haven't already 288 ### if self._count == -1 and self._countThread == None: 289 ### self._countThread = MutatorCountCalculator(self) 290 ### self._countThread.start() 291 ### 292 ### elif self._countThread != None: 293 ### if self._countThread.hasCountEvent.isSet(): 294 ### self._count = self._countThread.count 295 ### self._countThread = None 296 ### self._countGroup = None 297 ### self._countGeneratorMap = None 298 ### 299 ###def PeachStr(s): 300 ### ''' 301 ### Our implementation of str() which does not 302 ### convert None to 'None'. 303 ### ''' 304 ### 305 ### if s == None: 306 ### return None 307 ### 308 ### return str(s) 309 ### 310 ###class _BuildPeach: 311 ### ''' 312 ### Logic to build a tree of generators around a Template. This used 313 ### to be the base fuzzer logic for Peach 2.0 release and was in 314 ### Engine\build.py. No longer :) 315 ### ''' 316 ### 317 ### def __init__(self, peachXml): 318 ### self.context = self.peachXml = peachXml 319 ### self._relationSizeofNeedResolving = [] 320 ### self._relationCountofNeedResolving = [] 321 ### self._performAllImports() 322 ### 323 ### def GetClassesInModule(self, module): 324 ### ''' 325 ### Return array of class names in module 326 ### ''' 327 ### 328 ### classes = [] 329 ### for item in dir(module): 330 ### i = getattr(module, item) 331 ### if type(i) == types.ClassType and item[0] != '_': 332 ### classes.append(item) 333 ### 334 ### return classes 335 ### 336 ### def getDefaultPeachByName(self, templateName, dataName = None): 337 ### group = GroupSequence() 338 ### template = self._GetTemplateByName(templateName) 339 ### template = template.copy(None) 340 ### 341 ### return self.getDefaultPeach(template, dataName) 342 ### 343 ### def getDefaultPeach(self, template, dataName = None): 344 ### ''' 345 ### Return a master generator and group 346 ### ''' 347 ### 348 ### group = GroupSequence() 349 ### 350 ### #DomPrint(0, template) 351 ### 352 ### if dataName != None: 353 ### data = self._GetDataByName(dataName) 354 ### template.setDefaults(data) 355 ### 356 ### self._ResetTemplate(template) 357 ### gen = self._getDefaultGenerator(template, group) 358 ### template.generator = gen 359 ### 360 ### # Resolve any sizeof relations waiting around 361 ### for relation in self._relationSizeofNeedResolving: 362 ### 363 ### if relation == None: 364 ### continue 365 ### 366 ### if relation.of_ref != None: 367 ### if relation.of_ref.generator == None: 368 ### raise Exception("Found a relation I'm unable to resolve") 369 ### 370 ### relation.blockSize.setBlock(relation.of_ref.generator) 371 ### 372 ### else: 373 ### if relation.from_ref.generator == None: 374 ### raise Exception("Found a relation I'm unable to resolve") 375 ### 376 ### relation.blockMulti.setSize(relation.from_ref.generator) 377 ### 378 ### # Resolve any countof relations waiting around 379 ### for relation in self._relationCountofNeedResolving: 380 ### #print "Resolving count of relation..." 381 ### if relation.of_ref != None: 382 ### if relation.of_ref.generator == None: 383 ### raise Exception("Found a relation I'm unable to resolve") 384 ### 385 ### relation.blockCount.setBlock(relation.of_ref.generator) 386 ### else: 387 ### if relation.from_ref.generator == None: 388 ### raise Exception("Found a relation I'm unable to resolve") 389 ### 390 ### relation.blockMulti.setGenOccurs(relation.from_ref.generator) 391 ### 392 ### return (group, gen, template) 393 ### 394 ### def _HasSizeofRelation(self, node): 395 ### for relation in node.relations: 396 ### if relation.type == 'size': 397 ### return True 398 ### 399 ### return False 400 ### def _GetSizeofRelation(self, node): 401 ### for relation in node.relations: 402 ### if relation.type == 'size': 403 ### return relation 404 ### 405 ### return None 406 ### 407 ### def _HasCountofRelation(self, node): 408 ### for relation in node.relations: 409 ### if relation.type == 'count': 410 ### return True 411 ### 412 ### return False 413 ### def _GetCountofRelation(self, node): 414 ### for relation in node.relations: 415 ### if relation.type == 'count': 416 ### return relation 417 ### 418 ### return None 419 ### 420 ### def _ResetTemplate(self, node): 421 ### ''' 422 ### Set the .generator values in template tree to None 423 ### ''' 424 ### 425 ### if node.elementType != 'generator': 426 ### node.generator = None 427 ### 428 ### try: 429 ### for child in node: 430 ### self._ResetTemplate(child) 431 ### except: 432 ### # we arn't always a sequence :) 433 ### pass 434 ### 435 ### def _performAllImports(self): 436 ### ''' 437 ### Find all Import objects and insert them into the current 438 ### namespace. 439 ### ''' 440 ### 441 ### for obj in self.context: 442 ### if hasattr(obj, 'elementType') and obj.elementType == 'import': 443 ### self._performImport(obj) 444 ### 445 ### def _performImport(self, importObj): 446 ### ''' 447 ### Import the specified import object into the current namespace. 448 ### ''' 449 ### 450 ### importStr = importObj.importStr 451 ### 452 ### if importObj.fromStr != None: 453 ### fromStr = importObj.fromStr 454 ### 455 ### if importStr == "*": 456 ### module = __import__(PeachStr(fromStr), globals(), locals(), [ PeachStr(importStr) ], -1) 457 ### 458 ### try: 459 ### # If we are a module with other modules in us then we have an __all__ 460 ### for item in module.__all__: 461 ### globals()["PeachXml_"+item] = getattr(module, item) 462 ### 463 ### except: 464 ### # Else we just have some classes in us with no __all__ 465 ### for item in self.GetClassesInModule(module): 466 ### globals()["PeachXml_"+item] = getattr(module, item) 467 ### 468 ### else: 469 ### module = __import__(PeachStr(fromStr), globals(), locals(), [ PeachStr(importStr) ], -1) 470 ### for item in importStr.split(','): 471 ### item = item.strip() 472 ### globals()["PeachXml_"+item] = getattr(module, item) 473 ### 474 ### else: 475 ### globals()["PeachXml_"+importStr] = __import__(PeachStr(importStr), globals(), locals(), [], -1) 476 ### 477 ### def _GetTemplateByName(self, str): 478 ### ''' 479 ### Get the object indicated by ref. Currently the object must have 480 ### been defined prior to this point in the XML 481 ### ''' 482 ### 483 ### origStr = str 484 ### baseObj = self.peachXml 485 ### 486 ### # Parse out a namespace 487 ### 488 ### if str.find(":") > -1: 489 ### ns, tmp = str.split(':') 490 ### str = tmp 491 ### 492 ### print "GetRef(): Found namepsace:",ns 493 ### 494 ### # Check for namespace 495 ### if hasattr(self.context.namespaces, ns): 496 ### baseObj = getattr(self.context.namespaces, ns) 497 ### else: 498 ### raise Exception("Unable to locate namespace") 499 ### 500 ### for name in str.split('.'): 501 ### 502 ### # check base obj 503 ### if hasattr(baseObj, name): 504 ### baseObj = getattr(baseObj, name) 505 ### 506 ### # check templates 507 ### elif hasattr(baseObj, 'templates') and hasattr(baseObj.templates, name): 508 ### baseObj = getattr(baseObj.templates, name) 509 ### 510 ### else: 511 ### print "name: " + str 512 ### print baseObj 513 ### raise Exception("Could not resolve ref", origStr) 514 ### 515 ### return baseObj 516 ### 517 ### 518 ### def _GetDataByName(self, str): 519 ### ''' 520 ### Get the data object indicated by ref. Currently the object must 521 ### have been defined prior to this point in the XML. 522 ### ''' 523 ### 524 ### if hasattr(str, "elementType") and str.elementType == "data": 525 ### return str 526 ### 527 ### origStr = str 528 ### baseObj = self.peachXml 529 ### 530 ### # Parse out a namespace 531 ### 532 ### if str.find(":") > -1: 533 ### ns, tmp = str.split(':') 534 ### str = tmp 535 ### 536 ### print "_GetDataByName(): Found namepsace:",ns 537 ### 538 ### # Check for namespace 539 ### if hasattr(self.context.namespaces, ns): 540 ### baseObj = getattr(self.context.namespaces, ns) 541 ### else: 542 ### raise Exception("_GetDataByName(): Unable to locate namespace") 543 ### 544 ### # check base obj 545 ### if hasattr(baseObj, str): 546 ### return getattr(baseObj, str) 547 ### 548 ### # check templates 549 ### elif hasattr(baseObj, 'data') and hasattr(baseObj.data, str): 550 ### return getattr(baseObj.data, str) 551 ### 552 ### raise Exception("_GetDataByName(): Could not resolve ref", origStr) 553 ### 554 ### def _lookUp(self, name, start): 555 ### ''' 556 ### Search up an object tree looking for an element name. 557 ### ''' 558 ### 559 ### #if start.name == name: 560 ### # print "_lookup: [%s] == [%s]" % (name, start.name) 561 ### # return start 562 ### # 563 ### #else: 564 ### # print "_lookup: [%s] != [%s]" % (name, start.name) 565 ### 566 ### obj = None 567 ### obj = self._lookSiblings(name, start) 568 ### if obj == None and start.parent != None: 569 ### return self._lookUp(name, start.parent) 570 ### 571 ### return obj 572 ### 573 ### def _lookDown(self, name, start): 574 ### 575 ### if start.name == name: 576 ### return start 577 ### 578 ### for child in start: 579 ### 580 ### ret = self._lookDown(name, child) 581 ### if ret != None: 582 ### return ret 583 ### 584 ### return None 585 ### 586 ### def _lookSiblings(self, name, start): 587 ### 588 ### for child in start: 589 ### if child.name == name: 590 ### return child 591 ### #else: 592 ### # print "_lookSiblings: [%s] != [%s]" % (name, child.name) 593 ### 594 ### return None 595 ### 596 ### def _getRef(self, name, parent): 597 ### ''' 598 ### Get a reference to an element in a tempalte 599 ### ''' 600 ### 601 ### obj = None 602 ### isFirst = True 603 ### for name in name.split('.'): 604 ### 605 ### if isFirst: 606 ### isFirst = False 607 ### 608 ### obj = self._lookUp(name, parent) 609 ### 610 ### else: 611 ### obj = self._lookDown(name, obj) 612 ### 613 ### if obj == None: 614 ### raise Exception("_getRef: Unable to resolve reference", name) 615 ### 616 ### return obj 617 ### 618 ### def _createExtraGenerator(self, generator): 619 ### ''' 620 ### Will create and return an instance of an extra 621 ### generated that was specified by the user. 622 ### ''' 623 ### 624 ### code = "PeachXml_"+generator.classStr + '(' 625 ### isFirst = True 626 ### 627 ### for param in generator: 628 ### #if param.elementName != 'param': 629 ### # continue 630 ### 631 ### if param.valueType == 'ref': 632 ### # need to resolve reference! 633 ### obj = self._getRef(param.defaultValue, generator.parent) 634 ### if obj.generator == None: 635 ### raise Exception("_createExtraGenerator(): Unable to resolve generator reference. Object has null generator attribute. [%s]" % str(param.defaultValue)) 636 ### 637 ### PeachXml_Tmp_Generator = obj.generator 638 ### value = 'PeachXml_Tmp_Generator' 639 ### 640 ### else: 641 ### value = param.defaultValue 642 ### 643 ### if not isFirst: 644 ### code += ', ' 645 ### else: 646 ### isFirst = False 647 ### 648 ### code += PeachStr(value) 649 ### 650 ### code += ')' 651 ### gen = eval(code, globals(), locals()) 652 ### 653 ### return gen 654 ### 655 ### 656 ### def _getDefaultGenerator(self, node, group): 657 ### ''' 658 ### Build up a generator construct for a peach dom node. 659 ### ''' 660 ### 661 ### if node.elementType == 'transformer': 662 ### return Block() 663 ### 664 ### generator = None 665 ### innerGen = None 666 ### genList = GeneratorList(None, []) 667 ### 668 ### if len(node.extraGenerators) > 0: 669 ### for gen in node: 670 ### if gen.elementType == 'generator': 671 ### if gen.generator == None: 672 ### gen.generator = self._createExtraGenerator(gen) 673 ### 674 ### genList.getList().append(gen.generator) 675 ### 676 ### ### STRING 677 ### if node.elementType == 'string': 678 ### 679 ### charSize = 1 680 ### if node.type == 'wchar': 681 ### charSize = 2 682 ### 683 ### if node.isStatic == False: 684 ### if node.autoGen == False: 685 ### if node.defaultValue != None: 686 ### # genList must have contents else an array index exception is thrown 687 ### if len(genList.getList()) == 0: 688 ### innerGen = _StaticFromTemplate(node) 689 ### else: 690 ### innerGen = WithDefault(group.addNewGroup(), _StaticFromTemplate(node), genList) 691 ### else: 692 ### # if no value is provided and no extra generators exist then we have no values to fuzz with 693 ### if len(genList.getList()) == 0: 694 ### raise Exception("'autoGen' disabled, no 'value' provided or generators provide for node '" + node.name + "'") 695 ### else: 696 ### genList.setGroup(group.addNewGroup()) 697 ### innerGen = genList 698 ### else: 699 ### if node.defaultValue != None: 700 ### genList.getList().append(StringTokenFuzzer(None, node.defaultValue, node.tokens)) 701 ### innerGen = WithDefault(group.addNewGroup(), _StaticFromTemplate(node), genList) 702 ### else: 703 ### genList.getList().append(BadStrings()) 704 ### genList.setGroup(group.addNewGroup()) 705 ### innerGen = genList 706 ### 707 ### 708 ### # ignore all extraGenerators (genList) for Static node 709 ### else: 710 ### if node.defaultValue != None: 711 ### innerGen = _StaticFromTemplate(node) 712 ### else: 713 ### # if the user specifies a static string w/o a default value we should raise an error 714 ### # because we have no idea what the static value should be. 715 ### raise Exception("No 'value' specified for Static element '" + node.name + "'") 716 ### 717 ### # Handle sizeof relation 718 ### if self._HasSizeofRelation(node): 719 ### 720 ### relation = self._GetSizeofRelation(node) 721 ### blockSize = BlockSize(None) 722 ### 723 ### if node.isStatic == False: 724 ### genList.getList().append(NumberVariance(None, blockSize, 50)) 725 ### genList.getList().append(BadStrings()) 726 ### 727 ### innerGen = WithDefault(group.addNewGroup(), 728 ### blockSize, 729 ### genList) 730 ### else: 731 ### innerGen = blockSize 732 ### 733 ### #print "Of: ", relation.of 734 ### #print dir(relation) 735 ### #print relation.of_ref 736 ### 737 ### if relation.of_ref.generator != None: 738 ### blockSize.setBlock(relation.of_ref.generator) 739 ### 740 ### else: 741 ### relation.blockSize = blockSize 742 ### self._relationSizeofNeedResolving.append(relation) 743 ### 744 ### # Handle countof relation 745 ### if self._HasCountofRelation(node): 746 ### 747 ### relation = self._GetCountofRelation(node) 748 ### 749 ### if relation.of_ref != None: 750 ### 751 ### blockCount = MultiBlockCount(None) 752 ### 753 ### if node.isStatic == False: 754 ### genList.getList().append(NumberVariance(None, blockCount, 50)) 755 ### genList.getList().append(BadStrings()) 756 ### 757 ### innerGen = WithDefault(group.addNewGroup(), 758 ### blockCount, 759 ### genList) 760 ### else: 761 ### innerGen = blockCount 762 ### 763 ### if relation.of_ref.generator != None: 764 ### blockSize.setBlock(relation.of_ref.generator) 765 ### 766 ### else: 767 ### relation.blockCount = blockCount 768 ### self._relationCountofNeedResolving.append(relation) 769 ### 770 ### if innerGen == None: 771 ### genList.getList().append(BadStrings()) 772 ### genList.setGroup(group.addNewGroup()) 773 ### innerGen = genList 774 ### 775 ### # Handle fixed length string 776 ### if node.length != None: 777 ### generator = innerGen = FixedLengthString(None, innerGen, node.length, node.padCharacter, charSize) 778 ### 779 ### # Handle null terminated strings 780 ### if node.nullTerminated: 781 ### generator = innerGen = Block([ 782 ### innerGen, 783 ### Static('\0') 784 ### ]) 785 ### 786 ### # Handle wide char strings 787 ### if charSize == 2: 788 ### generator = innerGen.setTransformer(WideChar()) 789 ### 790 ### # Handle min/max Occurences 791 ### if node.minOccurs != 1 or node.maxOccurs != 1 or (self._HasCountofRelation(node) and relation.from_ref != None): 792 ### if self._HasCountofRelation(node) and relation.from_ref != None: 793 ### 794 ### if relation.from_ref.generator != None: 795 ### generator = MultiBlock(group.addNewGroup(), [innerGen], node.minOccurs, node.maxOccurs, relation.from_ref.generator) 796 ### else: 797 ### generator = MultiBlock(group.addNewGroup(), [innerGen], node.minOccurs, node.maxOccurs) 798 ### relation.blockMulti = generator 799 ### self._relationCountofNeedResolving.append(relation) 800 ### else: 801 ### generator = MultiBlock(group.addNewGroup(), [innerGen], node.minOccurs, node.maxOccurs) 802 ### else: 803 ### generator = innerGen 804 ### 805 ### ### NUMBER 806 ### elif node.elementType == 'number': 807 ### if node.signed: 808 ### isSigned = 1 809 ### else: 810 ### isSigned = 0 811 ### 812 ### if node.endian == 'little': 813 ### isLittleEndian = 1 814 ### else: 815 ### isLittleEndian = 0 816 ### 817 ### # Is number static? 818 ### if node.isStatic: 819 ### innerGen = Static(0) 820 ### if node.defaultValue != None: 821 ### innerGen = _StaticFromTemplate(node) 822 ### else: 823 ### raise Exception("No 'value' specified for Static element '" + node.name + "'") 824 ### else: 825 ### # autoGen 826 ### if node.autoGen == False: 827 ### if node.defaultValue != None: 828 ### # genList must have contents else an array index exception is thrown 829 ### if len(genList.getList()) == 0: 830 ### innerGen = _StaticFromTemplate(node) 831 ### else: 832 ### innerGen = WithDefault(group.addNewGroup(), _StaticFromTemplate(node), genList) 833 ### else: 834 ### # if no value is provided and no extra generators exist then we have no values to fuzz with 835 ### if len(genList.getList()) == 0: 836 ### raise Exception("'autoGen' disabled, no 'value' provided or generators provide for node '" + node.name + "'") 837 ### else: 838 ### innerGen = genList 839 ### else: 840 ### if node.size == 8: 841 ### genList.getList().append(BadNumbers8()) 842 ### elif node.size == 16: 843 ### genList.getList().append(BadNumbers16()) 844 ### elif node.size == 24: 845 ### genList.getList().append(BadNumbers24()) 846 ### elif node.size == 32: 847 ### genList.getList().append(BadNumbers32()) 848 ### elif node.size == 64: 849 ### genList.getList().append(BadNumbers64()) 850 ### else: 851 ### raise Exception("Invalide 'size' specified for element '" + node.name + "'") 852 ### 853 ### if node.defaultValue != None: 854 ### innerGen = WithDefault(group.addNewGroup(), _StaticFromTemplate(node), genList) 855 ### else: 856 ### genList.setGroup(group.addNewGroup()) 857 ### innerGen = genList 858 ### 859 ### # Does number have size relation? 860 ### if self._HasSizeofRelation(node): 861 ### relation = self._GetSizeofRelation(node) 862 ### blockSize = BlockSize(None) 863 ### genList.getList().append(NumberVariance(None, blockSize, 50)) 864 ### 865 ### if relation.of_ref.generator != None: 866 ### blockSize.setBlock(relation.of_ref.generator) 867 ### innerGen = WithDefault(None, 868 ### blockSize, 869 ### genList) 870 ### else: 871 ### innerGen = WithDefault(None, blockSize, genList) 872 ### relation.blockSize = blockSize 873 ### self._relationSizeofNeedResolving.append(relation) 874 ### 875 ### relation = None 876 ### # Does number have count relation? 877 ### if self._HasCountofRelation(node): 878 ### relation = self._GetCountofRelation(node) 879 ### 880 ### if relation.of_ref != None: 881 ### blockCount = MultiBlockCount(None) 882 ### genList.getList().append(NumberVariance(None, blockCount, 50)) 883 ### 884 ### if relation.of_ref.generator != None: 885 ### blockCount.setBlock(relation.of_ref.generator) 886 ### innerGen = WithDefault(None, 887 ### blockCount, 888 ### genList) 889 ### else: 890 ### innerGen = WithDefault(None, blockCount, genList) 891 ### relation.blockCount = blockCount 892 ### self._relationCountofNeedResolving.append(relation) 893 ### 894 ### if innerGen == None: 895 ### innerGen = genList 896 ### 897 ### #allow for generator reference (checksums) 898 ### if node.defaultValue == None: 899 ### genList.setGroup(group.addNewGroup()) 900 ### innerGen = genList 901 ### 902 ### if node.size == 8: 903 ### generator = AsInt8(group.addNewGroup(), innerGen, isSigned, isLittleEndian) 904 ### elif node.size == 16: 905 ### generator = AsInt16(group.addNewGroup(), innerGen, isSigned, isLittleEndian) 906 ### elif node.size == 24: 907 ### generator = AsInt24(group.addNewGroup(), innerGen, isSigned, isLittleEndian) 908 ### elif node.size == 32: 909 ### generator = AsInt32(group.addNewGroup(), innerGen, isSigned, isLittleEndian) 910 ### elif node.size == 64: 911 ### generator = AsInt64(group.addNewGroup(), innerGen, isSigned, isLittleEndian) 912 ### 913 ### if generator == None: raise Exception("Unknown number size, sucks!!") 914 ### 915 ### if node.minOccurs != 1 or node.maxOccurs != 1 or (relation != None and relation.from_ref != None): 916 ### if relation != None and relation.from_ref != None: 917 ### if relation.from_ref.generator != None: 918 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs, relation.from_ref.generator) 919 ### else: 920 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs, relation.from_ref.generator) 921 ### 922 ### else: 923 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 924 ### relation.blockMulti = generator 925 ### self._relationCountofNeedResolving.append(relation) 926 ### 927 ### ### BLOCK or TEMPLATE 928 ### elif node.elementType == 'block' or node.elementType == 'template': 929 ### 930 ### if node.minOccurs != 1 or node.maxOccurs != 1 or self._HasCountofRelation(node): 931 ### block = MultiBlock(group.addNewGroup(), [], node.minOccurs, node.maxOccurs) 932 ### else: 933 ### block = Block([]) 934 ### 935 ### node.generator = block 936 ### 937 ### if self._HasCountofRelation(node): 938 ### relation = self._GetCountofRelation(node) 939 ### relation.blockMulti = block 940 ### 941 ### if relation.from_ref.generator != None: 942 ### block.setGenOccurs = relation.from_ref.generator 943 ### else: 944 ### relation.blockMulti = block 945 ### self._relationSizeofNeedResolving.append(relation) 946 ### 947 ### for child in node: 948 ### gen = self._getDefaultGenerator(child, group) 949 ### block.append(gen) 950 ### child.generator = gen 951 ### 952 ### generator = block 953 ### 954 ### ### SEQUENCE 955 ### elif node.elementType == 'sequence': 956 ### 957 ### groups = [] 958 ### generators = [] 959 ### 960 ### block = GeneratorList2(group.addNewGroup(), groups, generators) 961 ### 962 ### for child in node: 963 ### g = GroupSequence() 964 ### 965 ### gen = self._getDefaultGenerator(child, g) 966 ### 967 ### groups.append(g) 968 ### generators.append(gen) 969 ### 970 ### child.generator = gen 971 ### 972 ### 973 ### if node.minOccurs != 1 or node.maxOccurs != 1 or self._HasCountofRelation(node): 974 ### block = MultiBlock(group.addNewGroup(), block, node.minOccurs, node.maxOccurs) 975 ### 976 ### if self._HasCountofRelation(node): 977 ### relation = self._GetCountofRelation(node) 978 ### relation.blockMulti = block 979 ### 980 ### if relation.from_ref.generator != None: 981 ### block.setGenOccurs = relation.from_ref.generator 982 ### else: 983 ### relation.blockMulti = block 984 ### self._relationSizeofNeedResolving.append(relation) 985 ### 986 ### generator = block 987 ### 988 ### ### CHOICE 989 ### elif node.elementType == 'choice': 990 ### 991 ### groups = [] 992 ### generators = [] 993 ### 994 ### for child in node: 995 ### g = GroupSequence() 996 ### 997 ### gen = self._getDefaultGenerator(child, g) 998 ### 999 ### groups.append(g) 1000 ### generators.append(gen) 1001 ### 1002 ### child.generator = gen 1003 ### 1004 ### block = GeneratorChoice(group.addNewGroup(), node.minOccurs, node.maxOccurs, groups, generators, node.generatedOccurs) 1005 ### 1006 ### if self._HasCountofRelation(node): 1007 ### print "Warning: choice does not support count relation yet!!!" 1008 ### 1009 ### #if node.minOccurs != 1 or node.maxOccurs != 1 or self._HasCountofRelation(node): 1010 ### # block = MultiBlock(block, node.minOccurs, node.maxOccurs) 1011 ### # 1012 ### # if self._HasCountofRelation(node): 1013 ### # relation = self._GetCountofRelation(node) 1014 ### # relation.blockMulti = block 1015 ### # 1016 ### # if relation.from_ref.generator != None: 1017 ### # block.setGenOccurs = relation.from_ref.generator 1018 ### # else: 1019 ### # relation.blockMulti = block 1020 ### # self._relationSizeofNeedResolving.append(relation) 1021 ### 1022 ### generator = block 1023 ### 1024 ### ### FLAGS 1025 ### elif node.elementType == 'flags': 1026 ### 1027 ### flagArray = [] 1028 ### 1029 ### for child in node: 1030 ### if child.elementType != 'flag': 1031 ### continue 1032 ### 1033 ### if child.defaultValue != None: 1034 ### defaultValue = child.defaultValue 1035 ### else: 1036 ### defaultValue = 0 1037 ### 1038 ### if child.length == 1: 1039 ### defaultGen = Bit() 1040 ### elif child.length < 10: 1041 ### defaultGen = List(None, range(2**int(child.length))) 1042 ### else: 1043 ### defaultGen = BadUnsignedNumbers16() 1044 ### 1045 ### genList.getList().append(defaultGen) 1046 ### flag = [child.position, child.length, GeneratorList(group.addNewGroup(), [ 1047 ### Static(defaultValue), 1048 ### genList, 1049 ### Static(defaultValue) 1050 ### ])] 1051 ### 1052 ### flagArray.append(flag) 1053 ### 1054 ### flags = Flags2(None, node.length, flagArray) 1055 ### 1056 ### if node.endian == 'little': 1057 ### endian = 1 1058 ### else: 1059 ### endian = 0 1060 ### 1061 ### if node.length == 8: 1062 ### generator = AsInt8(None, flags, 0, endian) 1063 ### elif node.length == 16: 1064 ### generator = AsInt16(None, flags, 0, endian) 1065 ### elif node.length == 24: 1066 ### generator = AsInt24(None, flags, 0, endian) 1067 ### elif node.length == 32: 1068 ### generator = AsInt32(None, flags, 0, endian) 1069 ### elif node.length == 64: 1070 ### generator = AsInt64(None, flags, 0, endian) 1071 ### 1072 ### if generator == None: raise Exception("Whoops, that was lame, looks like you have a non-standard flag field size. Sucks to be you!") 1073 ### 1074 ### if node.minOccurs != 1 or node.maxOccurs != 1 or self._HasCountofRelation(node): 1075 ### if self._HasCountofRelation(node): 1076 ### relation = self._GetCountofRelation(node) 1077 ### 1078 ### if relation.from_ref != None: 1079 ### if relation.from_ref.generator != None: 1080 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs, relation.from_ref.generator) 1081 ### else: 1082 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 1083 ### relation.from_ref.generator = generator 1084 ### self._relationCountofNeedResolving.append(relation) 1085 ### else: 1086 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 1087 ### else: 1088 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 1089 ### 1090 ### ### BLOB 1091 ### elif node.elementType == 'blob': 1092 ### 1093 ### # TODO: decide what to do with this pad stuff. A user might want to fill the blob via a generator and therefore 1094 ### # provide no default value. In which case, the padding at this level makes no sense. Also this will cause 1095 ### # a runtime error when attempting to calculate len(node.defaultValue) as it will be a NoneType. 1096 ### 1097 ### value = node.defaultValue 1098 ### if node.length != None and len(node.defaultValue) < node.length: 1099 ### # need to pad things with null 1100 ### value += node.padValue * (node.length - len(node.defaultValue)) 1101 ### 1102 ### if node.isStatic == False and len(value) < 2000: 1103 ### 1104 ### # autoGen 1105 ### if node.autoGen == False: 1106 ### if value != None: 1107 ### # genList must have contents else an array index exception is thrown 1108 ### if len(genList.getList()) == 0: 1109 ### innerGen = Static(value) 1110 ### else: 1111 ### innerGen = WithDefault(group.addNewGroup(), Static(value), genList) 1112 ### else: 1113 ### # if no value is provided and no extra generators exist then we have no values to fuzz with 1114 ### if len(genList.getList()) == 0: 1115 ### raise Exception("'autoGen' disabled, no 'value' provided or generators provide for node '" + node.name + "'") 1116 ### else: 1117 ### genList.setGroup(group.addNewGroup()) 1118 ### innerGen = genList 1119 ### else: 1120 ### if value != None: 1121 ### # TODO: Lets do a random flipper!! 1122 ### genList.getList().append(WithDefault(group.addNewGroup(), value, SequentialFlipper(None, value))) 1123 ### innerGen = WithDefault(group.addNewGroup(), _StaticFromTemplate(node), genList) 1124 ### else: 1125 ### # TODO: Lets do a random flipper!! 1126 ### genList.getList().append(SequentialFlipper(None, value)) 1127 ### genList.setGroup(group.addNewGroup()) 1128 ### innerGen = genList 1129 ### 1130 ### generator = innerGen 1131 ### 1132 ### else: 1133 ### generator = Static(value) 1134 ### 1135 ### if node.minOccurs != 1 or node.maxOccurs != 1 or self._HasCountofRelation(node): 1136 ### if self._HasCountofRelation(node): 1137 ### relation = self._GetCountofRelation(node) 1138 ### 1139 ### if relation.from_ref != None: 1140 ### if relation.from_ref.generator != None: 1141 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs, relation.from_ref.generator) 1142 ### else: 1143 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 1144 ### relation.from_ref.generator = generator 1145 ### self._relationCountofNeedResolving.append(relation) 1146 ### else: 1147 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 1148 ### else: 1149 ### generator = MultiBlock(group.addNewGroup(), [generator], node.minOccurs, node.maxOccurs) 1150 ### 1151 ### if generator == None: raise Exception("Unknown type: %s" % node.elementType) 1152 ### 1153 ### if node.transformer != None: 1154 ### if generator.getTransformer() != None: 1155 ### # Make sure we add this transformer 1156 ### # to the last transformer in the chain 1157 ### trans = generator.getTransformer() 1158 ### while trans.getAnotherTransformer() != None: 1159 ### trans = trans.getAnotherTransformer() 1160 ### trans.setAnotherTransformer(node.transformer.transformer) 1161 ### 1162 ### else: 1163 ### generator.setTransformer(node.transformer.transformer) 1164 ### 1165 ### return generator 1166 1167 # end 116881 ''' 82 Goto next mutation. When this is called 83 the state machine is updated as needed. 84 ''' 85 86 raise MutatorCompleted()8789 ''' 90 Return a binary string that contains 91 any information about current state of 92 Mutator. This state information should be 93 enough to let the same mutator "restart" 94 and continue when setState() is called. 95 ''' 96 97 return ''98100 ''' 101 Set the state of this object. Should put us 102 back in the same place as when we said 103 "getState()". 104 ''' 105 pass106 109 110 ##################################################### 111 # Callbacks when Action needs a value 112114 return action.template.getValue()115117 return action.template.getValue()118
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Aug 16 12:17:17 2008 | http://epydoc.sourceforge.net |