decode_mars_nocrypt_log_file.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #!/usr/bin/python
  2. import sys
  3. import os
  4. import glob
  5. import zlib
  6. import struct
  7. import binascii
  8. import traceback
  9. MAGIC_NO_COMPRESS_START = 0x03
  10. MAGIC_NO_COMPRESS_START1 = 0x06
  11. MAGIC_NO_COMPRESS_NO_CRYPT_START = 0x08
  12. MAGIC_COMPRESS_START = 0x04
  13. MAGIC_COMPRESS_START1 = 0x05
  14. MAGIC_COMPRESS_START2 = 0x07
  15. MAGIC_COMPRESS_NO_CRYPT_START = 0x09
  16. MAGIC_END = 0x00
  17. lastseq = 0
  18. def IsGoodLogBuffer(_buffer, _offset, count):
  19. if _offset == len(_buffer): return (True, '')
  20. magic_start = _buffer[_offset]
  21. if MAGIC_NO_COMPRESS_START==magic_start or MAGIC_COMPRESS_START==magic_start or MAGIC_COMPRESS_START1==magic_start:
  22. crypt_key_len = 4
  23. 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:
  24. crypt_key_len = 64
  25. else:
  26. return (False, '_buffer[%d]:%d != MAGIC_NUM_START'%(_offset, _buffer[_offset]))
  27. headerLen = 1 + 2 + 1 + 1 + 4 + crypt_key_len
  28. if _offset + headerLen + 1 + 1 > len(_buffer): return (False, 'offset:%d > len(buffer):%d'%(_offset, len(_buffer)))
  29. length = struct.unpack_from("I", buffer(_buffer, _offset+headerLen-4-crypt_key_len, 4))[0]
  30. 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)))
  31. 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]))
  32. if (1>=count): return (True, '')
  33. else: return IsGoodLogBuffer(_buffer, _offset+headerLen+length+1, count-1)
  34. def GetLogStartPos(_buffer, _count):
  35. offset = 0
  36. while True:
  37. if offset >= len(_buffer): break
  38. 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]:
  39. if IsGoodLogBuffer(_buffer, offset, _count)[0]: return offset
  40. offset+=1
  41. return -1
  42. def DecodeBuffer(_buffer, _offset, _outbuffer):
  43. if _offset >= len(_buffer): return -1
  44. # if _offset + 1 + 4 + 1 + 1 > len(_buffer): return -1
  45. ret = IsGoodLogBuffer(_buffer, _offset, 1)
  46. if not ret[0]:
  47. fixpos = GetLogStartPos(_buffer[_offset:], 1)
  48. if -1==fixpos:
  49. return -1
  50. else:
  51. _outbuffer.extend("[F]decode_log_file.py decode error len=%d, result:%s \n"%(fixpos, ret[1]))
  52. _offset += fixpos
  53. magic_start = _buffer[_offset]
  54. if MAGIC_NO_COMPRESS_START==magic_start or MAGIC_COMPRESS_START==magic_start or MAGIC_COMPRESS_START1==magic_start:
  55. crypt_key_len = 4
  56. 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:
  57. crypt_key_len = 64
  58. else:
  59. _outbuffer.extend('in DecodeBuffer _buffer[%d]:%d != MAGIC_NUM_START'%(_offset, magic_start))
  60. return -1
  61. headerLen = 1 + 2 + 1 + 1 + 4 + crypt_key_len
  62. length = struct.unpack_from("I", buffer(_buffer, _offset+headerLen-4-crypt_key_len, 4))[0]
  63. tmpbuffer = bytearray(length)
  64. seq=struct.unpack_from("H", buffer(_buffer, _offset+headerLen-4-crypt_key_len-2-2, 2))[0]
  65. begin_hour=struct.unpack_from("c", buffer(_buffer, _offset+headerLen-4-crypt_key_len-1-1, 1))[0]
  66. end_hour=struct.unpack_from("c", buffer(_buffer, _offset+headerLen-4-crypt_key_len-1, 1))[0]
  67. global lastseq
  68. if seq != 0 and seq != 1 and lastseq != 0 and seq != (lastseq+1):
  69. _outbuffer.extend("[F]decode_log_file.py log seq:%d-%d is missing\n" %(lastseq+1, seq-1))
  70. if seq != 0:
  71. lastseq = seq
  72. tmpbuffer[:] = _buffer[_offset+headerLen:_offset+headerLen+length]
  73. try:
  74. decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
  75. if MAGIC_NO_COMPRESS_START1==_buffer[_offset] or MAGIC_COMPRESS_START2==_buffer[_offset]:
  76. print("use wrong decode script")
  77. elif MAGIC_COMPRESS_START==_buffer[_offset] or MAGIC_COMPRESS_NO_CRYPT_START==_buffer[_offset]:
  78. tmpbuffer = decompressor.decompress(str(tmpbuffer))
  79. elif MAGIC_COMPRESS_START1==_buffer[_offset]:
  80. decompress_data = bytearray()
  81. while len(tmpbuffer) > 0:
  82. single_log_len = struct.unpack_from("H", buffer(tmpbuffer, 0, 2))[0]
  83. decompress_data.extend(tmpbuffer[2:single_log_len+2])
  84. tmpbuffer[:] = tmpbuffer[single_log_len+2:len(tmpbuffer)]
  85. tmpbuffer = decompressor.decompress(str(decompress_data))
  86. else:
  87. pass
  88. # _outbuffer.extend('seq:%d, hour:%d-%d len:%d decompress:%d\n' %(seq, ord(begin_hour), ord(end_hour), length, len(tmpbuffer)))
  89. except Exception, e:
  90. traceback.print_exc()
  91. _outbuffer.extend("[F]decode_log_file.py decompress err, " + str(e) + "\n")
  92. return _offset+headerLen+length+1
  93. _outbuffer.extend(tmpbuffer)
  94. return _offset+headerLen+length+1
  95. def ParseFile(_file, _outfile):
  96. fp = open(_file, "rb")
  97. _buffer = bytearray(os.path.getsize(_file))
  98. fp.readinto(_buffer)
  99. fp.close()
  100. startpos = GetLogStartPos(_buffer, 2)
  101. if -1==startpos:
  102. return
  103. outbuffer = bytearray()
  104. while True:
  105. startpos = DecodeBuffer(_buffer, startpos, outbuffer)
  106. if -1==startpos: break;
  107. if 0==len(outbuffer): return
  108. fpout = open(_outfile, "wb")
  109. fpout.write(outbuffer)
  110. fpout.close()
  111. def main(args):
  112. global lastseq
  113. if 1==len(args):
  114. if os.path.isdir(args[0]):
  115. filelist = glob.glob(args[0] + "/*.xlog")
  116. for filepath in filelist:
  117. lastseq = 0
  118. ParseFile(filepath, filepath+".log")
  119. else: ParseFile(args[0], args[0]+".log")
  120. elif 2==len(args):
  121. ParseFile(args[0], args[1])
  122. else:
  123. filelist = glob.glob("*.xlog")
  124. for filepath in filelist:
  125. lastseq = 0
  126. ParseFile(filepath, filepath+".log")
  127. if __name__ == "__main__":
  128. main(sys.argv[1:])