关灯
开启左侧

魔兽WoD新文件格式:CASC文件系统分析与WoD文件拆解器

  [复制链接]
admin实名认证 发表于 2016-5-4 23:00:22 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
 
文件拆解器
只负责无脑搬运,程序风险自行承担。

解压工具下载
游客,如果您要查看本帖隐藏内容请回复


用法:
1.如果你是64位,把wowb-64.exe改名成别的(例如wowb-642.exe)
2.打开wowb.exe
3.运行extractor.exe
4.选择wowb.exe进程
5.选择输出目录
6.选择文件列表(包里附带,由TOM_RUS提供)
7.选择DLL的存放目录(如果你原样解压,不用动)
8.单击“Launch”按钮
9.等
10.耐心等
11.等差不多两个小时
12.??
13.完活


CASC (内容可寻存储容器) 文件系统

德拉诺之王 Alpha, Build 6.0.1.18125
1.2版

允许无限制地发布和复制这份说明文档,只要没有修改。允许自由地引用于其他作品,只要声明了引用来源和作者。

0) 简介
CASC是目前暴雪在《风暴英雄》和《魔兽世界:德拉诺之王》Alpha版本中采用的新文件格式。
根据说明,它比之前使用的MPQ格式功能更强大,更轻量。截至目前,新格式完全没有加密能力,而且只支持一种文件压缩算法。那些绝不可以被修改的重要文件(例如地图文件)的正确性,依靠位于根目录下的一种叫“signaturefile”的文件来保证。似乎以后再也没有办法获取客户端包含的全部文件的文件名了,MPQ包含一个“(listfile)”用纯文本给出所有文件名,而CASC似乎没有。
在我的分析中,仍有几处含义不明的值。利用我所发现的知识,你应该能够从压缩档中定位并提取任何已经完全下载下来的文件。
我的研究范围不涵盖任何按需下载或部分下载的文件,它们可能会引入一些难以理解的问题。另外目前只涵盖了'data/data/'目录下的文件。我还没搞明白'data/config/'和'data/indices/'下的文件是干什么用的,不过没有它们照样可以提取游戏文件。
欢迎任何反馈,也希望我的发现能够帮助其他人解开剩下的谜团。

0.1) 术语
[LE]:给定数据按小端对齐存储。
[BE]:给定数据按大端对齐存储。
译注:32位数“0x12345678”按[LE]存储会存为“0x78 0x56 0x34 0x12”;按[BE]存储会存为“0x12 0x34 0x56 0x78”。

0.2) BlizzHash
除MD5以外,还需要用到一种Bob Jenkins的散列算法,后文称作BlizzHash。Hash值由A、B两部分组成,每部分为4字节;有时两部分都会用到,有时只用一个。数据按每块12字节进行散列,但余下不足一块的数据也会参与散列。实际实现请参照'BlizzHash.cpp'。

译注:
其中有一个宏定义HASH_BLOCK_SIZE 12意即按12字节分块。

请注意在生成每个Hash值之前都需要将HashA和HashB都初始化为0
1) data.XXX 文件

1.1) 概述
所有 data.XXX 文件(后文称作“data文件”)是单纯的文件容器。它们只包含纯文件内容,没有任何的索引信息。所有包含在内的文件按照有序的二进制块存储,每一块有一个很短的首部(30字节)。由于技术所限(参见IDX文件编址格式),任何data文件都不能超过2^30 = 1,073,741,824字节。然而,最多可以有2^10 = 1,024个data文件并存,所以整个系统可以寻址超过1TiB的压缩数据(含额外开销)。

1.2) 文件格式

1.2.1) 整体格式
  • [块] [块] [块] .... [块]

1.2.2) [块]格式
  • 16 字节 - MD5校验和(不确定是校验谁,也许是首部?)
  • 4 字节 - 整块的大小(包括前面的校验和),以字节为单位[LE]
  • 10 字节 - 未知
  • [数据] - 长度为整块的大小减去30字节

2) BLTE 文件

2.1) 概述
BLTE文件是(目前)data文件中唯一包含的文件类型。它包含了实际的游戏文件,可以分簇,每一簇独立地压缩(也许还能独立地下载)。

2.2) 文件格式

2.2.1) 整体格式
  • 4 字节 - 标头“BLTE”
  • 4 字节 - 压缩数据偏移,以字节为单位[BE]
  • if(压缩数据偏移 > 0)
    {
    • 2 字节 - 未知,猜测是[BE]
    • 2 字节 - 簇数量[BE]
    • for(簇数量)
      {
      • 4 字节 - 压缩簇大小,以字节为单位[BE]
      • 4 字节 - 解压后簇大小,以字节为单位[BE]
      • 16 字节 - 簇MD5校验和(应该是按压缩后的簇,我觉得)
      }
    • for(簇数量)
      {
      • [压缩数据块]
      }
    }
  • else
    {
    • [压缩数据块]
    }

2.2.2) [压缩数据块]格式
  • 1 字节 - [数据]的压缩类型(目前用'N'表示未压缩,'Z'表示用Deflate算法(ZLib))
  • [数据] - 长度为压缩后大小减1字节
译注:ZLib需要拿源码自己编译一遍才能用。

3) *.idx 文件

3.1) 概述
IDX文件将前9字节的MD5‘文件键’(后详)与所在的data文件编号(data.XXX)和在该文件内指向该[块]起始位置的字节偏移量建立对应关系。IDX文件由以下两块连在一起写作十六进制形式作为文件名:
  • 1 字节 - 文件编号(总是在0x00 .. 0x0F之间)
  • 4 字节 - 版本号[LE]
在更新时,老版本会被保留,一旦发生数据污染就能恢复数据。对同一个文件编号,只要装载版本号最高的IDX文件就足够了;而对同一个版本号,每一个文件编号的IDX文件都必须装载。

3.2) 文件格式

3.2.1) 整体格式
  • 首部1:
    • 4 字节 - 首部2的长度(按字节)[LE]
    • 4 字节 - 首部2的BlizzHash校验和(只要A部分)[LE]
    • [填充] - 全部填0x00直到坐标(8 + 首部2的长度 + 0x0F) & 0xFFFFFFF0
  • 首部2:
    • 4 字节 - 数据长度(按字节)[LE]
    • 4 字节 - 数据的BlizzHash校验和(只要A部分)[LE]
      (数据按18字节分块散列!)
  • 数据:
    • for(数据长度 / 18)
      {
      • 18 字节 - [块]
      }
    • [填充] - 全部填0x00直到坐标(数据长度 + 0x0FFF) & 0xFFFFF000
    • [未知]

译注:首部2应该还包含了其他信息,我尝试看了几个,后面都有一个32位数“0”和32位数“4”[LE],总长度为16字节,但作者没有说明。填充存在的目的应该是将数据块的起始位置按4KiB在文件内对齐,加快速度——猜测WoW是按4KiB/次读取磁盘文件的,等同于NTFS默认的磁盘簇大小。

3.2.2) [块]格式
  • 9 字节 - 文件键的前9字节
  • 1 字节 - 索引信息的高字节
  • 4 字节 - 索引信息的低字节[BE]
  • 4 字节 - 文件大小,以字节为单位[LE]

索引信息按下面的方式计算后可以得到编号和偏移:
  • data文件编号 = (高字节 << 2) | ((低字节 & 0xC0000000) >> 30)
  • data文件偏移 = (低字节 & 0x3FFFFFFF)
译注:IDX文件用于定位BLTE在哪一个data文件的哪一个位置上。读取时可以把索引信息的高字节和低字节看作一个整体,[BE],等到运算时再切分开。

4) data文件中包含的特殊文件

4.1) 概述
在data文件中,有4个特殊的文件,用于文件系统管理,而非普通的游戏文件。因此它们没有被IDX文件索引,而是依据它们在data文件中的MD5校验和,由Build配置文件(后详)予以索引。
译注:这几个特殊文件,同样装在BLTE里,要从BLTE里解出来才是这些文件。


4.2) "encoding"文件

4.2.1) 概述
给定一个文件内容的MD5散列值,"encoding"可以确定其文件键。文件键通过IDX文件就可以找出实际文件内容的存放位置。文件键可能也是一个MD5散列,但我还没找出它究竟散列了什么东西。不过,只是出于单纯的提取游戏文件的目的,这没什么关系。
从data文件和BLTE中提取出来之后,它的格式如下所述。


