Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. import getopt
  2. import sys
  3. import struct
  4. import os
  5. import zlib
  6. import hashlib
  7.  
  8. class MypException(Exception):
  9.     pass
  10.  
  11. def main():
  12.     try:
  13.         opts,args=getopt.getopt(sys.argv[1:],"d:",["directory="])
  14.     except getopt.GetoptError,err:
  15.         print str(err) # will print something like "option -a not recognized"
  16.         #usage()
  17.         sys.exit(2)
  18.     directory=None
  19.     for o,a in opts:
  20.         if o in ("-d","--directory"):
  21.             directory=a
  22.         else:
  23.             raise MypException('unhandled option')
  24.     if directory==None:
  25.         raise MypException('no directory specified')
  26.     files=os.listdir(directory)
  27.     for filename in files:
  28.         if '.tor' not in filename: continue
  29.         print '%s...'%(filename)
  30.         f=open(directory+os.sep+filename,'rb')
  31.         signature,version,endianness,tableOffset,_,_,_,_,_,_=struct.unpack('<LLLQLLLHHL',f.read(40)) #getbasicfileinfo
  32.         #print '0x%08x %d 0x%08x'%(signature,version,endianness)
  33.         if signature!=0x0050594d or endianness!=0xfd23ec43:
  34.             raise MypException('invalid file signature or endianness')
  35.         if version!=5:
  36.             raise MypException('invalid version')
  37.         while tableOffset!=0:
  38.             f.seek(tableOffset,os.SEEK_SET)
  39.             n,tableOffset=struct.unpack('<LQ',f.read(12))
  40.             #print '%d 0x%016x'%(n,tableOffset)
  41.             while n!=0:
  42.                 streamOffset,h,compressedSize,uncompressedSize,qwordHash,X,isCompressed=struct.unpack('<QLLLQLH',f.read(34))
  43.                 if streamOffset==0:
  44.                     break #no need to continue
  45.                 if isCompressed==0 and compressedSize!=uncompressedSize:
  46.                     raise MypException('compression discrepency')
  47.                 currentOffset=f.tell()
  48.                 #print '0x%016x %d 0x%08x 0x%08x 0x%016x 0x%08x %d'%(streamOffset,h,compressedSize,uncompressedSize,qwordHash,X,isCompressed)
  49.                 f.seek(streamOffset,os.SEEK_SET)
  50.                 hashType,hashSize=struct.unpack('<HH',f.read(4)) #2 is sha256?
  51.                 if hashType!=2:
  52.                     raise MypException('unknown hash type')
  53.                 streamHash=f.read(hashSize)
  54.                 #print '%d %d %s'%(hashType,hashSize,streamHash.encode('hex'))
  55.                 buffer=f.read(compressedSize)
  56.                 if isCompressed==1: buffer=zlib.decompress(buffer)
  57.                 h=hashlib.new('sha256')
  58.                 h.update(buffer)
  59.                 computedHash=h.digest()
  60.                 if computedHash!=streamHash:
  61.                     #print '%s!=%s'%(computedHash.encode('hex'),streamHash.encode('hex'))
  62.                     #raise MypException('sha256 discrepency')
  63.                     pass
  64.                 if len(buffer)!=uncompressedSize:
  65.                     raise MypException('size discrepency')
  66.  
  67.                 #XXX: DO SOMETHING HERE
  68.  
  69.                 f.seek(currentOffset,os.SEEK_SET)
  70.                 n-=1
  71.         f.close()
  72.  
  73. if __name__=="__main__":
  74.     main()
  75.  
  76.