首页
社区
课程
招聘
[已解决] [求助]一个小众PC游戏资源apk包解包问题 300.00雪花
2024-3-18 16:51 2326

[已解决] [求助]一个小众PC游戏资源apk包解包问题 300.00雪花

2024-3-18 16:51
2326

先上一个二进制图 图片描述
二进制格式大概是这样的,第一次遇到这样奇怪的算法格式,不知道有哪位大佬能看下这是什么格式的算法。
目标是解开所有pak包,自己通过调试它每次读入 1000 个长度,读完后好像过滤掉了 10个字符,然后又将内容拷贝到别的地方,自己下硬件断点没找到它在哪里读取字节,以自己的理解正常一个包文件应该有文件偏移大小这些数据,这个看开头也不像这样的,感觉像是把所有数据先简单的异或了下,自己的实战能力有限。
不知那位大佬有兴趣尝试下,雪花还可以增加些。另外主程序也脱壳了大大降低了难度。

链接:https://pan.baidu.com/s/1I_zGxwX7Qir33A1VkXJmMw
提取码:0r0k


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2024-3-19 09:47 被zhonghuayi编辑 ,原因: 补充
收藏
点赞0
打赏
分享
最新回复 (19)
雪    币: 51
活跃值: (341)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
白菜大叔 2024-3-22 13:37
2
0
7801一看就是zlib压缩的,没有什么特殊算法把,知道地址和长度就可以了。
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-22 15:59
3
0
白菜大叔 7801一看就是zlib压缩的,没有什么特殊算法把,知道地址和长度就可以了。
大佬能看下具体的吗?可以在加雪花,它是一次1000的读取,实战功底欠缺不知道它在那个位置算这个地址和长度
雪    币: 51
活跃值: (341)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
白菜大叔 2024-3-22 16:29
4
0
你就搜索7801,按这个把内容每隔开,然后都zlib解压缩下就好了。<BuffList>
  <eAbnormal_Sleep Effect="0108" Bone="Link_Top" Animation="Action_Stun" />  第一个文件的部分的内容
雪    币: 1244
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_yqjtfroq 2024-3-22 18:12
5
0

韩语的游戏吗

雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-22 20:03
6
0
mb_yqjtfroq 韩语的游戏吗
对的大佬方便给出参考吗?是这算法没办法一起解压吗,感谢二位,一楼得单独打赏了。
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-22 20:07
7
0
mb_yqjtfroq 韩语的游戏吗
看来你们经验丰富啊,一看头标识就知道是啥算法,我还以为他先异或了。e'x'e里找了很久以前也看过一些包没想到他不按e常理出牌尴尬了。这奇葩他如果这样压缩读取,没文件名字他咋分。全干到一起了咋知道啥内容用于啥?
雪    币: 51
活跃值: (341)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
白菜大叔 2024-3-22 21:09
8
0
肯定有个什么表什么的。
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-22 23:51
9
0
很尴尬
//zlib标准头
78 01 - No Compression/low
78 9C - Default Compression
78 DA - Best Compression
但是文件中搜索发现都有,这就没办法循环搜索来解包了呀
雪    币: 267
活跃值: (3199)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
EX呵呵 2024-3-23 00:01
10
0
zhonghuayi 很尴尬 //zlib标准头 78 01 - No Compression/low 78 9C - Default Compression 78 DA - Best Compression 但 ...
用binwalk搞
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-23 22:41
11
0
大佬能详细说下吗?我分段还是解不开你这样的
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-24 22:44
12
0
链接:https://pan.baidu.com/s/1dTlSb6bYKjN28-JJbnCAcg 
提取码:xip2 
这个点击运行就可以直接 加载脱壳的主程序调试
雪    币: 537
活跃值: (810)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gailium 2024-3-25 11:23
13
0
能不能把SgsCtrl.dll也脱壳了
雪    币: 537
活跃值: (810)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gailium 2024-3-25 16:54
14
0
输入二次密码报错C000005
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-26 12:58
15
0
gailium 输入二次密码报错C000005
不会吧?格式头读取在这个dll里吗?
雪    币: 331
活跃值: (366)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
龙卷风呼呼呼 2024-3-26 17:25
16
0
import struct
import zlib
import os

