From 02fd69dec5b5bdc96f6466adc8d3d2b0707f1f25 Mon Sep 17 00:00:00 2001 From: AleaJactaEst Date: Wed, 6 Nov 2019 21:36:42 +0100 Subject: [PATCH] adding yaml output --- spykhanat.py | 124 ++++++++++++++++++++++++++++++--------------- tools/BitStream.py | 53 +++++++++++++++++-- 2 files changed, 131 insertions(+), 46 deletions(-) diff --git a/spykhanat.py b/spykhanat.py index b42a4b8..7e243a1 100755 --- a/spykhanat.py +++ b/spykhanat.py @@ -57,7 +57,7 @@ LOGGER = 'SpyKhanat' #print(ip_packet) class SpyPcap(): - def __init__(self, khanat_host_service, pcap_file, msg_xml, filter_host_service, show_raw_packet, show_message_decoded): + def __init__(self, khanat_host_service, pcap_file, msg_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None): if khanat_host_service: self.khanat_host_service = re.compile(khanat_host_service) else: @@ -78,6 +78,7 @@ class SpyPcap(): msgRawXml = fp.read() self.msgXml = ET.fromstring(msgRawXml) self.decodeImpulse.loadMsg(self.msgXml) + self.outyaml = outyaml def readRaw(self): file = open( self.pcap_file , 'rb') @@ -145,7 +146,7 @@ class SpyPcap(): else: max = hostdetected[host] id = host - logging.getLogger(LOGGER).info("khanat host :%s" % id) + logging.getLogger(LOGGER).info(" host :%s" % id) return id def initialize_client(self, clientid): @@ -212,7 +213,7 @@ class SpyPcap(): # def decode_client_receive_normal_message(self, msgin, clientid, dst): # actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] ) -# logging.getLogger(LOGGER).info("[Client -> Khanat] actions:%s" % str(actions)) +# logging.getLogger(LOGGER).info("[Client -> Server] actions:%s" % str(actions)) # # decodeVisualProperties( msgin ); def decode_client_send_normal_message(self, msgin, clientid, dst): @@ -228,24 +229,24 @@ class SpyPcap(): try: cycle = msgin.readUint32("Cycle") num = msgin.readUint8("num") - logging.getLogger(LOGGER).debug("[Client -> Khanat] Cycle:%u num:%u" % (cycle, num)) + logging.getLogger(LOGGER).debug("[Client -> Server] Cycle:%u num:%u" % (cycle, num)) for i in range(0, num): actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin)) pass except BitStream.OverflowError: noerror = False except Exception as e: - logging.getLogger(LOGGER).debug("[Client -> Khanat] end %s (not read:%u)" % (e.__class__, msgin.needRead())) + logging.getLogger(LOGGER).debug("[Client -> Server] end %s (not read:%u)" % (e.__class__, msgin.needRead())) raise e msgin.enable_LogErrorOnStreamOverflow() - logging.getLogger(LOGGER).debug("[Client -> Khanat] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions]))) + logging.getLogger(LOGGER).debug("[Client -> Server] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions]))) # decodeVisualProperties( msgin ); - def decode_client_message(self, msgin, clientid, dst): + def decode_client_message(self, msgin, clientid, dst, sequenceid): CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber') SystemMode = msgin.readBool('SystemMode') - logging.getLogger(LOGGER).debug("[Client -> Khanat] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst)) + logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst)) self.initialize_client(clientid) self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber if not SystemMode: @@ -256,7 +257,7 @@ class SpyPcap(): self.client_state[clientid]['LastReceivedAck'] = LastReceivedAck AckBitMask = msgin.readUint32('AckBitMask') self.client_state[clientid]['AckBitMask'] = AckBitMask - logging.getLogger(LOGGER).info("[Client -> Khanat] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck)) + logging.getLogger(LOGGER).info("[Client -> Server] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck)) #self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1) self.decode_client_send_normal_message(msgin, clientid, dst) else: @@ -270,11 +271,11 @@ class SpyPcap(): UserKey = msgin.readUint32('UserKey') UserId = msgin.readUint32('UserId') LanguageCode = msgin.readString('LanguageCode') - logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" % + logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" % (typeMessage, CurrentReceivedNumber, clientid, dst, UserAddr, UserKey, UserId, LanguageCode)) elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: LatestProbe = msgin.readSint32('LatestProbe') - logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, + logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, LatestProbe, CurrentReceivedNumber, clientid, dst)) elif message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: Synchronize = msgin.readUint32('Synchronize') @@ -284,7 +285,7 @@ class SpyPcap(): md5Msg = bytes(MsgData) DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') md5Database = bytes(DatabaseData) - logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % ( + logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % ( typeMessage, CurrentReceivedNumber, clientid, dst, Synchronize, stime, LatestSync, binascii.hexlify(md5Msg).decode(), binascii.hexlify(md5Database).decode())) elif message == Enum.CLFECOMMON.SYSTEM_ACK_SYNC_CODE: LastReceivedNumber = msgin.readSint32('LastReceivedNumber') @@ -292,27 +293,27 @@ class SpyPcap(): LongAckBitField = CBitSet.CBitSet() LongAckBitField.readSerial(msgin, 'LongAckBitField') LatestSync = msgin.readSint32('LatestSync') - logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % ( + logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % ( typeMessage, CurrentReceivedNumber, clientid, dst, LastReceivedNumber, LastAckInLongAck, LatestSync, LongAckBitField)) elif message == Enum.CLFECOMMON.SYSTEM_ACK_PROBE_CODE: SizeLatestProbes = msgin.readSint32('SizeLatestProbes') LatestProbes = [] for data in range(0, SizeLatestProbes): LatestProbes.append(msgin.readSint32('LatestProbes')) - logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes))) + logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes))) else: - logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst)) - logging.getLogger(LOGGER).debug("[Client -> Khanat] msg:%s" % msgin.showAllData()) + logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst)) + logging.getLogger(LOGGER).debug("[Client -> Server] msg:%s" % msgin.showAllData()) - def decode_khanat_message(self, msgin, src, dst): + def decode_khanat_message(self, msgin, src, dst, sequenceid): CurrentSendNumber = msgin.readSint32('CurrentSendNumber') - logging.getLogger(LOGGER).debug("[Khanat -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst)) + logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst)) SystemMode = msgin.readBool('SystemMode') self.initialize_client(dst) self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber if not SystemMode: _LastReceivedAck = msgin.readSint32('LastReceivedAck'); - logging.getLogger(LOGGER).debug("[Khanat -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck)) + logging.getLogger(LOGGER).debug("[Server -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck)) actions = self.decode_server(dst, msgin, CurrentSendNumber, CurrentSendNumber-1) if actions: logging.getLogger(LOGGER).debug('list actions: [' + str(len(actions)) + '] ' +','.join( [ str(x) for x in actions] ) ) @@ -328,13 +329,13 @@ class SpyPcap(): logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE") elif action.Code == Enum.TActionCode.ACTION_GENERIC_CODE: action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) - logging.getLogger(LOGGER).info("[Khanat -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action)) + logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action)) elif action.Code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE: action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) - logging.getLogger(LOGGER).debug("[Khanat -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action) + logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action) for id in self.client_state[dst]['GenericMultiPartTemp'].data: if self.client_state[dst]['GenericMultiPartTemp'].data[id].isAvailable(): - logging.getLogger(LOGGER).info("[Khanat -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, id, self.client_state[dst]['GenericMultiPartTemp'].data[id].read().showAllData())) + logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, id, self.client_state[dst]['GenericMultiPartTemp'].data[id].read().showAllData())) elif action.Code == Enum.TActionCode.ACTION_DUMMY_CODE: logging.getLogger(LOGGER).info("Action : ACTION_DUMMY_CODE") self.add_registered_action(dst, action) @@ -344,34 +345,39 @@ class SpyPcap(): # self._Actions.pop(0) else: message = msgin.readUint8('message') - logging.getLogger(LOGGER).debug("[Khanat -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message)) + logging.getLogger(LOGGER).debug("[Server -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message)) if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: - logging.getLogger(LOGGER).debug("[Khanat -> Client] Synchronize") + logging.getLogger(LOGGER).debug("[Server -> Client] Synchronize") Synchronize = msgin.readUint32('Synchronize') stime = msgin.readSint64('stime') LatestSync = msgin.readUint32('LatestSync') MsgData = msgin.readArrayUint8(16, 'MsgData') DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') - logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData))) + logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData))) elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE: - logging.getLogger(LOGGER).debug("[Khanat -> Client] Stalled") - logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) + logging.getLogger(LOGGER).debug("[Server -> Client] Stalled") + logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: - logging.getLogger(LOGGER).debug("[Khanat -> Client] Probe") + logging.getLogger(LOGGER).debug("[Server -> Client] Probe") LatestProbe = msgin.readSint32('LatestProbe') - logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe)) + logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe)) elif message == Enum.CLFECOMMON.SYSTEM_SERVER_DOWN_CODE: - logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) + logging.getLogger(LOGGER).info("[Server -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) else: logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message) #cActionFactory = CAction.CActionFactory(None) #cActionFactory.unpack(msgin) - logging.getLogger(LOGGER).debug("[Khanat -> Client] msg:%s" % msgin.showAllData()) + logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData()) def read(self): file = open( self.pcap_file , 'rb') pcapfile = savefile.load_savefile(file,verbose=False) khanat_host = self.detect_khanat_server(pcapfile.packets) + clientid = 1 + serverid = 1 + list_host = {} + sequenceid = 1 + for pkt in pcapfile.packets: eth_frame = ethernet.Ethernet(pkt.raw()) if eth_frame.type == 2048: @@ -396,18 +402,42 @@ class SpyPcap(): dst = "%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port) if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src): - _provenance = 'Khanat -> Client' + _provenance = 'Server -> Client' + who = "Server" + if src not in list_host: + clientname = "Server %d" % serverid + list_host.setdefault(src, clientname) + serverid += 1 logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) - self.decode_khanat_message(msgin, src, dst) + self.decode_khanat_message(msgin, src, dst, sequenceid) else: - _provenance = 'Client -> Khanat' + _provenance = 'Client -> Server' + if src not in list_host: + clientname = "Client %d" % clientid + list_host.setdefault(src, clientname) + clientid += 1 + who = "Client" logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) - self.decode_client_message(msgin, src, dst) + self.decode_client_message(msgin, src, dst, sequenceid) + moredata='message decoded' + if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: + moredata = "message partially decoded" if self.show_message_decoded: - moredata='(message decoded)' - if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: - moredata = "(message decoded: not full)" - logging.getLogger(LOGGER).debug("[%s] %s %s" % (_provenance, moredata, msgin.showAllData())) + logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData())) + if self.outyaml: + self.outyaml.write("\nmessage_%d:\n sequence: %d\n time: %s\n name: %s\n function: %s\n source: %s\n destination: %s\n state: %s\n message:\n" % ( + sequenceid, + sequenceid, + datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), + list_host[src], + who, + src, + dst, + moredata + )) + for key in msgin.extractAllData(): + self.outyaml.write(" - %s\n" % key) + sequenceid += 1 for client in self.client_state: logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber'])) @@ -432,9 +462,11 @@ def main(): parser.add_argument("--khanat-host-service", help="filter to detect khanat host:service (FES)") parser.add_argument("--filter-host-service", help="filter host:service") parser.add_argument("-d", "--debug", help="show debug message", action='store_true') + parser.add_argument("-v", "--verbose", help="show verbose message", action='store_true') parser.add_argument("-p", "--pcap-file", help="file pcap to read", required=True) parser.add_argument("-m", "--msg-xml", help="file msg.xml (from server khanat)", required=True) parser.add_argument("-r", "--raw", help="show message raw", action='store_true') + parser.add_argument("--yaml", help="generate YAML file (decode all message)", type=argparse.FileType('w'), default=None) parser.add_argument("--show-raw-packet", help="show packet (raw data)", action='store_true') parser.add_argument("--show-message-decoded", help="show packet (raw data)", action='store_true') @@ -442,15 +474,23 @@ def main(): if args.debug: level = logging.getLevelName('DEBUG') - else: + elif args.verbose: level = logging.getLevelName('INFO') + else: + level = logging.getLevelName('WARNING') + for logid in logger: logid.setLevel(level) logging.getLogger(LOGGER).info("Begin") - spy = SpyPcap(khanat_host_service=args.khanat_host_service, pcap_file=args.pcap_file, msg_xml=args.msg_xml, filter_host_service=args.filter_host_service, - show_raw_packet=args.show_raw_packet, show_message_decoded=args.show_message_decoded) + spy = SpyPcap(khanat_host_service=args.khanat_host_service, + pcap_file=args.pcap_file, + msg_xml=args.msg_xml, + filter_host_service=args.filter_host_service, + show_raw_packet=args.show_raw_packet, + show_message_decoded=args.show_message_decoded, + outyaml=args.yaml) if args.raw: spy.readRaw() else: diff --git a/tools/BitStream.py b/tools/BitStream.py index d0690c1..e125d0a 100644 --- a/tools/BitStream.py +++ b/tools/BitStream.py @@ -517,7 +517,7 @@ class BitStream(): self._groupWrite.append((p1, p2, name, 'BitStream', '')) # ------------------------------------ - def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False): + def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False, signed=False): v1 = self._read if nbits == 0: return @@ -543,6 +543,8 @@ class BitStream(): if emulate: self._read = oldRead if decode and not emulate: + if signed: + value = c_int32(value).value self._groupRead.append((v1, v1+nbits, name, typeName, value)) return value @@ -560,7 +562,7 @@ class BitStream(): return v def readSint32(self, name, decode=True): - v = self.readSerial(32, name=name, decode=decode, typeName='Sint32') + v = self.readSerial(32, name=name, decode=decode, typeName='Sint32', signed=True) return c_int32(v).value def readUint16(self, name, decode=True): @@ -568,7 +570,7 @@ class BitStream(): return v def readSint16(self, name): - v = self.readSerial(16, name=name, typeName='Sint16') + v = self.readSerial(16, name=name, typeName='Sint16', signed=True) return c_int16(v).value def readUint8(self, name, decode=True, typeName='Uint8'): @@ -576,7 +578,7 @@ class BitStream(): return v def readSint8(self, name): - v = self.readSerial(8, name=name, typeName='Sint8') + v = self.readSerial(8, name=name, typeName='Sint8', signed=True) return c_int8(v).value def readUint64(self, name): @@ -865,6 +867,49 @@ class BitStream(): self._read = readBefore return ret + def extractAllData(self): + ret = "" + readBefore = self._read + self._read = 0 + while self._read < self._pos: + if self._pos - self._read >= 8: + nsize = 8 + else: + nsize = self._pos - self._read + data = self.readSerial(nsize, decode=False) + if nsize == 1: + ret += "{0:01b}".format(data) + elif nsize == 2: + ret += "{0:02b}".format(data) + elif nsize == 3: + ret += "{0:03b}".format(data) + elif nsize == 4: + ret += "{0:04b}".format(data) + elif nsize == 5: + ret += "{0:05b}".format(data) + elif nsize == 6: + ret += "{0:06b}".format(data) + elif nsize == 7: + ret += "{0:07b}".format(data) + else: + ret += "{0:08b}".format(data) + self._read = readBefore + ret2 = [] + + last = 0 + for x, y, name, typeName, value in self._groupRead: + if not typeName: + nbbit = y - x + typeName = "%d bit" % nbbit + if nbbit > 1: + typeName += "s" + ret2.append("<" + str(x) + ':' + str(y-1) + "> " + '(' + typeName + ') ' + str(name) + ' => ' + str(value) + " : " + ret[x:y]) + last = y + if last < self._pos: + ret2.append("<" + str(last) + ':' + str(self._pos - 1) + "> " + ret[last:]) + + return ret2 + def checkOnlyZeroAtEnd(self): readBefore = self._read while self._read < self._pos: