吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10209|回复: 6
收起左侧

[Python 转载] pak文件解析代码

[复制链接]
zerglurker 发表于 2019-7-6 09:21
最近遇到一个pak文件,网上都是各种解析工具,但是感觉都不敢用
干脆自己写一个,现在发出来,方便大家一起使用
附件有一个测试用的pak文件
代码如下:
[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import os
import struct
 
 
class Binary:
    def __init__(self, data: [bytearray, bytes, str]):
        self.index = 0
        if isinstance(data, bytearray):
            self.data = data
        elif isinstance(data, bytes):
            self.data = bytearray(data)
        elif isinstance(data, str):
            self.data = bytearray(data.encode(encoding='utf-8'))
        else:
            raise TypeError('data type is invalid:', data.__class__.__name__)
        self.size = len(self.data)
 
    def read_int8(self) -> int:
        ret = self.data[self.index]
        self.index += 1
        return ret
 
    def read_int16(self) -> int:
        ret, = struct.unpack('h', self.data[self.index:self.index + 2])
        self.index += 2
        return ret
 
    def read_int32(self) -> int:
        ret, = struct.unpack('i', self.data[self.index:self.index + 4])
        self.index += 4
        return ret
 
    def read_int64(self) -> int:
        ret, = struct.unpack('q', self.data[self.index:self.index + 8])
        self.index += 8
        return ret
 
    def read_string(self) -> str:
        pass
 
    def read_bytes(self, size: int) -> bytearray:
        if size > self.rest():
            ret = self.data[self.index:]
            self.index += self.rest()
            return ret
        ret = self.data[self.index:self.index + size]
        self.index += size
        return ret
 
    def __len__(self):
        return len(self.data)
 
    def rest(self) -> int:
        return len(self.data) - self.index
 
    @staticmethod
    def bytes2str(data: [bytearray, bytes]):
        out = ''
        if data is None or len(data) == 0:
            return 'Null'
        for b in data:
            if out:
                out += ','
            out += '0x%02X' % b
        out += '\n'
        out += data.decode('utf-8')
        return out
 
 
class PakData:
    def __init__(self, br: Binary):
        self.version = br.read_int32()
        self.count = br.read_int32()
        self.coding = br.read_int8()
        self.resources = list()
        for i in range(self.count):
            item = {
                'id': br.read_int16(),
                'offset': br.read_int32(),
                'data': bytearray(),
                'size': 0
            }
            self.resources.append(item)
        for i, item in enumerate(self.resources):
            if i + 1 < self.count:
                item['size'] = self.resources[i + 1]['offset'] - item['offset']
            else:
                item['size'] = len(br) - item['offset']
            item['data'] = br.data[item['offset']:item['offset'] + item['size']]
 
 
class PakFile:
    def __init__(self, path: str):
        self.path = path
        if os.path.exists(path):
            self.decode()
            return
        self.data = None
 
    def set_path(self, path):
        self.path = path
 
    def decode(self) -> int:
        if os.path.exists(self.path) is False:
            return -1
        with open(self.path, mode='rb') as file:
            raw = bytearray(file.read())
            file.close()
            br = Binary(raw)
            self.data = PakData(br)
 
 
def main():
    pak = PakFile(r'.\zh-CN.pak')
    if isinstance(pak.data, PakData):
        print('版本:', pak.data.version)
        print('数量:', pak.data.count)
        print('编码:', pak.data.coding)
        for i in range(pak.data.count):
            print('ID:', pak.data.resources[i]['id'])
            print('偏移:', pak.data.resources[i]['offset'])
            print('大小:', pak.data.resources[i]['size'])
            print('内容:', Binary.bytes2str(pak.data.resources[i]['data']))
 
 
if __name__ == '__main__':
    main()

zh-CN.zip

16.46 KB, 下载次数: 387, 下载积分: 吾爱币 -1 CB

测试用的pak文件

免费评分

参与人数 2吾爱币 +4 热心值 +2 收起 理由
cmputer + 1 + 1 清晰简单,可用
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| zerglurker 发表于 2019-7-6 09:26
注意:
1 如果你已经有pak文件了,请不要下载附件
2 pak文件结构非常简单
版本 4字节 数量 4字节 编码 1字节
ID01 偏移01
ID02 偏移02
....
ID0n 偏移0n
数据块
别人都叫我老木 发表于 2019-7-6 09:33
heham 发表于 2020-4-18 09:04
版本: 5
数量: 1
编码: 216
ID: -5370
偏移: -838829056
大小: 838906547
Traceback (most recent call last):
  File "1.py", line 127, in <module>
    main()
  File "1.py", line 123, in main
    print('内容:', Binary.bytes2str(pak.data.resources[i]['data']))
  File "1.py", line 66, in bytes2str
    out += data.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd8 in position 8: invalid continuation byte
 楼主| zerglurker 发表于 2020-4-27 18:41
heham 发表于 2020-4-18 09:04
版本: 5
数量: 1
编码: 216

试一试gbk或者gb2312等编码看看
lecibubi 发表于 2021-1-4 16:27
下载一下试试,希望可以用!
m13276965150 发表于 2021-6-11 11:17
大佬您好,我看了您发的关于雷电的那2篇文章,收获很大
我花了2天去学习您的代码,我自身是自学的python
勉强看懂了您的代码之后我有一个很尴尬的问题就是我想尝试这用一下,但是我不懂得如何实际用起来
所以很冒昧的想请教您一下,您是否有实例的代码,可不可以让我学习一下,非常感谢。我知道我这个要求有点过分,只是看了2天,我现在不会用,而且我也不知道我要在学习什么,才能用起来,所以想请教您!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-18 20:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表