12ccfd96f83cb060ee384fc66edb82978af2cf15
[goodfet] / client / experiments.py
1 import sys;
2 import binascii;
3 import array;
4 import csv, time, argparse;
5 import datetime
6 import os
7 from random import randrange
8 import random
9 from GoodFETMCPCAN import GoodFETMCPCAN;
10 from GoodFETMCPCANCommunication import GoodFETMCPCANCommunication
11 from intelhex import IntelHex;
12 import Queue
13 import math
14
15 tT = time
16
17
18 class experiments(GoodFETMCPCANCommunication):
19     
20     def __init__(self):
21         GoodFETMCPCANCommunication.__init__(self)
22         #super(experiments,self).__init(self)
23         self.freq = 500;
24         
25     def filterStdSweep(self, freq, low, high, time = 5):
26         msgIDs = []
27         self.client.serInit()
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])
35             if( count != 0):
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])
41                     if( count != 0):
42                         msgIDs.append(j)
43         return msgIDs
44     
45     
46     def sweepRandom(self, freq, number = 5, time = 200):
47         msgIDs = []
48         ids = []
49         self.client.serInit()
50         self.client.MCPsetup()
51         for i in range(0,number+1,6):
52             idsTemp = []
53             comment = "sweepFilter: "
54             for j in range(0,6,1):
55                 id = randrange(2047)
56                 #comment += "_%d" % id
57                 idsTemp.append(id)
58                 ids.append(id)
59             print comment
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)
62             if( count != 0):
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])
68                     if( count != 0):
69                         msgIDs.append(j)
70         return msgIDs, ids
71     
72     
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
75     
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):
78         #set up file
79         now = datetime.datetime.now()
80         datestr = now.strftime("%Y%m%d")
81         path = self.DATALOCATION+datestr+"_rtr.csv"
82         filename = path
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)])
87         print "started"
88         #self.client.serInit()
89         #self.spitSetup(freq)
90         for i in range(lowID,highID+1, 1):
91             self.client.serInit()
92             self.spitSetup(freq)
93             standardid = [i, i, i, i]
94             #set filters
95             self.addFilter(standardid, verbose = True)
96             
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
100             #create RTR packet
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 
104             #clear buffer
105             packet1 = self.client.rxpacket();
106             packet2 = self.client.rxpacket();
107             #send in rtr request
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()
114                 if( packet == None):
115                     continue
116                 row = []
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
122                 for byte in packet:
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);
132 #                continue
133 #            elif( packet1 != None):
134 #                print self.client.packet2parsedstr(packet1)
135 #            elif( packet2 != None):
136 #                print self.client.packet2parsedstr(packet2)
137             trial= 2;
138             # for each trial
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();
147                     row = []
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
153                     for byte in packet:
154                         row.append("%02x"%ord(byte));
155                     dataWriter.writerow(row)
156                     print self.client.packet2parsedstr(packet)
157 #                    packet2=self.client.rxpacket();
158 #                    
159 #                    if( packet1 != None and packet2 != None):
160 #                        print "packets recieved :\n "
161 #                        print self.client.packet2parsedstr(packet1);
162 #                        print self.client.packet2parsedstr(packet2);
163 #                        #break
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)
170                 trial += 1
171         print "sweep complete"
172         outfile.close()
173         
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]
177     # ..
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, standardIDs, dbLimits, period, writesPerFuzz, Fuzzes):
183         #print "Fuzzing on standard ID: %d" %standardId
184         self.client.serInit()
185         self.spitSetup(freq)
186         packet = [0,0,0x00,0x00,0x08,0,0,0,0,0,0,0,0] #empty template
187         #form a basic packet
188         
189 #        #### split SID into different regs
190 #        SIDlow = (standardIds[0] & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
191 #        SIDhigh = (standardIds[0] >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
192 #        
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]]
197 #        
198         
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"
203         filename = path
204         outfile = open(filename,'a');
205         dataWriter = csv.writer(outfile,delimiter=',');
206         #dataWriter.writerow(['# Time     Error        Bytes 1-13']);
207         #dataWriter.writerow(['#' + description])
208             
209         numIds = len(standardIDs)
210         fuzzNumber = 0;
211         while( fuzzNumber < Fuzzes):
212             id_new = standardIDs[random.randint(0,numIds-1)]
213             #### split SID into different regs
214             SIDlow = (id_new & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
215             SIDhigh = (id_new >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
216             packet[0] = SIDhigh
217             packet[1] = SIDlow
218             
219             #generate a fuzzed packet
220             for i in range(0,8): # for each databyte, fuzz it
221                 idx = "db%d"%i
222                 limits = dbLimits[idx]
223                 value = random.randint(limits[0],limits[1]) #generate pseudo-random integer value
224                 packet[i+5] = value
225             
226             #put a rough time stamp on the data and get all the data bytes    
227             row = [time.time(), id_new,8]
228             msg = "Injecting: "
229             for i in range(5,13):
230                 row.append(packet[i])
231                 msg += " %d"%packet[i]
232             #print msg
233             dataWriter.writerow(row)
234             self.client.txpacket(packet)
235             #inject the packet repeatily 
236             for i in range(1,writesPerFuzz):
237                 self.client.MCPrts(TXB0=True)
238                 time.sleep(period/1000)
239             fuzzNumber += 1
240         print "Fuzzing Complete"   
241         outfile.close()
242             
243     
244     def generationFuzzRandomID(self, freq, standardIDs, dbLimits, period, writesPerFuzz, Fuzzes):
245         print "Fuzzing on standard ID: %d" %standardId
246         self.client.serInit()
247         self.spitSetup(freq)
248         packetTemp = [0,0,0,0,0,0,0,0]
249         #form a basic packet
250         
251         #### split SID into different regs
252         SIDlow = (standardId & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
253         SIDhigh = (standardId >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
254         
255         packet = [SIDhigh, SIDlow, 0x00,0x00, # pad out EID regs
256                   0x08, # bit 6 must be set to 0 for data frame (1 for RTR) 
257                   # lower nibble is DLC                   
258                  packetTemp[0],packetTemp[1],packetTemp[2],packetTemp[3],packetTemp[4],packetTemp[5],packetTemp[6],packetTemp[7]]
259         
260         
261         #get folder information (based on today's date)
262         now = datetime.datetime.now()
263         datestr = now.strftime("%Y%m%d")
264         path = self.DATALOCATION+"InjectedData/"+datestr+"_GenerationFuzzedPackets.csv"
265         filename = path
266         outfile = open(filename,'a');
267         dataWriter = csv.writer(outfile,delimiter=',');
268         #dataWriter.writerow(['# Time     Error        Bytes 1-13']);
269         #dataWriter.writerow(['#' + description])
270             
271         numIds = len(standardIDs)
272         fuzzNumber = 0;
273         while( fuzzNumber < Fuzzes):
274             id_new = standsardIDs[random.randint(0,numIds-1)]
275             #### split SID into different regs
276             SIDlow = (id_new & 0x07) << 5;  # get SID bits 2:0, rotate them to bits 7:5
277             SIDhigh = (id_new >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
278             packet[0] = SIDhigh
279             packet[1] = SIDlow
280             
281             #generate a fuzzed packet
282             for i in range(0,8): # for each databyte, fuzz it
283                 idx = "db%d"%i
284                 limits = dbLimits[idx]
285                 value = random.randint(limits[0],limits[1]) #generate pseudo-random integer value
286                 packet[i+5] = value
287             
288             #put a rough time stamp on the data and get all the data bytes    
289             row = [time.time(), standardId,8]
290             msg = "Injecting: "
291             for i in range(5,13):
292                 row.append(packet[i])
293                 msg += " %d"%packet[i]
294             #print msg
295             dataWriter.writerow(row)
296             self.client.txpacket(packet)
297             #inject the packet repeatily 
298             for i in range(1,writesPerFuzz):
299                 self.client.MCPrts(TXB0=True)
300                 time.sleep(period/1000)
301             fuzzNumber += 1
302         print "Fuzzing Complete"   
303         outfile.close()