4.2.2) 文件格式
  • 首部:
    • 2 字节 - 语言(?)'EN'
    • 1 字节 - 未知
    • 1 字节 - 未知
    • 1 字节 - 未知
    • 2 字节 - 未知,可能是[BE]
    • 2 字节 - 未知,可能是[BE]
    • 4 字节 - Hash表大小[BE]
    • 4 字节 - 未知,可能是[BE]
    • 1 字节 - 未知
    • 4 字节 - Hash表偏移,以字节为单位[BE]
  • 未知:
    • 一组纯文本,以零结尾的ASCII字串,直到首部结束之后[Hash表偏移]个字节处。
  • Hash表校验和块:
    • for(Hash表大小)
      {
      • 16 字节 - 后面的Hash表块中第一个入口的文件内容MD5
      • 16 字节 - MD5校验和(也许是校验后面Hash表块的?)
      }
  • Hash表块:
    • for(Hash表大小)
      {
      • while( 2个字节非零 )
        {
        • 4 字节 - 文件大小,以字节为单位[BE]
        • 16 字节 - 文件内容MD5
        • 16 字节 - 文件键
        }
      • 28 字节 - 在最后一个入口结束后填充0x00
      }


译注:
这一段可能不好理解,作者没有解释入口的概念,我简单解释一下。
这个while表示读两个字节,如果不是零,就再读后面4+16+16个字节——这36个字节合在一起称为一个“入口”。每一个Hash表项可能有多个入口。
每一个Hash表项的第一个入口的“文件内容MD5”这一段(也就是第一个入口的[4:19],整个表项的[6:21])会写在前面“Hash表校验和块”里面。
如果while处读到的两个字节都是零,说明该表项已经结束,在其后会有28个填充零。


4.3) "root"文件

4.3.1) 概述
"root"将一个游戏文件完整文件名的BlizzHash与该文件的内容的MD5校验和关联起来。依据内容的MD5校验和可以在"encoding"中获取文件键。"root"是由单纯的许多数据块组成,直到文件结束。从data文件和BLTE中提取出来后,它的格式如下所述。

4.3.2) 文件格式

4.3.2.1) 整体格式
  • [数据块] [数据块] [数据块] .... [数据块]

4.3.3.2) [数据块]格式
  • 首部:
    • 4 字节 - Root入口数量[LE]
    • 4 字节 - 未知,可能是[LE]
    • 4 字节 - 未知,可能是[LE]
  • 未知:
    • for(Root入口数量)
      {
      • 4 字节 - 未知,可能是[LE]
      }
  • 数据:
    • for(Root入口数量)
      {
      • 16 字节 - 文件内容MD5
      • 4 字节 - 文件全名的BlizzHash(B)[LE]
      • 4 字节 - 文件全名的BlizzHash(A)[LE]
      }



4.4) "download"文件

4.4.1) 概述
这是data文件中所含四个特殊文件中的一个。


4.5) "install"文件

4.5.1) 概述
这是data文件中所含四个特殊文件中的一个。

5) Build配置文件

5.1) 概述
这些文件位于'data/config/'。它们的文件名就是一段MD5散列,但我还不知道散列了什么。
它们存放于一种目录结构中,以其MD5的前两字节和次前两字节作为目录名。例如一个名为'806f4fd265de05a9b328310fcc42eed0'的Build配置文件可以在'data/config/80/6f/'目录下找到。
这些文件是一种格式类似ini的纯文本文件,包含了客户端一个Build的信息。它们遵循一种类似'变量名 = 变量值'的格式,'#'用于注释。目前指定了这些变量:

5.2) 指定变量
变量名
信息
示例
build-name
Build名字
'WOW-18125patch6.0.1'
build-playbuild-installer
使用的安装程序
'ngdptool_casc2'
build-product
产品名
'WoW'
build-uid
Build的UID
'wow_beta'
download
"download"文件的MD5散列
encoding
"encoding"文件的MD5散列
install
"install"文件的MD5散列
root
"root"文件的MD5散列


请注意对这四个特殊文件,可能会给出多个MD5散列值。这时,最后一个给出的值可能是正在使用的。

6) CDN(内容分布网络)配置文件

6.1) 概述
这个文件位于'data/config/'而且与5)中描述的Build配置文件具有相同的命名和存放规则。它们也有相同的文件格式。CDN配置文件包含了对所有可用的Build配置文件、档案组、档案和位于'data/indices'的补丁档案的引用。

