喵宅苑 MewoGarden × 技术宅社区II | Z站 Z Station 来喵宅苑,有可爱的男孩子

正文

想成为一名破解者吗?

作者:kesaan
想成为一名破解者吗? Part I: 所需技能与相应责任 (译者按: Part I的开始前想先提一下insani文章的风格.他们在系列文章的开篇总会提到"责任"问题.这部分打算按照原文翻译,但并不代表译者完全认同其观点.这部分的翻译之后,也会附上一段Susie的简单使用介绍.另外对"hacker"一词翻译为了"破解者",因为译者认为实际上文章所描述的工作与其说是hack还不如说是crack.) "我想翻译游戏,但是我一点日语都不懂." 如果每次听到这种话我都用一个字节来记录的话,我可以换掉我的硬盘了... 所幸的是,在做翻译之外还有一条路——这与[捣弄假名然后为代词都跑哪去了而疑惑]需要的是完全不同的一套技能.然而这项工作与翻译同等重要.试想没有你提供的脚本的话,一个翻译能对着什么翻译? 没有你提取出的图像,一个改图者能改什么图? 没有你重新组装好的游戏,一个玩家能玩什么游戏? 所以,问题就变成了,"想成为一名破解者吗?" 或者,抓住要点来说,你拥有破解游戏所需要的技能吗? 破解者(或者程序员,或者技术指导,或者随便怎么称呼)在翻译过程中的早期阶段有着重要的职责.最优先的就是找出提取游戏数据的方法,具体来说就是脚本和图像.这样小组的其他成员才能开始工作.其次,他必须找到把修改过的数据重新放入游戏中而不出错的方法.最后也是最麻烦的,他经常须要修改游戏本身的方法来让游戏正确使用修改过的资源(例如,将游戏的文本引擎改为使用半角英语字符,或者实现日语游戏所不需要的自动换行功能) (译者按: 对于中文化工作者来说,这些例子的对应版本就会是修改字体的参数来让汉字编码得以正确显示,或者修改边界值来逃过字符集的边界检查等.上面提到的自动换行原文是word-wrapping,关键在于自动换行时要考虑到单词的完整性.) 提取过程有时候很简单,因为在对H CG的不懈追求中,可能已经有其他破解者写好了从游戏提取图像的工具.相比之下,再插入工具则甚为罕见;你几乎总是得自己来写,除非你处理的游戏与其他的翻译小组以前处理过的使用了相同的游戏引擎.就算顺利提取出了脚本,在把脚本交给翻译前,你得先想清楚他会返回些什么东西...你能把脚本自动再插入,还是得自己手动复制粘贴 一·行·行·的 脚本呢? 有一点我要明确一下,我不会单纯为了盗版而讨论破解防拷贝技术.这里所讨论的破解纯粹是为了翻译自由发行游戏,或者是为已经购买了完整的日语版游戏的人制作英语补丁. (译者按: 这点翻译得相当无奈.在一些客观条件的限制下,玩家的需求与条件的限制之间的矛盾,促使越来越多的中文化工作组出现和成长.相信多数的非官方中文化工作者,在中文化一部游戏作品的时候,并不是站在侵犯任何组织或个人的权益的出发点上的.相反,这是在得不到有效的官方代理的条件下,为了推广自己喜欢作品而尽的努力.在可能的范围内,中文化工作者都应该尽量少涉及与作品原作者权益相背的范围.但是许多时候实在是事出无奈...嗯,这个问题就此打住了.Ed的观点译者在此只能理解却无法认同了.) 你需要已经具备哪些知识呢?如果你在考虑这个问题,我希望你懂得一定的编程,因为那个我教了你.好在,你并不会经常需要[大量]编程...只要些基本工具就够用了,越底层越好:你连如何在Windows中制作一个单选按钮都不需要知道,但是你得知道区分big与little-endian.这个,我教会你. 来想想所以你懂得的程序设计语言.把不能轻松完成如在文件与未处理的字节数组间读写之类的一些底层操作的语言扔掉.用你觉得最顺手的语言,或者也可以尝试点新东西.个人而言,我主要直接用C,不过如果我得从头再做一次的话,我可能会仔细考虑一下,比如说,Python,Java,C++,或者其它好用常用的语言.不过如果你最喜欢的语言是Visual Basic的话...我觉得你是时候扩展一下你的技能了. (译者按: 嗯,这部分译这也想说点.在中文化游戏的过程中,破解者自己所写的程序多数只是自己临时使用的,所以就算慢一点或者代码乱一点问题也不大.在语言的选择范围上也就有相当大的余地.如Ed所说,用什么语言其实是自己的习惯,并不一定要专门另外去学一门困难的语言的.然而如果完全不懂得编程的话而又想加入到中文化工作的程序破解方面中,如果不学习哪怕一点点的编程知识,会带来比较大的限制. 对于有C或者语法与C类似的(例如C++,Java,C#)语言基础的人而言,安心继续使用你觉得顺手的就可以了.熟悉JavaScript或者Flash ActionScript的,在破解时也可以考虑转向Java或者C#,语法比较相似.haeleth喜欢用CAML,ML的一种变体,那个也是相当方便的语言. 如果是完全没接触过编程的,译者推荐Python或者Perl,或者其他功能强大的脚本语言.相对于较底层的C/C++来说,这两种脚本语言都既有足够能力完成工作,又不会让你为底层操太多心. 请不必在"比较编程语言"这个环节上浪费太多时间.不考虑实际使用背景就比较语言毫无意义.在破解工作中能用得顺手,时刻让自己保持清醒的头脑才是最重要的.速度之类的重要性并不优先. 汇编的话,并不一定需要掌握.只是,掌握多少知识在破解上就能做到多少程度.许多时候并不需要做到很深的程度就能完成破解任务了...至少,一部分吧 XD 学习程序设计语言时,一开始要注意的是一些基本概念,如执行流的控制等;又例如面向对象语言里的"对象"等.只要在一门语言上清楚掌握了这些概念,就会发现在其他语言里其实都是一样的,只是具体写法可能不同. 过程化概念: 变量,以及变量的声明 语句,以及语句块 表达式与操作符 执行流控制,例如循环,分支,跳转等 函数的声明和调用 函数的重载 面向对象概念: 对象的概念 成员变量/方法与类变量/方法的区别 类的继承 ... 基本上就是这么些概念了. 推荐书籍: C++: C++ Primer, Effective C++ Java: Core Java 7th Edition C#: C# Bible Perl: Programming Perl(编程珠玑) Python: 完了我不记得Python我看的是什么了...=_= ) 最重要的是,你得有解决问题的意识.你将着手的任务是谜题,而且它们并不会像你的计算机科学教授特意设计的题目一样,能正好用上这个星期的课教的内容以一页纸或不到的代码就解决.正好相反,你在与原作的日本程序员作战,而他们或许根本不在乎他们数据格式是否能被逆向工程所破解——如果他们在乎的话,他们大概更是会特地把数据加密来让你的工作更难进行吧! 好了,卷起你的袖子,启动你的编译器,戴上你的"思维帽".在这个系列的文章中,我们会把一些范例游戏的攻破过程完整走一遍.希望你能看出自己是否适合破解者的角色...同时也学会几招道中小技巧吧! (译者按: Part I结束.上面提到了从游戏中提取图像资源的问题.嗯,也不排除有就是为了CG或者BGM而想加入到破解行列的读者.如果目的只是到这一步而已,那系列的后续文章基本上不看也可以,只要掌握一个基础工具就能够应付非常多的游戏了.这个工具就是Susie. Susie简介: Susie是一款在Windows上用于图像浏览的免费软件.凭借其良好的可扩展性,它不但可以用于浏览图片,在加上相应插件后也可以用于归档文件的资源提取,或者文件格式转换之类,因此在日本十分流行.所谓"有其他破解者写好了提取工具"很多时候就是以Susie插件(后缀为spi, spi=Susie plug-in)形式发布的. 官网: 「Susieの部屋」 http://www.digitalpad.co.jp/~takechin/ 在此可以找到Susie的本体. 澄空学园CK-GAL区里的工具交流帖里有Susie本体以及相关插件包可以下载: http://bbs.sumisora.org/read.php?tid=207722 此外如果需要给Susie寻找新插件,直接在搜索引擎上输入你希望提取资源的游戏名,加上"Susie""plug-in"等关键字就可以了.非常的多... Susie简单使用说明: 首先,Susie是绿色软件,安装简单.使用归档管理软件(WinRAR,WinZIP,7-zip等都可以)将susie347b.lzh解压到任意目录即可. 本体解压完成后,将插件也解压到Susie的安装目录下.Susie在不安装任何插件的时候能做的事情并不多,所以在试图提取什么资源前务必确认是否已经正确安装好相应的插件. 要运行,如果不是在J-Windows或者当前语言区域在日语下的话,请使用AppLocale来引导Susie以日语启动;否则可以直接启动Susie.exe. 启动后会见到一个工具条: 点击「開」.会看到下面的文件选择界面: 选择需要打开的文件即可.如果打开的文件是归档文件,那么可以直接从打开后的文件窗口里把需要的文件拖放到目标目录. 上面的文件选择界面里有"Catalog"选项,点击则会进入浏览/预览模式. 简单的拆档使用就这么简单.其他一些设置请查看susie.chm吧~ 如果不介意使用付费工具的话,其实WESTSIDE对大量游戏都制作了资源提取器.当然其中不少也是Susie插件. 详细请见其官网, http://www.westside.co.jp/index.html 这个汉化技术区里的工具帖里还有不少其他工具,也很值得一看.)
想成为一名破解者吗? Part II: 十六进制编辑器 (译者按: Part II介绍的有两部分,其一是资源文件的常见形式,另一部分是在探究一个未知的资源格式时最可靠的伴——十六进制编辑器.在这部分的翻译开始前,译者希望能为缺少编程与计算机相关知识的读者先做些背景资料介绍.同时,在翻译过程中也会适当加入一些内容. 译者先前也写了点资源格式相关的文字,灯穂奇譚的文件格式以ef - the first tale. / Trial Version中资源文件的加密的解析简单介绍几个工具中的[准备工作1]部分) (译者按: 背景知识介绍: 首先,数字的进制问题. 所谓"进制问题",小学生也应该知道"逢X进一"的就是X进制,所以也不需要多说...这里特地提到,是因为计算机所使用的进制与我们日常生活中习惯的十进制不同.这里要说的,是二进制和十六进制. 二进制,逢二进一,每位可以是0-1两个状态. 十六进制,逢十六进一,每位可以是0-9,A-F共十六个状态.下面十六进制数字都使用0x为前缀表示.没有0x前缀的则是普通的十进制数字. 不同进制间的换算就不用说了吧...不过2的补码(2's complement)需要说说. 计算机里常使用所谓"2的补码"的形式来表达带符号的二进制数字.比起单独消耗掉一位来记录正负使0有两个,2的补码完整的利用了整个n位二进制数[-2^(n-1),2^(n-1)-1]范围内的所有数字.其值的计算方式是: -2^(n-1)*最高位+2^(n-2)&*次高位+...+2^0*最低位. 非负的2的补码的二进制数与直接从十进制换算到二进制的一样,不过首位必须要为0. 负的2的补码的二进制数是通过"取补"(complement)操作完成的.先得到数字的绝对值的原码,也就是直接从十进制换算到二进制的数;然后对每一位都"取反"(NOT),0变为1,1变为0,这样就得到了"反码";将反码加1,得到"补码". 对2的补码形式表达的二进制数,加法直接进行;减法转换为加上减数的补码;补码的计算就是"取反加一",其作用就是取得原数的相反数(绝对值相等,符号相反). 当前主流的计算机使用的电子元件都只能支持两个状态间的切换,"开"或者"关".因而使用二进制数字来描述计算机上储存的数据非常合适.但是二进制数字写起来还是显示起来都很冗长,为了方便起见,使用2的4次幂=16为底的十六进制来作为二进制数据的简写表达形式.所以,在查看二进制文件时,一般使用的是十六进制编辑器.高级语言像是C++和Java里一般也只允许以八进制或者十六进制作为简写形式来表达二进制数据. 用十六进制来表达二进制数字的方法: 将原二进制数字以4位为一组,分别换算为十六进制的对应数字作为一个十六进制位.最靠左的一组二进制数字不足四位的在前面补零.这样,一个字节是8个二进制位,用十六进制表达就是2个十六进制位. 然后,"文件"相关. 在计算机上,一个"文件"是在次级存储器(如磁盘,磁片,磁带,光盘等)上储存数据所使用的基本结构.在面向对象程序设计里,文件是一种用于描述次级存储器与内存之间数据传输的软件对象.本段的讨论范围并不涉及"管道文件""设备文件"之类的特殊文件,请注意区别.普通的文件,可以分为文本文件和二进制文件两种.其中, 文本文件是能被人直接阅读的文件.一个文本文件里的数据由一串字符所组成.字符都是按照一定的文字编码所表示的,例如ASCII或者UNICODE.可以直接以文本编辑器打开并阅读/编辑.举例的话,一个整数12345,保存到文本文件之后,就变成了"1""2""3""4""5"这五个字符. 二进制文件是文本文件以外的文件.这种文件更加简洁高效,但是其数据通常是不满足文字编码的一串0和1,不能直接被人阅读.举例的话,同样是整数12345,保存到二进制文件之后,就变成了0x00 0x00 0x30 0x39这4个字节的二进制数据. Archive,意思是存档,档案文件.本文内将其称为"归档".这个名词应该并不陌生,因为电脑的日常使用中也经常会用到rar,zip,tar,tar.gz,7z等格式的归档文件.游戏多数都不会将其使用的资源直接分散放在游戏的安装目录下,而会将他们"归档"到归档文件里.这样就能够使文件结构更加清晰,而且也可以在一定程度上节省空间,一是归档的时候可能有压缩,二是大量小文件浪费空间的问题被解决了.因而,通常情况下,要提取资源,首要破解目标就是游戏所采用归档的格式. 游戏有可能使用同样的归档文件格式对其所有类型的资源进行归档,也可能对不同类型的资源采取不同的归档格式,也有可能有选择性的归档.即使放入了归档文件,其中的资源也有可能被有选择性的压缩或加密过. 另外,还得提一下字节顺序的问题. 当一种数据需要多于一个字节来表达时,就牵涉到字节的顺序问题.可以认为从前向后读,首先读到的是最高位的,称为big-endian序;也可以认为最后读到的是最高位的,称为little-endian序.例如说,如果要读入一个32位的整型数,读入的数据是0x61 0x62 0x63 0x64的话,按big-endian读是0x61626364,而按little-endian读是0x64636261.同样的数据如果解释为ASCII编码的字符的话,无论采用什么字节顺序读都是"abcd"(也就是0x61 0x62 0x63 0x64对应的ASCII字符),因为ASCII字符只占一个字节(8位),而字节序只影响同一数据内的字节排列顺序而不影响数据间的顺序或者字节内位的顺序. 在Mac的PowerPC上,数据一般以big-endian顺序储存.而在我们常用的x86兼容的PC机上,数据一般以little-endian顺序储存.请留意. 呵呵,正篇开始前似乎废话太多呢.好了,开始翻译了.) 那么让我们开始吧.今天我们会看看一个简单的范例归档格式,作为讨论一个"标准的"游戏数据文件的各部分的跳板.把这种模板记在心里,尝试理解游戏数据文件里看似无规律的字节时就会轻松不少. 这次我们作为范例的游戏是Cross+Channel(体验版的下载链接在该页末尾).这个游戏已经有一个翻译计划正在进行中.喜欢的话下载一份体验版,然后我们来看看. (译者按: 嗯,原文里提到的翻译计划自然是英文化的翻译计划.现在其实也有中文化计划正在进行中.到时候或许就能见到成果了吧 ^ ^) 游戏安装后,安装目录下除了可执行文件之类以外,我们还能看到几个文件:bgm.pd, cg.pd, script.pd, se.pd, 还有voice.pd.这非常典型: 多数游戏不会让每个音频文件和图像文件独立放在外面,而会把它们集合起来放在几个归档文件里,然后游戏引擎就可以随机访问它们了.把原始的独立文件从归档文件中分离提取出来是攻破游戏的第一步. 现在就该启动破解者最喜欢的工具,十六进制编辑器.这是一类相对简单的工具软件,只是显示文件的原始字节及对应地址...常见的高级功能包括将数据解释为常见数据形式(整数或者浮点数,之类),比较文件,还有搜索特定数据模式等.我个人习惯用Mac上的工具,HexEdit.如果你有喜欢的Windows或者Linux上的十六进制编辑器的话,可以在回复的时候提及,让其他读者也留意一下. (更新: 至今提及的推荐的工具,在Windows上有WinHex,HView,XVI32,Hex Workshop,和文本/十六进制混合编辑器UltraEdit-32.Unix系的操作系统上有HexCurse.谢谢!) (译者按: 十六进制编辑器最基本的显示部分有两个: 一是以十六进制方式显示的原始的字节数据,每一个字节表示为两个十六进制位,并且每个字节之间会稍微分开一点;二是于前者相对应的以ASCII(或其他编码)方式解释的数据.有了对应的这个解释部分,我们就可以轻松的看出是否存在有明文存在的文本/标记. 译者想重点介绍一下WinHex.它是不但可以打开一般文件,还可以像打开文件一样打开正在运行中的进程的内存,同时还有别的一些方便的工具,像是计算器,十进制与十六进制转换器,磁盘编辑器等... 例如说,在Data Interpreter窗口里,可以直接读出光标当前位置之后(包括当前位置)的8位,16位和32位数据(以little-endian字节序解释)的十进制值,非常方便.) 那这些后缀为pd的文件看起来是什么样的呢? 下图是cg.pd的开头部分,我们可以肯定的猜测这个文件存有游戏的图像文件. 好极了,来看看: 可以辨认的文件名! (如bgcc0000e.png) 如果你看到的是类似这样的东西,而不是一些看似随机的字节,你应该庆幸.虽然你可能还不知道这些数据到底代表着什么,很明显能看到继续解释这些数据的前路. 为了更好的解释我们看到的数据是什么,是时候来简单介绍一下典型的游戏归档的内容了. - 1. 文件头 文件头里包含的是关于整个文件的一般信息.并不是必须的.不过如果在一个归档文件的开头就看到一串不像是文件名的字符串的话,多半就是有文件头的了. -- 1. 特征标记(signature) 通常一个归档文件都会以某种特征标记字符串开头,好让程序能辨认出归档的格式和版本.你可以通过这个标记来确认当前处理的文件是否属于正确的类型. -- 2. 索引位置 大多数情况下,紧接着特征标记就会是归档内的内容索引了.不过有时候索引实际上位于归档的末尾,毕竟归档打包程序要等到归档内的内容都处理完了才会知道索引有多大(例如说内容索引本身就被压缩过的情况).如果是那样的话,会有一个指向索引所在位置的指针. - 2.内容索引 归档内容的索引是你需要掌握的重要结构,因为你要通过它才能知道如何提取出归档里的文件. -- 1. 索引大小 索引一般会以一个表示大小的值开始.很多时候这个值就是归档所包含的文件数量,也可能是索引所占的字节数.不过索引大小并不一定存在,因为有时候内容索引会一直延续直到遇到一个特殊的结束记录(例如说,包含负的文件大小或者空的文件名的记录,等等). -- 2. 文件记录的列表 接下来会是归档内所包含的每个独立文件的记录的列表.这可以是定长或者变长的数据结构,取决于文件名是如何处理的.有时候还会有表示目录树装结构的路径层次结构.每个记录有含有一定数量的标准信息: 1. 文件名/文件路径: 可能是以0x00结尾的字符串,若不是也可能明确给出了字符串的长度.信不信由你,文件名其实不是必需的.我至少遇到过一个例子,只保存了文件名的哈希值. 2. 起始位置: 这会是一个相对某个位置的偏移量,通常是一个32位的整数.这"某个位置"可以是归档文件的开始,可以是内容索引的开始,或者有时候是"文件区"的开始(就是说,归档内第一个文件的起始地址,也可以说是内容索引的结束之后). 3. 文件大小: 文件的在归档内所占的空间大小,或者是文件的原始大小,通常是32位的整数.当文件在归档内所占空间与其原始大小相等时,文件大小要么有一个,要么干脆就省略掉了,因为可以从下一个文件的起始位置来计算出文件的大小;不相等时,通常说明文件被压缩过.则压缩后所占空间与原始大小都需要在内容索引里记录下来. 4. 标志位: 标明文件是否被压缩过,有的话用了何种算法;或者是否被加密过,有的话是否有相应的密钥或者初始值等. 5. 校验和(checksum): 为确保数据的完整性,有时候会记录下文件的校验和.这对破解者来说可能有点烦,因为这意味着修改归档的内容后我们还得把校验算法也跟出来,才能计算出修改过的新数据的正确校验和(不然想办法禁止掉可执行文件里的校验检查也可以). 注意: 有时候这些信息可能会分散在不同位置.例如说,文件的起始位置与文件名放在了索引的记录里,而文件大小和相关的一些标志位却在那个起始位置给出,紧接着的就是相应的原始文件. - 3.原始文件 原始文件的数据基本上就是头尾相接的放置在归档文件里了.这些数据有可能被压缩过也有可能被加密过.游戏引擎可以通过索引快速的定位到这些数据,因而可以任意使用它需要的文件数据. 好吧,了解了这个标准模板后,让我们来看看它能如何解释cg.pd里的数据.最开始的PackOnly看起来像是个特征标记.接下来是一串0x00字节,直到我们来到地址0x40,在一串可辨认的ASCII字符串之前有这么一组数据: 0x21 0x02 0x00 0x00 0x00 0x00 0x00 0x00. 这会是内容索引的大小吗? 说起来,我们应该如何解释这几个字节呢? 我们有几种选择: ·随机的标志位. 这里可以看成3个位被置位(set)了: 第一个字节中的0x20和0x01,以及第二个字节中的0x02.(注意这里最好转换到二进制观察每一位的值,是置位(set)还是清零(clear).例如0x21=00100001=0x20 AND 0x01.)这么解释算是有点道理,不过暂时没什么价值.看看其他可能吧. ·little-endian整数. 这里,0x21是最低字节,0x02是次低字节,依此类推.所以这个整数的实际数值是0x0000000000000221,十进制就是545.这可能是一个合理的索引大小值. ·big-endian整数. 按这种字节序的话,0x21是最高字节,0x02是次高字节,依此类推,整数值是0x21020000,也就是十进制的553,779,200(这已经是忽略了后面那4个0x00了).这个数据比较不合理,因为整个归档文件才不到500MB.所以如果想以big-endian方式来解释的话,得换个长度,例如说这可能是个16位的整数: 0x2102= 8450,这个值或许有可能,例如说是索引数组的字节数之类. 让我们来具体看看.从归档文件的开头开始看下来,似乎文件名是在0x48,0xD8,0x168,0x1F8,0x288等位置开始的.也就是说每个文件名的开始到下个文件名的开始之间有0x90 = 144字节.最后一个文件名(TCYM0005c.png)是在0x13248开始的,说明大概有(0x13248-0x00048)/0x90 + 1 = 545个文件记录. 你看到了什么了么? 没错,就是545! 以little-endian方式来解释0x21 0x02 0x00 0x00 0x00 0x00 0x00 0x00应该正确的告诉了我们在内容索引里有多少条记录.而且更重要的是,现在我们就可以专注于那些144字节的数据,确信这些就是一个个的索引记录.而且,我们知道这个归档青睐little-endian字节序,也可能使用8字节(64位)的整数. 那就让我们来看看这些索引记录.不过(这里有个小技巧了)不要看第一个记录.很多数据在第一个记录里都有可能是零,我们就看不出数据的意义了.来看看第二条记录吧,在地址0xD8到0x167: 我们看到了一个文件名,一堆零,和看起来像是8字节的little-endian整数.回忆一下典型游戏归档的模板...我们在寻找的是文件大小和位置的信息,或许还有一些标志位之类.那堆0x00可能会是标志位,不过现在还没办法确定. 眼下先假设那些零是文件名所属的数据结构的一部分: 这样就刚好给文件名分配了128个字节,是一个(懒惰的?)程序员会做的合理的事情.剩下的信息是两个整数,0x002420FA和0x0008370E.暂时还不知道这些是什么数据...还是先多看几个记录吧.内容索引的头几条记录里对应位置的数据是什么样的呢? File 1 0x00240048 0x000020B2 File 2 0x002420FA 0x0008370E File 3 0x002C5808 0x00002FA6 File 4 0x002C870E 0x00063B8A File 5 0x0032C338 0x0006A7CB 现在这些数据有点看头了.第一列数据总是越来越大,更重要的是它们总是以第二列的值增大! 这正是经典的位置+文件大小的进行. 如果我们的假设是正确的,那么第一个文件,bgcc0000e.png,应该有0x000020B2 = 8370字节这么长,而且应该在归档内的地址0x00240048附近开始.我们不能完全肯定,因为不知道这个偏移量是相对归档文件开头还是特征标记后还是哪里,而且这个值有点诡异,因为我们知道内容索引是在0x000132D7结束的,还记得吗? 总之先到那个地址去看看吧,因为文件的顺序可能被打乱了 爽! 我们猜得完全正确,地址0x00240048正是一个PNG文件的开头.无压缩,无加密.事实上,要是我们从这个地址开始把接下来的8370字节复制粘贴到一个新文件里(当然也是在十六进制编辑器里),然后用图像浏览器打开的话,我们就得到了...一张640×480的空白白色图. 呃.无论如何,游戏也是需要纯白图的,至少这图的尺寸没错.那么为保险起见,再试试下一张图片.从地址0x002420FA开始复制出0x0008370E个字节,我们得到的是: 好耶! 胜利是属于我们的! 现在让我们来总结一下.我们在这个阶段,认为.PD格式包括: 特征标记字符串"PackOnly" 56字节的0x00 8字节little-endian的文件数量值 多个144字节的索引记录,每个包括: 128字节的文件名,是以0x00表示结束的字符串 8字节little-endian的文件位置(从归档文件开头算起的偏移量) 8字节little-endian的文件大小 最后是原始文件数据,无压缩无加密,正好在索引里给出的位置上开始. 那么,内容索引之后到第一个原始文件之间的这段空白(全是0x00)该如何解释呢? 其实,那个地址,0x00240048看起来很可疑...一个索引记录是在0x48,也就是说有0x240000字节的空间可用于放置索引记录.每个记录144字节的话,就能装下16384个记录.也就是2^14.所以让我觉得这很像是一个(懒惰的?)程序员会做的事: 留下足够多的空间给大量的文件用就算了. 那这段空白是否必要呢? 说不定我们在重新打包归档的时候可以把这段空白清除掉,省下那么几兆空间.要不然我们把数据移动超过1个字节程序也会崩溃...我们只能等后面实践的时候才知道了. 好了,下次就让我们把获取到的知识转换成实际的程序代码吧.当然,我们会遇到些障碍,嘿嘿 (译者按: Part II结束.这个part所讲解的例子是一个非常简单,无加密无压缩的归档文件的格式分析. 简单说来,如果被分析的归档文件比较典型且无加密无压缩,那么就按照典型的游戏归档的形式,找到内容索引后,猜测索引内每个数值的意义,并且到归档内猜测的位置寻找原始文件. 译者的经验是,如果一开始就以脚本文件为目标的话,过程会比较痛苦.因为脚本文件经常是纯文本文件或者一些特制的格式,不一定有明确的起始标示,不便于确定是否正确定位到了原始文件的位置.所以,可以尝试对估计含有图像的或者音频的归档文件下手,就像本篇的例子以CG归档为破解对象. 为什么要针对图象,音频和视频下手呢? 因为业界在许多时候都会使用标准的格式来储存图像,音频和视频文件. 下面列举几种常见的文件格式,以[格式名]: [特征标识串]表示 图像: BMP: 0x41 0x4D (BM) PNG: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A (.PNG....) GIF: 0x47 0x49 0x46 0x38 0x37 0x61 (GIF87a) 或 0x47 0x49 0x46 0x38 0x39 0x61 (GIF89a) JPEG: 0xFF 0xD8 0xFF 0xE0 0xxx 0xxx 0x4A 0x46 ( . ...JF) 0x49 0x46 0x00 (IF.) 音频: OGG: 0x4F 0x67 0x67 0x53 ("OggS") WAV: 0x52 0x49 0x46 0x46 0xxx 0xxx 0xxx 0xxx (RIFF....) 0x57 0x41 0x56 0x45 0x66 0x6D 0x74 0x20 (WAVEfmt ) 视频: MPEG: 0x00 0x00 0x01 0xBx AVI: 0x52 0x49 0x46 0x46 0xxx 0xxx 0xxx 0xxx (RIFF....) 0x41 0x56 0x49 0x20 0x4C 0x49 0x53 0x54 (AVI LIST) 在找到这些特征标识串后,我们就能轻松确定 1)是否存在某类型文件 2)文件的起始位置 从而可以与文件头里的信息进行对比,判断数据的意义,然后推广到游戏中同格式的其他归档的处理(例如含有脚本的归档) 更多更详细的文件特征标识串,可以在这里查询: http://www.garykessler.net/library/file_sigs.html Part II里举的例子"太过典型",让我们来看看可能发生什么简单的变化吧.同样是无加密无压缩的归档,灯穂奇譚里的AOD格式的归档虽然也有内容索引,但却被分成了一段段.详细请看灯穂奇譚的文件格式. 另外,区里另一篇帖子的例子更加有趣.ONE ~輝く季節へ FullVoice 汉化实战篇,其中的归档与其索引是分开在不同文件里的.再次提醒我们索引的必要性以及可能需要变通的地方. 不得不注意到,并不是所有游戏都会把资源都放入归档内的. 举个例子来说,Visual Art's旗下制作组所使用的RealLive,会使用GAMEEXE.INI文件来配置是否使用归档.其中相关的一段: Quote:
#FOLDNAME.TXT = "DAT" = 1 : "SEEN.TXT" #FOLDNAME.DAT = "DAT" = 0 : "DAT.PAK" #FOLDNAME.ANM = "ANM" = 0 : "ANM.PAK" #FOLDNAME.ARD = "ARD" = 0 : "ARD.PAK" #FOLDNAME.HIK = "HIK" = 0 : "HIK.PAK" #FOLDNAME.PDT = "PDT" = 0 : "PDT.PAK" #FOLDNAME.G00 = "G00" = 0 : "G00.PAK" #FOLDNAME.M00 = "M00" = 0 : "M00.PAK" #FOLDNAME.WAV = "WAV" = 0 : "WAV.PAK" #FOLDNAME.BGM = "BGM" = 0 : "BGM.PAK" #FOLDNAME.KOE = "KOE" = 1 : "" #FOLDNAME.MOV = "MOV" = 0 : "MOV.PAK" #FOLDNAME.GAN = "GAN" = 0 : "GAN.PAK"
中间的数字就是说明是否使用归档的,是的话值为1,否的话值为0.这个还要与后面的文件名相配合,即使前面的值为1,假如后面的文件名为空串的话,也不使用归档,而是直接把一个个资源文件独立放置在安装目录下.上面这段引用自智代After的GAMEEXE.INI,可以看到只有脚本资源被放进了归档里,文件是SEEN.TXT.把这个归档文件拆开,就能看到里面实际上是许多小文件,SEEN0628.TXT到SEEN9072.TXT.而这些小文件又是编译过的脚本. 就算是放进了归档里的资源,要分析其内容索引也不总是这么轻松.假如说有数据被加密或压缩过,情况就会相对复杂一些. 也举个简单的例子吧.呵呵这个可是运气/RP大爆发的例子... 在はるのあしおと的web_trial里,归档文件的后缀是paz,都被简单加密过.要使用上面的经验来处理加密过的归档显然不实际,至少也得先解决解密问题.怎么办呢? 由于业界经常在音频格式上选择使用Ogg Vorbis,而且在游戏的安装目录下发现了"ogg.dll"和"vorbis.dll"这两个用于处理Ogg Vorbis文件的程序.所以我们大胆猜测bgm.paz里包含的背景音乐文件是采用Ogg Vorbis格式的,并由其入手. 用十六进制编辑器打开bgm.paz,发现里面都是些无法识别的数据.从头到尾浏览过之后没有发现形似文件头或者内容索引的东西.因此猜测文件被加密过. 上面说明文件的特征标识串时提到了,Ogg格式的文件是以0x4F 0x67 0x67 0x53 ("OggS")开头的,注意到中间有连续两个字节的值是一样的.如果运气好,文件只是被简单的加密过的话,那么加密后的密文里这两个字节的对应位置的值也应该是一样的;同理,拥有相同值的连续两个字节,其之前和之后的字节的值应该不同.根据这条线索,让我们来找找文件中有符合这个特征的地方. 很快我们就注意到了这个地方.红色标记出来的部分就是我们找到的一组符合线索的数据,0xB1 0x99 0x99 0xAD.先看看0x67可以如何对应到0x99上.还记得本篇开始时背景知识里提到的2的补码吗?把0x67和0x99分别展开,可以看到它们正是符合互为补码的关系.将头尾两个字节也对比一下,发现符合相同的关系.于是可以大胆猜测,整个文件都是以取补码的方式简单加密过的(虽然这个猜测不完全对...嘿嘿不过还是很RP吧...). 于是把想法实践一下,发现简单解密处理处理过后的文件已经相当的可读了.这样就可以继续按照典型的游戏归档文件的处理方法来处理了. 注意到,这里bgm.paz的头4个字节我并没有做取补处理.原因见以ef - the first tale. / Trial Version中资源文件的加密的解析简单介绍几个工具中的[准备工作1]部分所写的内容,这里就不重复写了. 虽然通过简单的观察就能破解出归档格式是很RP的事,不过游戏厂商在决定使用什么加密/压缩方式时本来也很RP -- XD 简单观察法适用于无加密无压缩,或者只做了简单加密的归档.简单的加密方法有: 1)加上或减去一个常量; 2)取反(NOT)或者取补(complement/negate); 3)与常量做简单的异或(XOR).如果是上述的3种情况,那么加密后的密文里字节与字节间的相等/不等关系会得以维持,因而可以让简单观察法顺利进行. 再举个例子的话...嗯,CIRCUS虽然一直不怎么用归档,不过它的游戏的脚本文件(后缀MES)对文本部分加了密,用的就是加上常量的方式,所以很容易由观察得出. )
打击蛮大的,继续转吧写的蛮累的。。。。。讲究看吧

回复

0%
站点地图友情链接:
喵宅苑
喵空间社区程序
喵宅苑 静态版
宅喵RPG地图编辑器
络合兔
喵宅苑预览版
Lanzainc
技术宅
小五四博客
莉可POI
Mithril.js
枫の主题社
Project1
午后少年
机智库
七濑胡桃
xiuno
幻想の日常
魂研社
Nothentai
0xffff
欲望之花
泽泽社长
淀粉月刊
HAYOU
红客联盟
异次元
轻之国度
神奇宝贝新生代
游戏狗
口袋双子星
我的世界论坛
梦次元
动漫东东
动漫国际
精艺论坛
78动漫
吐槽弹幕网
漫客栈
nexmoe