Пример #1
0
    def test_packet1(self) -> Node:
        root = Node.void('test')
        root.set_attribute('test', 'test string value')

        # Regular nodes
        root.add_child(Node.void('void_node'))
        root.add_child(Node.s8('s8_node', -1))
        root.add_child(Node.u8('u8_node', 245))
        root.add_child(Node.s16('s16_node', -8000))
        root.add_child(Node.u16('u16_node', 65000))
        root.add_child(Node.s32('s32_node', -2000000000))
        root.add_child(Node.u32('u32_node', 4000000000))
        root.add_child(Node.s64('s64_node', -1234567890000))
        root.add_child(Node.u64('u64_node', 1234567890000))
        root.add_child(Node.binary('bin_node', b'DEADBEEF'))
        root.add_child(Node.string('str_node', 'this is a string!'))
        root.add_child(Node.ipv4('ip4_node', '192.168.1.24'))
        root.add_child(Node.time('time_node', 1234567890))
        root.add_child(Node.float('float_node', 2.5))
        root.add_child(Node.fouru8('4u8_node', [0x20, 0x21, 0x22, 0x23]))
        root.add_child(Node.bool('bool_true_node', True))
        root.add_child(Node.bool('bool_false_node', False))

        # Array nodes
        root.add_child(Node.s8_array('s8_array_node', [-1, -2, 3, 4, -5]))
        root.add_child(Node.u8_array('u8_array_node', [245, 2, 0, 255, 1]))
        root.add_child(Node.s16_array('s16_array_node', [-8000, 8000]))
        root.add_child(Node.u16_array('u16_array_node', [65000, 1, 2, 65535]))
        root.add_child(Node.s32_array('s32_array_node', [-2000000000, -1]))
        root.add_child(Node.u32_array('u32_array_node', [4000000000, 0, 1, 2]))
        root.add_child(
            Node.s64_array('s64_array_node', [-1234567890000, -1, 1, 1337]))
        root.add_child(
            Node.u64_array('u64_array_node', [1234567890000, 123, 456, 7890]))
        root.add_child(
            Node.time_array('time_array_node', [1234567890, 98765432]))
        root.add_child(
            Node.float_array('float_array_node', [2.5, 0.0, 5.0, 20.5]))
        root.add_child(
            Node.bool_array('bool_array_node', [False, True, True, False]))

        # XML escaping
        escape = Node.string(
            'escape_test',
            '\r\n<testing> & \'thing\' "thing" \r\nthing on new line\r\n    ')
        escape.set_attribute('test',
                             '<testing> & \'thing\' "thing" \r\n thing')
        root.add_child(escape)

        # Unicode
        unicode_node = Node.string('unicode', '今日は')
        unicode_node.set_attribute('unicode_attr', 'わたし')
        root.add_child(unicode_node)

        self.assertLoopback(root)
Пример #2
0
    def handle_game_common_request(self, request: Node) -> Node:
        game = Node.void('game')
        for flagid in range(512):
            flag = Node.void('flag')
            game.add_child(flag)

            flag.set_attribute('id', str(flagid))
            flag.set_attribute('t', '0')
            flag.set_attribute('s1', '0')
            flag.set_attribute('s2', '0')
            flag.set_attribute('area', '51')
            flag.set_attribute('is_final', '0')

        # Last month's hit chart
        hit_chart = self.data.local.music.get_hit_chart(
            self.game, self.music_version, self.GAME_MAX_SONGS, 30)
        counts_by_reflink = [0] * self.GAME_MAX_SONGS
        for (reflink, plays) in hit_chart:
            if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
                counts_by_reflink[reflink] = plays
        game.add_child(Node.u32_array('cnt_music_monthly', counts_by_reflink))

        # Last week's hit chart
        hit_chart = self.data.local.music.get_hit_chart(
            self.game, self.music_version, self.GAME_MAX_SONGS, 7)
        counts_by_reflink = [0] * self.GAME_MAX_SONGS
        for (reflink, plays) in hit_chart:
            if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
                counts_by_reflink[reflink] = plays
        game.add_child(Node.u32_array('cnt_music_weekly', counts_by_reflink))

        # Last day's hit chart
        hit_chart = self.data.local.music.get_hit_chart(
            self.game, self.music_version, self.GAME_MAX_SONGS, 1)
        counts_by_reflink = [0] * self.GAME_MAX_SONGS
        for (reflink, plays) in hit_chart:
            if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
                counts_by_reflink[reflink] = plays
        game.add_child(Node.u32_array('cnt_music_daily', counts_by_reflink))

        return game
Пример #3
0
    def handle_game_common_request(self, request: Node) -> Node:
        game = Node.void('game')
        for flagid in range(256):
            flag = Node.void('flag')
            game.add_child(flag)

            flag.set_attribute('id', str(flagid))
            flag.set_attribute('s2', '0')
            flag.set_attribute('s1', '0')
            flag.set_attribute('t', '0')

        hit_chart = self.data.local.music.get_hit_chart(self.game, self.music_version, self.GAME_MAX_SONGS)
        counts_by_reflink = [0] * self.GAME_MAX_SONGS
        for (reflink, plays) in hit_chart:
            if reflink >= 0 and reflink < self.GAME_MAX_SONGS:
                counts_by_reflink[reflink] = plays
        game.add_child(Node.u32_array('cnt_music', counts_by_reflink))

        return game