fd = open(r"Script.pak", "rb")

# 文件头
aa, bb, cc, dd, ee = struct.unpack(">11sHIII", fd.read(25))
print(aa, hex(bb), hex(cc), hex(dd), hex(ee))

# 偏移位置
fd.seek(0x289e50)
item_count, = struct.unpack("<I", fd.read(4))
print("压缩文件数量:", item_count)
items = zlib.decompress(fd.read())
pos = 0
while pos < len(items):
    file_name = items[pos:pos + 260].replace(b'\x00', b'').decode("utf8")
    pos += 260
    uncompress_size, compress_size, offset_begin, unkmown = struct.unpack("<IIII", items[pos:pos + 16])
    fd.seek(offset_begin)
    dd = fd.read(compress_size)
    uncompress_data = zlib.decompress(dd)
    assert len(uncompress_data) == uncompress_size
    try:
        os.makedirs(os.path.dirname(file_name))
    except FileExistsError as e:
        pass
    with open(file_name, "wb+") as fp_write:
        fp_write.write(uncompress_data)
    pos += 16
fd.close()

很简单的文件解析,只看文件就能分析的出来。

雪    币: 331
活跃值: (366)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
龙卷风呼呼呼 2024-3-26 17:40
17
0
import struct
import zlib
import os

pak_name=r"Script.pak"
fd = open(pak_name, "rb")

# 文件头
aa, bb, cc, dd, ee = struct.unpack(">11sHIII", fd.read(25))
print(aa, hex(bb), hex(cc), hex(dd), hex(ee))

file_size=os.path.getsize(pak_name)
fd.seek(file_size-4)

dirctory_pos,=struct.unpack("<I", fd.read(4))

# 偏移位置
fd.seek(dirctory_pos-4)
item_count, = struct.unpack("<I", fd.read(4))
print("压缩文件数量:", item_count)
items = zlib.decompress(fd.read())
pos = 0
while pos < len(items):
    file_name = items[pos:pos + 260].replace(b'\x00', b'').decode("utf8")
    pos += 260
    uncompress_size, compress_size, offset_begin, unkmown = struct.unpack("<IIII", items[pos:pos + 16])
    fd.seek(offset_begin)
    dd = fd.read(compress_size)
    uncompress_data = zlib.decompress(dd)
    assert len(uncompress_data) == uncompress_size
    try:
        os.makedirs(os.path.dirname(file_name))
    except FileExistsError as e:
        pass
    with open(file_name, "wb+") as fp_write:
        fp_write.write(uncompress_data)
    pos += 16
fd.close()


雪    币: 537
活跃值: (810)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gailium 2024-3-26 21:28
18
0
zhonghuayi 不会吧?格式头读取在这个dll里吗?
我说是游戏玩不了
雪    币: 127
活跃值: (875)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhonghuayi 2024-3-27 12:13
19
0
龙卷风呼呼呼 import&nbsp;struct import&nbsp;zlib import&nbsp;os pak_name=r&quot;Script.pak&a ...
感谢感谢,和我跟踪的差不多,没想到他是这样的变化,难怪我后面分析不出来。不知道在哪里能单独赠送雪花。单独在打赏你。看完你的分析后,我感觉我前面分析的是对的,通过断点SetFilePointer,还有他总长度减4这块就分析不下去了,大佬就是不一样一眼就看出来了。我还得消化消化。
雪    币: 331
活跃值: (366)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
龙卷风呼呼呼 2024-3-27 14:09
20
0
整个文件结构:文件头(25字节)+n个压缩文件内容+n(四个字节)+压缩文件目录+目录偏移地址(4个字节)
目录结构:文件名(固定260字节,不足用0x00填充)+压缩前的大小(4个字节)+压缩后的大小(4个字节)+当前文件的压缩内容在整个文件中的偏移(4个字节)+ 四个字节(目前没有值,如果有大概率是checksum之类的校验内容)

这是相关的数据结构,可以帮你理解一下。至于打赏,我也不知道有没有这个功能。
游客
登录 | 注册 方可回帖
返回