Mars Xlog windows环境使用实践

准备工作:python2.7环境,通过git克隆mars项目

注意: marxlog 脚本decode_mars_crypt_log_file.py 目前只能在python2+环境里执行,在python3+环境脚本语法不支持,需要修改。
在python2.7执行发现一些无效的导入,导致执行报错,修改后可行。我这边是把xlog文件拷贝到和脚本在相同目录,切换到目录执行 Cpython decode_mars_crypt_log_file.py ***.xlog 命令,就可以查看了。

修改后是这样的,替换 mars\mars\log\crypt\decode_mars_crypt_log_file.py 内容。

!/usr/bin/python

import sys
import os
import glob
import zlib
import struct
import binascii

import pyelliptic

import traceback

import zstandard as zstd

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_SYNC_ZSTD_START = 0x0A;
MAGIC_SYNC_NO_CRYPT_ZSTD_START = 0x0B;
MAGIC_ASYNC_ZSTD_START = 0x0C;
MAGIC_ASYNC_NO_CRYPT_ZSTD_START = 0x0D;

MAGIC_END = 0x00

lastseq = 0

class ZstdDecompressReader:
def init(self, buffer):
self.buffer = buffer

def read(self, size):
    return self.buffer

PRIV_KEY = "145aa7717bf9745b91e9569b80bbf1eedaa6cc6cd0e26317d810e35710f44cf8"
PUB_KEY = "572d1e2710ae5fbca54c76a382fdd44050b3a675cb2bf39feebe85ef63d947aff0fa4943f1112e8b6af34bebebbaefa1a0aae055d9259b89a1858f7cc9af9df1"

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 = 0x9E3779B9
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 \
        or MAGIC_SYNC_ZSTD_START == magic_start or MAGIC_SYNC_NO_CRYPT_ZSTD_START == magic_start or MAGIC_ASYNC_ZSTD_START == magic_start or MAGIC_ASYNC_NO_CRYPT_ZSTD_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]\
        or MAGIC_SYNC_ZSTD_START == _buffer[offset] or MAGIC_SYNC_NO_CRYPT_ZSTD_START == _buffer[offset] or MAGIC_ASYNC_ZSTD_START == _buffer[offset] or MAGIC_ASYNC_NO_CRYPT_ZSTD_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\
    or MAGIC_SYNC_ZSTD_START == magic_start or MAGIC_SYNC_NO_CRYPT_ZSTD_START == magic_start or MAGIC_ASYNC_ZSTD_START == magic_start or MAGIC_ASYNC_NO_CRYPT_ZSTD_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:


    if MAGIC_NO_COMPRESS_START1==_buffer[_offset] or MAGIC_SYNC_ZSTD_START==_buffer[_offset]:
        pass
    
    elif MAGIC_COMPRESS_START2==_buffer[_offset] or MAGIC_ASYNC_ZSTD_START==_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)
        if MAGIC_COMPRESS_START2==_buffer[_offset]:
            decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
            tmpbuffer = decompressor.decompress(str(tmpbuffer))
        else:
            decompressor = zstd.ZstdDecompressor()
            tmpbuffer = next(decompressor.read_from(ZstdDecompressReader(str(tmpbuffer)), 100000, 1000000))
    elif MAGIC_ASYNC_NO_CRYPT_ZSTD_START==_buffer[_offset]:
        decompressor = zstd.ZstdDecompressor()
        tmpbuffer = next(decompressor.read_from(ZstdDecompressReader(str(tmpbuffer)), 100000, 1000000))
    elif MAGIC_COMPRESS_START==_buffer[_offset] or MAGIC_COMPRESS_NO_CRYPT_START==_buffer[_offset]:
        decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
        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)]

        decompressor = zlib.decompressobj(-zlib.MAX_WBITS)
        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:])

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容