6.2) 指定变量
变量名
信息
archive-group
位于'data/indices/'的档案组文件
archives
位于'data/indices/'的所有档案文件,以一个空格分隔
builds
位于'data/config/'的所有Build配置文件,以一个空格分隔
patch-archives
位于'data/indices/'的所有补丁档案文件,以一个空格分隔


7) 从CASC文件系统读取内容的处理流程

7.1) 初始化
  • - 加载CDN配置文件并找到要用的Build配置文件
  • - 加载Build配置文件
  • - 加载所有IDX文件并将数据存储于一个关联容器中:
    (文件键的前9字节 -> 索引信息)
  • - 利用从Build配置文件中找到的MD5,从data文件中定位并提取"encoding"文件
  • - 加载encoding文件并将数据存储于一个关联容器中:
    (文件内容MD5 -> 文件键)
  • - 利用从Build配置文件中找到的MD5,从data文件中定位并提取"root"文件
  • - 加载root文件并将数据存储于一个关联容器中:
    (完整文件名的BlizzHash -> 文件内容MD5)
    ** 注意单个BlizzHash可能会对应多个root入口,但其中只有一个是有效的! **
    ** 暂时还不知道如何确定哪一个是有效的 **

7.2) 定位并读取文件
  • - 将文件名转换为全大写,并将'/'替换为'\'
  • - 用文件名生成BlizzHash
  • - 用BlizzHash找到正确的root入口(或者干脆把找到的全试一遍..)
  • - 用root入口中给出的文件内容MD5,在encoding文件里查找文件键
  • - 用文件键,在IDX文件里查找索引信息
  • - 用索引信息,定位并提取该文件的BLTE
  • - 从BLTE中提取文件

8) Changelog
  • v1.0
    • - 初始的版本
  • v1.1
    • - FileTable更名为"encoding"文件
    • - Manifest文件更名为"root"文件
    • - 指出BlizzHash实际上是Bob Jenkin的散列
    • - 添加关于"download"和"install"文件的信息
  • v1.2
    • - 对'data/config'目录的分析


译注:TOM_RUS指出,现在最大的问题,是无法直接定位root文件,必须依靠一个MD5从海量的data文件里逐一寻找,导致加载速度奇慢无比。要想得到一份完整的文件列表,目前我们只有两种办法:暴力遍历,或者从暴雪总部偷出来。
你必须知道要提取的文件的文件名是什么,才能提取到它。目前来看,CASC不会保存文件名信息,而这正是新文件系统的设计意图。


 

精彩评论5

倒序浏览
yangdaiyang 发表于 2021-2-2 15:34:58 | 显示全部楼层
 
不知道现在9.0版本还能不能用。
 
zjqyf 发表于 2020-9-25 18:41:42 | 显示全部楼层
 
求个下载地址
 
719154500 发表于 2020-1-25 15:09:14 | 显示全部楼层
 
厉害厉害厉害厉害厉害厉害
 
爱上你的人 发表于 2016-10-11 03:49:49 | 显示全部楼层
 
小白一个 顶一下,吾爱尚玩免费服务端下载!
 
gmaster 发表于 2016-9-21 15:05:31 | 显示全部楼层
 
感谢楼主分享,吾爱尚玩,可以免费下载网单!
 
VIP介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 最佳新人

    注册账号后积极发帖的会员
  • 活跃会员

    经常参与各类话题的讨论,发帖内容较有主见
  • 热心会员

    经常帮助其他会员答疑
  • 推广达人

    积极宣传本站,为本站带来更多注册会员
  • 宣传达人

    积极宣传本站,为本站带来更多的用户访问量
  • 灌水之王

    经常在论坛发帖,且发帖量较大
  • 突出贡献

    长期对论坛的繁荣而不断努力,或多次提出建设性意见
  • 优秀版主

    活跃且尽责职守的版主
  • 荣誉管理

    曾经为论坛做出突出贡献目前已离职的版主
  • 论坛元老

    为论坛做出突出贡献的会员

0关注

5粉丝

3420帖子

排行榜
作者专栏

QQ交流群&&微信订阅号

QQ交流群

微信订阅号

吾爱尚玩资源基地永久域名:

Www.523Play.Com

在线管理员QQ:1589479632

邮箱:Email@523play.com

QQ交流群:558936238

Copyright   ©2015-2116  吾爱尚玩资源基地|523play.comPowered by©523Pplay.Com技术支持:吾爱尚玩资源基地