Пример #4
0
def parse_psmap(data: bytes, offset: str, rootname: str) -> Node:
    pe = pefile.PE(data=data, fast_load=True)
    root = Node.void(rootname)
    base = int(offset, 16)

    def virtual_to_physical(offset: int) -> int:
        for section in pe.sections:
            start = section.VirtualAddress + pe.OPTIONAL_HEADER.ImageBase
            end = start + section.SizeOfRawData

            if offset >= start and offset < end:
                return (offset - start) + section.PointerToRawData
        raise Exception(
            f'Couldn\'t find raw offset for virtual offset 0x{offset:08x}')

    if base >= pe.OPTIONAL_HEADER.ImageBase:
        # Assume this is virtual
        base = virtual_to_physical(base)

    def read_string(offset: int) -> str:
        # First, translate load offset in memory to disk offset
        offset = virtual_to_physical(offset)

        # Now, grab bytes until we're null-terminated
        bytestring = []
        while data[offset] != 0:
            bytestring.append(data[offset])
            offset = offset + 1

        # Its shift-jis encoded, so decode it now
        return bytes(bytestring).decode('shift_jisx0213')

    # For recursing into nodes
    saved_root: List[Node] = []
    saved_loc: List[int] = []

    while True:
        chunk = data[base:(base + 16)]
        base = base + 16

        (nodetype, mandatory, outoffset, width, nameptr,
         defaultptr) = struct.unpack('<BBHIII', chunk)

        if nodetype == 0xFF:
            # End of nodes, see if we should exit
            if len(saved_root) == 0:
                break
            else:
                root = saved_root.pop()
                oldbase = saved_loc.pop()
                if oldbase is not None:
                    base = oldbase
                continue

        # Grab name, get rid of parse numbers
        name = read_string(nameptr)
        try:
            if name.index('#') >= 0:
                name = name[:name.index('#')]
        except ValueError:
            pass

        if nodetype == 0x00:
            raise Exception(f'Invalid node type 0x{nodetype:02x}')
        elif nodetype == 0x01:
            # This is a void node, so we should handle by recursing
            node = Node.void(name)
            root.add_child(node)

            # Recurse here
            saved_root.append(root)

            if defaultptr != 0:
                saved_loc.append(base)
                base = virtual_to_physical(defaultptr)
            else:
                saved_loc.append(None)

            root = node
            continue
        elif nodetype == 0x02 or nodetype == 0x43:
            if nodetype < 0x40:
                elements = int(width / 1)
            else:
                elements = width
            if elements > 1:
                node = Node.s8_array(name, [-1] * elements)
            else:
                node = Node.s8(name, -1)
        elif nodetype == 0x03 or nodetype == 0x44:
            if nodetype < 0x40:
                elements = int(width / 1)
            else:
                elements = width
            if elements > 1:
                node = Node.u8_array(name, [0] * elements)
            else:
                node = Node.u8(name, 0)
        elif nodetype == 0x04 or nodetype == 0x45:
            if nodetype < 0x40:
                elements = int(width / 2)
            else:
                elements = width
            if elements > 1:
                node = Node.s16_array(name, [-1] * elements)
            else:
                node = Node.s16(name, -1)
        elif nodetype == 0x05 or nodetype == 0x46:
            if nodetype < 0x40:
                elements = int(width / 2)
            else:
                elements = width
            if elements > 1:
                node = Node.u16_array(name, [0] * elements)
            else:
                node = Node.u16(name, 0)
        elif nodetype == 0x06 or nodetype == 0x47:
            if nodetype < 0x40:
                elements = int(width / 4)
            else:
                elements = width
            if elements > 1:
                node = Node.s32_array(name, [-1] * elements)
            else:
                node = Node.s32(name, -1)
        elif nodetype == 0x07 or nodetype == 0x48:
            if nodetype < 0x40:
                elements = int(width / 4)
            else:
                elements = width
            if elements > 1:
                node = Node.u32_array(name, [0] * elements)
            else:
                node = Node.u32(name, 0)
        elif nodetype == 0x08 or nodetype == 0x49:
            if nodetype < 0x40:
                elements = int(width / 8)
            else:
                elements = width
            if elements > 1:
                node = Node.s64_array(name, [-1] * elements)
            else:
                node = Node.s64(name, -1)
        elif nodetype == 0x09 or nodetype == 0x4A:
            if nodetype < 0x40:
                elements = int(width / 8)
            else:
                elements = width
            if elements > 1:
                node = Node.u64_array(name, [0] * elements)
            else:
                node = Node.u64(name, 0)
        elif nodetype == 0x0A:
            node = Node.string(name, '')
        elif nodetype == 0x0D:
            node = Node.float(name, 0.0)
        elif nodetype == 0x32 or nodetype == 0x6D:
            if nodetype < 0x40:
                elements = int(width / 1)
            else:
                elements = width
            if elements > 1:
                node = Node.bool_array(name, [False] * elements)
            else:
                node = Node.bool(name, False)
        elif nodetype == 0x2F:
            # Special case, this is an attribute
            if name[-1] != '@':
                raise Exception(
                    f'Attribute name {name} expected to end with @')
            root.set_attribute(name[:-1], '')
            continue
        else:
            raise Exception(f'Unimplemented node type 0x{nodetype:02x}')

        # Append it
        root.add_child(node)

    return root