4 import csv, time, argparse;
7 from random import randrange
9 from GoodFETMCPCAN import GoodFETMCPCAN;
10 from GoodFETMCPCANCommunication import GoodFETMCPCANCommunication
11 from intelhex import IntelHex;
18 class experiments(GoodFETMCPCANCommunication):
21 GoodFETMCPCANCommunication.__init__(self)
22 #super(experiments,self).__init(self)
25 def filterStdSweep(self, freq, low, high, time = 5):
28 self.client.MCPsetup()
29 for i in range(low, high+1, 6):
30 print "sniffing id: %d, %d, %d, %d, %d, %d" % (i,i+1,i+2,i+3,i+4,i+5)
31 comment= "sweepFilter: "
32 #comment = "sweepFilter_%d_%d_%d_%d_%d_%d" % (i,i+1,i+2,i+3,i+4,i+5)
33 description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d, %d, %d, %d, %d, %d" % (i,i+1,i+2,i+3,i+4,i+5)
34 count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [i, i+1, i+2, i+3, i+4, i+5])
36 for j in range(i,i+5):
37 comment = "sweepFilter: "
38 #comment = "sweepFilter: %d" % (j)
39 description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d " % j
40 count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [j, j, j, j])
46 def sweepRandom(self, freq, number = 5, time = 200):
50 self.client.MCPsetup()
51 for i in range(0,number+1,6):
53 comment = "sweepFilter: "
54 for j in range(0,6,1):
56 #comment += "_%d" % id
60 description = "Running a sweep filer for all the possible standard IDs. This runs the following : " + comment
61 count = self.sniff(freq=freq, duration=time, description=description, comment = comment, standardid = idsTemp)
63 for element in idsTemp:
64 #comment = "sweepFilter: %d" % (element)
65 comment="sweepFilter: "
66 description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d " % element
67 count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [element, element, element])
73 # this will sweep through the given ids to request a packet and then sniff on that
74 # id for a given amount duration. This will be repeated the number of attempts time
76 #at the moment this is set to switch to the next id once a message is identified
77 def rtrSweep(self,freq,lowID,highID, attempts = 1,duration = 1, verbose = True):
79 now = datetime.datetime.now()
80 datestr = now.strftime("%Y%m%d")
81 path = self.DATALOCATION+datestr+"_rtr.csv"
83 outfile = open(filename,'a');
84 dataWriter = csv.writer(outfile,delimiter=',');
85 dataWriter.writerow(['# Time Error Bytes 1-13']);
86 dataWriter.writerow(['#' + "rtr sweep from %d to %d"%(lowID,highID)])
88 #self.client.serInit()
90 for i in range(lowID,highID+1, 1):
93 standardid = [i, i, i, i]
95 self.addFilter(standardid, verbose = True)
97 #### split SID into different areas
98 SIDlow = (standardid[0] & 0x07) << 5; # get SID bits 2:0, rotate them to bits 7:5
99 SIDhigh = (standardid[0] >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
101 packet = [SIDhigh, SIDlow, 0x00,0x00,0x40]
102 dataWriter.writerow(["#requested id %d"%i])
103 #self.client.poke8(0x2C,0x00); #clear the CANINTF register; we care about bits 0 and 1 (RXnIF flags) which indicate a message is being held
105 packet1 = self.client.rxpacket();
106 packet2 = self.client.rxpacket();
108 self.client.txpacket(packet)
109 ## listen for 2 packets. one should be the rtr we requested the other should be
110 ## a new packet response
111 starttime = time.time()
112 while ((time.time() - starttime) < duration):
113 packet = self.client.rxpacket()
117 row.append("%f"%time.time()) #timestamp
118 row.append(0) #error flag (not checkign)
119 row.append("rtrRequest_%d"%i) #comment
120 row.append(duration) #sniff time
121 row.append(1) # filtering boolean
123 row.append("%02x"%ord(byte));
124 dataWriter.writerow(row)
125 print self.client.packet2parsedstr(packet)
126 # packet1=self.client.rxpacket();
127 # packet2=self.client.rxpacket();
128 # if( packet1 != None and packet2 != None):
129 # print "packets recieved :\n "
130 # print self.client.packet2parsedstr(packet1);
131 # print self.client.packet2parsedstr(packet2);
133 # elif( packet1 != None):
134 # print self.client.packet2parsedstr(packet1)
135 # elif( packet2 != None):
136 # print self.client.packet2parsedstr(packet2)
139 while( trial <= attempts):
140 print "trial: ", trial
141 self.client.MCPrts(TXB0=True);
142 starttime = time.time()
143 # this time we will sniff for the given amount of time to see if there is a
144 # time till the packets come in
145 while( (time.time()-starttime) < duration):
146 packet=self.client.rxpacket();
148 row.append("%f"%time.time()) #timestamp
149 row.append(0) #error flag (not checking)
150 row.append("rtrRequest_%d"%i) #comment
151 row.append(duration) #sniff time
152 row.append(1) # filtering boolean
154 row.append("%02x"%ord(byte));
155 dataWriter.writerow(row)
156 print self.client.packet2parsedstr(packet)
157 # packet2=self.client.rxpacket();
159 # if( packet1 != None and packet2 != None):
160 # print "packets recieved :\n "
161 # print self.client.packet2parsedstr(packet1);
162 # print self.client.packet2parsedstr(packet2);
164 # elif( packet1 != None):
165 # print "just packet1"
166 # print self.client.packet2parsedstr(packet1)
167 # elif( packet2 != None):
168 # print "just packet2"
169 # print self.client.packet2parsedstr(packet2)
171 print "sweep complete"
174 # This method will do generation based fuzzing on the id given in standard id
175 # dbLimits is a dictionary of the databytes
176 # dbLimits['db0'] = [low, High]
178 # dbLimits['db7'] = [low, High]
179 # where low is the low end of values for the fuzz, high is the high end value
180 # period is the time between sending packets in milliseconds, writesPerFuzz is the times the
181 # same fuzzed packet will be injecetez. Fuzzes is the number of different packets to be injected
182 def generationFuzzer(self,freq, standardId, dbLimits, period, writesPerFuzz, Fuzzes):
183 print "Fuzzing on standard ID: %d" %standardId
184 self.client.serInit()
186 packetTemp = [0,0,0,0,0,0,0,0]
189 #### split SID into different regs
190 SIDlow = (standardId & 0x07) << 5; # get SID bits 2:0, rotate them to bits 7:5
191 SIDhigh = (standardId >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
193 packet = [SIDhigh, SIDlow, 0x00,0x00, # pad out EID regs
194 0x08, # bit 6 must be set to 0 for data frame (1 for RTR)
195 # lower nibble is DLC
196 packetTemp[0],packetTemp[1],packetTemp[2],packetTemp[3],packetTemp[4],packetTemp[5],packetTemp[6],packetTemp[7]]
199 #get folder information (based on today's date)
200 now = datetime.datetime.now()
201 datestr = now.strftime("%Y%m%d")
202 path = self.DATALOCATION+"InjectedData/"+datestr+"_GenerationFuzzedPackets.csv"
204 outfile = open(filename,'a');
205 dataWriter = csv.writer(outfile,delimiter=',');
206 #dataWriter.writerow(['# Time Error Bytes 1-13']);
207 #dataWriter.writerow(['#' + description])
211 while( fuzzNumber < Fuzzes):
212 #generate a fuzzed packet
213 for i in range(0,8): # for each databyte, fuzz it
215 limits = dbLimits[idx]
216 value = random.randint(limits[0],limits[1]) #generate pseudo-random integer value
219 #put a rough time stamp on the data and get all the data bytes
220 row = [time.time(), standardId,8]
222 for i in range(5,13):
223 row.append(packet[i])
224 msg += " %d"%packet[i]
226 dataWriter.writerow(row)
227 self.client.txpacket(packet)
228 #inject the packet repeatily
229 for i in range(1,writesPerFuzz):
230 self.client.MCPrts(TXB0=True)
231 time.sleep(period/1000)