| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- #!/usr/bin/python
- import sys
- import os
- import glob
- import zlib
- import struct
- import binascii
- import pyelliptic
- import traceback
- MAGIC_NO_COMPRESS_START = 0x03
- MAGIC_NO_COMPRESS_START1 = 0x06
- MAGIC_NO_COMPRESS_NO_CRYPT_START = 0x08
- MAGIC_COMPRESS_START = 0x04
- MAGIC_COMPRESS_START1 = 0x05
- MAGIC_COMPRESS_START2 = 0x07
- MAGIC_COMPRESS_NO_CRYPT_START = 0x09
- MAGIC_END = 0x00
- lastseq = 0
- PRIV_KEY = "05cb6f67b111a49660d706b15875b1ffc840db68e3545bd2786f02ac9a1233ef"
- PUB_KEY = "94e62d97637f357fbd20f0c1f667a67c2f675e158e46015dd0cc54cb3995d0a5d468f7e98b20aec266effb61ec0a2321fb1f8c61af72bf76567921a0d8305005"
- def tea_decipher(v, k):
- op = 0xffffffffL
- v0, v1 = struct.unpack('=LL', v[0:8])
- k1, k2, k3, k4 = struct.unpack('=LLLL', k[0:16])
- delta = 0x9E3779B9L
- s = (delta << 4) & op
- for i in xrange(16):
- v1 = (v1 - (((v0<<4) + k3) ^ (v0 + s) ^ ((v0>>5) + k4))) & op
- v0 = (v0 - (((v1<<4) + k1) ^ (v1 + s) ^ ((v1>>5) + k2))) & op
- s = (s - delta) & op
- return struct.pack('=LL', v0, v1)
- def tea_decrypt(v, k):
- num = len(v) / 8 * 8
- ret = ''
- for i in xrange(0, num, 8):
- x = tea_decipher(v[i:i+8], k)
- ret += x
- ret += v[num:]
- return ret
- def IsGoodLogBuffer(_buffer, _offset, count):
- if _offset == len(_buffer): return (True, '')
- magic_start = _buffer[_offset]
- if MAGIC_NO_COMPRESS_START==magic_start or MAGIC_COMPRESS_START==magic_start or MAGIC_COMPRESS_START1==magic_start:
- crypt_key_len = 4
- elif MAGIC_COMPRESS_START2==magic_start or MAGIC_NO_COMPRESS_START1==magic_start or MAGIC_NO_COMPRESS_NO_CRYPT_START==magic_start or MAGIC_COMPRESS_NO_CRYPT_START==magic_start:
- crypt_key_len = 64
- else:
- return (False, '_buffer[%d]:%d != MAGIC_NUM_START'%(_offset, _buffer[_offset]))
- headerLen = 1 + 2 + 1 + 1 + 4 + crypt_key_len
- if _offset + headerLen + 1 + 1 > len(_buffer): return (False, 'offset:%d > len(buffer):%d'%(_offset, len(_buffer)))
- length = struct.unpack_from("I", buffer(_buffer, _offset+headerLen-4-crypt_key_len, 4))[0]
- if _offset + headerLen + length + 1 > len(_buffer): return (False, 'log length:%d, end pos %d > len(buffer):%d'%(length, _offset + headerLen + length + 1, len(_buffer)))
- if MAGIC_END!=_buffer[_offset + headerLen + length]: return (False, 'log length:%d, buffer[%d]:%d != MAGIC_END'%(length, _offset + headerLen + length, _buffer[_offset + headerLen + length]))
- if (1>=count): return (True, '')
- else: return IsGoodLogBuffer(_buffer, _offset+headerLen+length+1, count-1)
-
-
- def GetLogStartPos(_buffer, _count):
- offset = 0
- while True:
- if offset >= len(_buffer): break
-
- if MAGIC_NO_COMPRESS_START==_buffer[offset] or MAGIC_NO_COMPRESS_START1==_buffer[offset] or MAGIC_COMPRESS_START==_buffer[offset] or MAGIC_COMPRESS_START1==_buffer[offset] or MAGIC_COMPRESS_START2==_buffer[offset] or MAGIC_COMPRESS_NO_CRYPT_START==_buffer[offset] or MAGIC_NO_COMPRESS_NO_CRYPT_START==_buffer[offset]:
- if IsGoodLogBuffer(_buffer, offset, _count)[0]: return offset
- offset+=1
-
- return -1
-
- def DecodeBuffer(_buffer, _offset, _outbuffer):
-
- if _offset >= len(_buffer): return -1
- # if _offset + 1 + 4 + 1 + 1 > len(_buffer): return -1
- ret = IsGoodLogBuffer(_buffer, _offset, 1)
- if not ret[0]:
- fixpos = GetLogStartPos(_buffer[_offset:], 1)
- if -1==fixpos:
- return -1
- else:
- _outbuffer.extend("[F]decode_log_file.py decode error len=%d, result:%s \n"%(fixpos, ret[1]))
- _offset += fixpos
- magic_start = _buffer[_offset]
- if MAGIC_NO_COMPRESS_START==magic_start or MAGIC_COMPRESS_START==magic_start or MAGIC_COMPRESS_START1==magic_start:
- crypt_key_len = 4
- elif MAGIC_COMPRESS_START2==magic_start or MAGIC_NO_COMPRESS_START1==magic_start or MAGIC_NO_COMPRESS_NO_CRYPT_START==magic_start or MAGIC_COMPRESS_NO_CRYPT_START==magic_start:
- crypt_key_len = 64
- else:
- _outbuffer.extend('in DecodeBuffer _buffer[%d]:%d != MAGIC_NUM_START'%(_offset, magic_start))
- return -1
- headerLen = 1 + 2 + 1 + 1 + 4 + crypt_key_len
- length = struct.unpack_from("I", buffer(_buffer, _offset+headerLen-4-crypt_key_len, 4))[0]
- tmpbuffer = bytearray(length)
- seq=struct.unpack_from("H", buffer(_buffer, _offset+headerLen-4-crypt_key_len-2-2, 2))[0]
- begin_hour=struct.unpack_from("c", buffer(_buffer, _offset+headerLen-4-crypt_key_len-1-1, 1))[0]
- end_hour=struct.unpack_from("c", buffer(_buffer, _offset+headerLen-4-crypt_key_len-1, 1))[0]
- global lastseq
- if seq != 0 and seq != 1 and lastseq != 0 and seq != (lastseq+1):
- _outbuffer.extend("[F]decode_log_file.py log seq:%d-%d is missing\n" %(lastseq+1, seq-1))
- if seq != 0:
- lastseq = seq
- tmpbuffer[:] = _buffer[_offset+headerLen:_offset+headerLen+length]
- try:
- decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
- if MAGIC_NO_COMPRESS_START1==_buffer[_offset]:
- pass
-
- elif MAGIC_COMPRESS_START2==_buffer[_offset]:
- svr = pyelliptic.ECC(curve='secp256k1')
- client = pyelliptic.ECC(curve='secp256k1')
- client.pubkey_x = str(buffer(_buffer, _offset+headerLen-crypt_key_len, crypt_key_len/2))
- client.pubkey_y = str(buffer(_buffer, _offset+headerLen-crypt_key_len/2, crypt_key_len/2))
- svr.privkey = binascii.unhexlify(PRIV_KEY)
- tea_key = svr.get_ecdh_key(client.get_pubkey())
- tmpbuffer = tea_decrypt(tmpbuffer, tea_key)
- tmpbuffer = decompressor.decompress(str(tmpbuffer))
- elif MAGIC_COMPRESS_START==_buffer[_offset] or MAGIC_COMPRESS_NO_CRYPT_START==_buffer[_offset]:
- tmpbuffer = decompressor.decompress(str(tmpbuffer))
- elif MAGIC_COMPRESS_START1==_buffer[_offset]:
- decompress_data = bytearray()
- while len(tmpbuffer) > 0:
- single_log_len = struct.unpack_from("H", buffer(tmpbuffer, 0, 2))[0]
- decompress_data.extend(tmpbuffer[2:single_log_len+2])
- tmpbuffer[:] = tmpbuffer[single_log_len+2:len(tmpbuffer)]
- tmpbuffer = decompressor.decompress(str(decompress_data))
- else:
- pass
- # _outbuffer.extend('seq:%d, hour:%d-%d len:%d decompress:%d\n' %(seq, ord(begin_hour), ord(end_hour), length, len(tmpbuffer)))
- except Exception, e:
- traceback.print_exc()
- _outbuffer.extend("[F]decode_log_file.py decompress err, " + str(e) + "\n")
- return _offset+headerLen+length+1
- _outbuffer.extend(tmpbuffer)
-
- return _offset+headerLen+length+1
- def ParseFile(_file, _outfile):
- fp = open(_file, "rb")
- _buffer = bytearray(os.path.getsize(_file))
- fp.readinto(_buffer)
- fp.close()
- startpos = GetLogStartPos(_buffer, 2)
- if -1==startpos:
- return
-
- outbuffer = bytearray()
-
- while True:
- startpos = DecodeBuffer(_buffer, startpos, outbuffer)
- if -1==startpos: break;
-
- if 0==len(outbuffer): return
-
- fpout = open(_outfile, "wb")
- fpout.write(outbuffer)
- fpout.close()
-
- def main(args):
- global lastseq
- if 1==len(args):
- if os.path.isdir(args[0]):
- filelist = glob.glob(args[0] + "/*.xlog")
- for filepath in filelist:
- lastseq = 0
- ParseFile(filepath, filepath+".log")
- else: ParseFile(args[0], args[0]+".log")
- elif 2==len(args):
- ParseFile(args[0], args[1])
- else:
- filelist = glob.glob("*.xlog")
- for filepath in filelist:
- lastseq = 0
- ParseFile(filepath, filepath+".log")
- if __name__ == "__main__":
- main(sys.argv[1:])
|