import random
from random import *

def intelli(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    pack[choice(range(len(packet)))]= byte
    byte1 = choice(["\xff","\x80","\x41","\x00"])
    lon = randrange(0,8)
    pack[choice(range(len(packet)))]= byte1*lon
    print "fuzzing intelli rand byte:%s and comon:%s len:%s\n" % (byte.encode("hex"),byte1.encode("hex"),lon)
    return pack

def onerand(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    pack[choice(range(len(packet)))]= byte
    print "fuzzing rand byte:%s\n" % (byte.encode("hex"))
    return pack

def doublerand(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    byte2 = str(chr(choice(range(256))))
    pack[choice(range(len(packet)))]= byte
    pack[choice(range(len(packet)))]= byte2
    print "fuzzing rand byte:%s byte2:%s\n" % (byte.encode("hex"),byte2.encode("hex"))
    return pack

def triplerand(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    byte2 = str(chr(choice(range(256))))
    byte3 = str(chr(choice(range(256))))
    pack[choice(range(len(packet)))]= byte
    pack[choice(range(len(packet)))]= byte2
    pack[choice(range(len(packet)))]= byte3
    print "fuzzing rand byte:%s byte2:%s byte3:%s\n" % (byte.encode("hex"),byte2.encode("hex"),byte3.encode("hex"))
    return pack

def quadrand(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    byte2 = str(chr(choice(range(256))))
    byte3 = str(chr(choice(range(256))))
    byte4 = str(chr(choice(range(256))))
    pack[choice(range(len(packet)))]= byte
    pack[choice(range(len(packet)))]= byte2
    pack[choice(range(len(packet)))]= byte3
    pack[choice(range(len(packet)))]= byte4
    byte1 = choice(["\xff","\x80","\x41","\x00"])
    lon = randrange(0,8)
    pack[choice(range(len(packet)))]= byte1*lon
    print "fuzzing rand byte:%s byte2:%s byte3:%s byte4:%s\n" % (byte.encode("hex"),byte2.encode("hex"),byte3.encode("hex"),byte4.encode("hex"))
    return pack

def longerrand(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    lon = randrange(0,5000)
    pack[choice(range(len(packet)))]= byte*lon
    print "fuzzing rand byte:%s len:%s\n" % (byte.encode("hex"),lon)
    return pack

def longerrandnull(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(256))))
    lon = randrange(0,400) 
    pack[choice(range(len(packet)))]= str(byte+"\x00")*lon
    print "fuzzing rand byte:%s len:%s\n" % (byte.encode("hex"),lon)
    return pack

def opnum(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(0,2))))
    pack[choice(range(len(packet)))]= byte
    print "fuzzing opnum:%s\n" % (byte.encode("hex"))
    return pack

def doubleopnum(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(0,2))))
    byte2 = str(chr(choice(range(0,2))))
    pack[choice(range(len(packet)))]= byte
    pack[choice(range(len(packet)))]= byte2
    print "fuzzing opnum:%s et opnum no-2:%s\n" % (byte.encode("hex"),byte2.encode("hex"))
    return pack

def tripleopnum(packet):
    pack  = packet[:]
    byte = str(chr(choice(range(0,2))))
    byte2 = str(chr(choice(range(0,2))))
    byte3 = str(chr(choice(range(0,2))))
    pack[choice(range(len(packet)))]= byte
    pack[choice(range(len(packet)))]= byte2
    pack[choice(range(len(packet)))]= byte3
    print "fuzzing opnum:%s, opnum no-2:%s, opnum no-3:%s \n" % (byte.encode("hex"),byte2.encode("hex"),byte3.encode("hex"))
    return pack

def doublenull(packet):
    pack  = packet[:]
    b = choice(range(len(packet)-2))
    c = b+2
    pack[b:c]= "\x00\x00"
    print "fuzzing Doublenum (\"\x00\x00\")\n"
    return pack

def doubleff(packet):
    pack  = packet[:]
    b = choice(range(len(packet)-2))
    c = b+2
    pack[b:c]= "\xff\xff"
    print "fuzzing Doublenum (ff ff)\n"
    return pack

def doublera(packet):
    pack  = packet[:]
    b = choice(range(len(packet)-2))
    c = b+2
    pack[b:c]= str(chr(choice(range(256))))*2
    print "fuzzing Doublera\n"
    return pack

def remove1(packet):
    pack  = packet[:]
    i = randrange(0, len(pack)-1)
    b = pack[:i] + pack[i+1:]
    print "remove two char fuzz, removed :%s"%(pack[i].encode("hex"))
    return b

def changenull(packet):
    pack = packet[:]
    null = [i for i in range(len(pack)) if pack[i] == '\x00']
    byte = (chr(choice(range(256))))
    pack[choice(null)] = byte
    print "replaced one null by:%s"% (byte.encode("hex"))
    return pack

def changeff(packet):
    pack = packet[:]
    null = [i for i in range(len(pack)) if pack[i] == '\xff']
    byte = str(chr(choice(range(256))))
    pack[choice(null)] = byte
    print "replaced one ff by a :%s" % (byte.encode("hex"))
    return pack

def removenull(packet):
    pack = packet[:]
    null = [i for i in range(len(pack)) if pack[i] == '\x00']
    num = choice(null)
    del pack[choice(null)]
    print "deleted null no-:%s"%(num)
    return pack

def mspath(packet):
    pack  = packet[:]
    byte = choice(["\\a\\..\\.",".\\a\\","./a/","a$",".\\a\\..",".\\...\\aaa\\\\.."])
    lon = randrange(0,200)
    pack[choice(range(len(packet)))]= str(byte*lon)
    print "fuzzing chosen str:%s len:%s\n" % (byte.encode("hex"),lon)
    return pack

def common(packet):
    pack  = packet[:]
    byte = choice(["\xff","\x80","\x41","\x00"])
    lon = randrange(0,8)
    b = choice(range(len(packet)-lon))
    c = b+lon
    pack[b:c]= byte*lon
    print "fuzzing common rand common byte:%s len:%s\n" % (byte.encode("hex"),lon)
    return pack

def addsome(packet):
    pack  = packet[:]
    i = "\x00" * randrange(0, 30)
    pack[choice(range(len(packet)))] = i
    print "added some null char, added :%s"%(len(i))
    return pack

def removesome(packet):
    pack  = packet[:]
    i = randrange(0, len(pack)-1)
    b = pack[:i] + pack[i+randrange(0, len(pack)-1):]
    print "remove some char fuzz, removed :%s"%(pack[i].encode("hex"))
    return b

#longerrand,
def randfunc(packet):
    func = choice([addsome,onerand,doublerand,doublera,triplerand,tripleopnum,changeff,doubleopnum,opnum,changenull,longerrandnull,longerrand,removenull,quadrand,remove1,intelli,doubleff,doublenull,removesome,common,mspath])
    print "using %s fuzzing type (HARD)"%(func.__name__) 
    return func(packet)