1 # A script for analyzing the output of NPSPY and merging data about streams. 2 3 import sys 4 5 6 def ReadFile(filename, flags='rb'): 7 """Returns the contents of a file.""" 8 file = open(filename, flags) 9 result = file.read() 10 file.close() 11 return result 12 13 14 def WriteFile(filename, contents): 15 """Overwrites the file with the given contents.""" 16 file = open(filename, 'w') 17 file.write(contents) 18 file.close() 19 20 21 # sample line: 'NPP_NewStream(0x645c898, 0x56ba900("application/x-shockwave-flash"), 0x64bb3b0 (http://weeklyad.target.com/target/flash/target/target.swf?ver=090326), TRUE, NP_NORMAL)' 22 class Stream: 23 def __init__(self, line): 24 split = line.split(', ') 25 26 self.mime_type = split[1].split('"')[1] 27 self.url = split[2].split(' ')[1].strip('()') 28 self.seekable = split[3] 29 self.type = split[4].strip(')') 30 self.size = 0 31 self.status = '' 32 try: 33 self.address = split[2].split(' ')[0] 34 except: 35 print 'parsing error on ' + line 36 self.address = '' 37 38 if self.type != 'NP_NORMAL': 39 print 'line got unexpected type: ' + line 40 41 42 def main(argv=None): 43 if argv is None: 44 argv = sys.argv 45 46 streams = [] 47 48 if len(argv) != 2: 49 print 'need filename' 50 return 51 file = ReadFile(argv[1]) 52 for line in file.splitlines(): 53 if line.startswith('NPP_NewStream('): 54 if line.count('(') < 3: 55 print 'unknown format for line: ' + line 56 continue 57 58 s = Stream(line) 59 streams.append(s) 60 elif line.startswith('NPP_Write('): 61 # sample: NPP_Write(0x645c898, 0x64bb3b0, 0, 16384, 0x56c1000("CW"))) 62 split = line.split(', ') 63 address = split[1] 64 start = int(split[2]) 65 size = int(split[3]) 66 found = False 67 for stream in streams: 68 if stream.address == address: 69 if stream.size != start: 70 print 'error: starting at wrong place for write ' + stream.url + ' ' + str(stream.size) + ' ' + str(start) 71 stream.size += size 72 found = True 73 break 74 75 if not found: 76 print "couldn't find stream to match NPP_Write " + line 77 elif line.startswith('NPP_DestroyStream('): 78 # sample: NPP_DestroyStream(0x645c898, 0x64bb3b0, NPRES_DONE) 79 split = line.split(', ') 80 address = split[1] 81 status = split[2].strip(')') 82 found = False 83 for stream in streams: 84 if stream.address == address: 85 stream.status = status 86 stream.address = '' # address can be reused 87 found = True 88 break 89 90 if not found: 91 print "couldn't find stream to match NPP_DestroyStream " + line 92 93 94 output = [] 95 for stream in streams: 96 if stream.status != 'NPRES_DONE': 97 print 'error: no NPP_DestroyStream with success for ' + stream.url + ' ' + stream.status + '.' 98 output.append(', '.join([stream.url, stream.mime_type, str(stream.size), stream.seekable])) 99 output_file = argv[1].replace('.', '_analyzed.') 100 101 WriteFile(output_file, '\n'.join(output)) 102 103 104 if __name__ == "__main__": 105 sys.exit(main()) 106