Example #1
0
def unwrap_packet(data):
    if data.bytesAvailable() < 2:
        return
    flag = data.readByte()
    if flag & BIG_LENGTH_FLAG:
        if data.bytesAvailable() >= 3:
            compressed = False
            byte0 = (flag ^ BIG_LENGTH_FLAG) << 24
            byte1 = (data.readByte() & 0xFF) << 16
            byte2 = (data.readByte() & 0xFF) << 8
            byte3 = data.readByte() & 0xFF
            length = byte0 + byte1 + byte2 + byte3
        else:
            return
    else:
        compressed = flag & ZIPPED_FLAG
        byte0 = (flag & 63) << 8
        byte1 = data.readByte() & 0xFF
        length = byte0 + byte1

    if data.bytesAvailable() < length:
        return
    unwrapped = util.ByteArray(data.readBytes(length))
    assert unwrapped.bytesAvailable() == length
    if compressed:
        compressed = unwrapped.readBytes()
        print('Compressed:', compressed.hex())
        unzipped = zlib.decompress(compressed, -15)
        unwrapped = util.ByteArray(unzipped)
    return unwrapped
Example #2
0
def dump_with_null_map(fname, optional):
    with open(fname, 'rb') as f:
        packet = util.ByteArray(f.read())
    space = protocol.SpaceCommandDecoder()
    while packet.bytesAvailable():
        command = space.decode(packet, optional)
        print(simplejson.dumps(command.__dict__, indent=4, ignore_nan=True))
Example #3
0
 def unwrapClient(self, data):
     output = util.ByteArray()
     for byte in data:
         if byte >= 128:
             byte -= 256
         self.clientSequence[
             self.clientSelector] = byte ^ self.clientSequence[
                 self.clientSelector]
         output.writeByte(self.clientSequence[self.clientSelector])
         self.clientSelector ^= self.clientSequence[self.clientSelector] & 7
     return output.data
Example #4
0
def decode_null_map(data):
    flag = data.readByte()

    if ((flag & INPLACE_MASK_FLAG) != 0):
        length = flag & 0x3F
        if ((flag & INPLACE_MASK_2_BYTES) != 0):
            length = (length << 16) + (
                (data.readByte() & 0xFF) << 8) + (data.readByte() & 0xFF)
        map = util.ByteArray(data.readBytes(length))
        return OptionalMap(length << 3, map)

    length = (flag & 0x60) >> 5
    flag = flag << 3
    map = util.ByteArray()
    if length == 0:
        map.writeByte(flag)
        size = 5
    elif length == 1:
        map1 = data.readByte()
        map.writeByte(flag + ((map1 & 0xFF) >> 5))
        map.writeByte(map1 << 3)
        size = 13
    elif length == 2:
        map1, map2 = data.readByte(), data.readByte()
        map.writeByte(flag + ((map1 & 0xFF) >> 5))
        map.writeByte((map1 << 3) + ((map2 & 0xFF) >> 5))
        map.writeByte(map2 << 3)
        size = 21
    elif length == 3:
        map1, map2, map3 = data.readByte(), data.readByte(), data.readByte()
        map.writeByte(flag + ((map1 & 0xFF) >> 5))
        map.writeByte((map1 << 3) + ((map2 & 0xFF) >> 5))
        map.writeByte((map2 << 3) + ((map3 & 0xFF) >> 5))
        map.writeByte(map3 << 3)
        size = 29
    else:
        raise AssertionError()

    return OptionalMap(size, map)
Example #5
0
def dump_bin(fname):
    os.makedirs('dump', exist_ok=True)
    with open(fname, 'rb') as f:
        i = 0
        reader = PacketReader(f)
        for record in reader:
            if record.rec_type == RECORD_DATA:
                packet = util.ByteArray(record.data)
                protocol.decode_null_map(packet)
                length = packet.position
                packet.position = 0
                raw_optional = list(packet.readBytes(length))
                with open(f'dump/{i}.bin', 'wb') as f:
                    f.write(packet.readBytes())
                print(f'Saved {i}.bin, optional={raw_optional}')
            i += 1
Example #6
0
    def _next_record(self):
        record = super().__next__()
        if record.rec_type == RECORD_BEGIN:
            self.in_space[record.conn_id] = False
            self.queue.append(BeginEvent(record))
        elif record.rec_type == RECORD_END:
            self.queue.append(EndEvent(record))
        elif record.rec_type == RECORD_DATA:
            packet = util.ByteArray(record.data)
            optional_map = protocol.decode_null_map(packet)
            space_conn = self.in_space[record.conn_id]
            decoder = self.space if space_conn else self.control[
                record.outgoing]
            while packet.bytesAvailable():
                try:
                    command = decoder.decode(packet, optional_map)
                except:
                    traceback.print_exc()
                    dummy = protocol.SpaceCommand(None, None)
                    dummy.data = base64.b64encode(packet.data).decode()
                    self.queue.append(CommandEvent(record, self.i, dummy))
                    return

                # upgrade connection if necessary
                if not space_conn and command.command_id == 3:
                    self.in_space[record.conn_id] = True

                # prevent leaking sensitive information
                if space_conn and command.data[
                        'codec'] == 'LoginModelServer_login':
                    command.data['password'] = '******' * 12

                self.queue.append(CommandEvent(record, self.i, command))

            assert packet.bytesAvailable() == 0

        self.i += 1
Example #7
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('filename')
    parser.add_argument('-j',
                        '--json',
                        action='store_true',
                        help='output as json')
    parser.add_argument('-b',
                        '--bin',
                        action='store_true',
                        help='output a binary file for each packet')
    parser.add_argument('-r',
                        '--raw',
                        action='store_true',
                        help='read file as raw packet with embedded null map')
    parser.add_argument('-n',
                        '--null',
                        nargs=1,
                        help='read file as raw packet with provided null map')
    args = parser.parse_args()
    if not os.path.isfile(args.filename):
        parser.error(f'{args.filename} not found')
        sys.exit(1)

    if args.json:
        dump_json(args.filename)
    elif args.bin:
        dump_bin(args.filename)
    elif args.raw:
        dump_raw(args.filename)
    elif args.null:
        nulls = bytearray([int(x, 0) for x in args.null[0].split(',')])
        null_map = protocol.decode_null_map(util.ByteArray(nulls))
        dump_with_null_map(args.filename, null_map)
    else:
        dump_contents(args.filename)