前言
有时候玩某个游戏觉得特别喜欢他的场景或者人物模型的时候,就像抓取下来学习使用。于是乎粗略的学习了一下模型抓取的方法,不用作任何商业用途。下面是在学习过程中的一些经验和工具。
学习论坛:
xentax论坛,关于模型解包论坛:https://forum.xentax.com/
教程集合:https://forum.xentax.com/viewtopic.php?f=29&t=22266
文件格式权威指南
大型端游
方案一(通用):有ninjaripper去抓取GPU数据,存为Ripper使用
工具:ninjaripper F10 抓取GPU数据生成Rip文件
用noesisv去读取相关的纹理和模型
或者直接用3dmax安装插件即可导入Rip文件。
优点:通用(只要经过GPU渲染数据理论上都行),抓取出来的数据贴图关系都是对应的
缺点:只能截取部分,并且冗余很多,并且目前好像不能提取骨骼和动作信息。
例子:
https://blog.csdn.net/one_six_mix/article/details/51051537/?ops_request_misc=&request_id=&biz_id=102&utm_term=%20ninja%20ripper&utm_medium=distribute.pc_search_result.none-task-blog-2\~all\~sobaiduweb~default-8-51051537
方案二:(例如Nier、Nino2等)
一般游戏资源是.CPK文件或一些其他自定义格式文件(例如.dat .dtt .g4tx .g4mg等)
(都是资源未加密的情况,加密情况另外讨论)
未加密,通用压缩方法
(经验和研究游戏文件存档):xter 论坛
1.首先解压CPK,工具:CriPakTools、CPKTool等
2.分析模型数据文件,例如dat文件 dtt文件 g4mg g4tx g4pkm g4md等
一般采用16进制工具阅读,工具:HxD、HexWorkShop、HexEdit5
一般的归档有哪些信息?
3.使用模型验证工具进行验证 例如:Hex2Obj、ModelResearcher、AMR等
ModelResearcher 发现模型顶点 面片 UV 骨骼等数据
模型相关数据(顶点数据、面数据、UVs数据、法线数据、骨骼数据、动画数据、纹理贴图等):具体跟模型文件格式相关(主流obj和fbx)
4.关联纹理特图等,一个最直接方法,直接去截取DDS文件字节流。(对应关系还需要分析) 工具:HyperRipper
5.编写python或c++dll集成到noesisv进行查看 (noesisv能够很方便的进行模型相关的浏览)
6.批量导出,可以使用Python/C#/C++(我自己熟悉的)编写脚本或者控制台程序进行文件夹/文件操作,然后用多线程或多进程进行快速导出。
方案三:从网络获取别人工具或去论坛或者网上找别人分析的文件格式,并反编译别人写的工具供研究使用(一般用.net写的工具,用ILSpy可以基本源码显示),然后再根据别人的思路自己再去研究修改,书写批量导出工具。
优点:可以很好的批量导出模型,甚至可以导出骨骼和动画
缺点:分析文件困难,需要大量积累经验和学习
学习成本:逆向文件的积累、熟悉常用模型文件格式的数据组织方式。尤其是Obj和FBX
加密或压缩或Unity
方案四:
压缩:用7z去测试压缩
加密:可以通过IDA和Ollydb去分析代码(困难) 通用找到FileMapping 然后找到相应映射
Unity:未加密可以直接用AssetStudio提取资源、
(研究中)一些资源加密,甚至程序和DLL加密 (此处需要脱壳等(破译软件的流程)) 然后进入后找到加载相关代码(基本都是汇编,只有部分可参考的C)
如果没有IL2CPP 则去看Managed中的Assebly-Csharp.Dll 如果用了Cpp则可能在Native 下的UserAssembly.dll中。(这是脚本动态库)
然后Unity有个通用的就是执行exe时会去加载Managed/Metadata/global-metadata.dat文件 如果对资源等加密 可以参考怎么处理这个文件
最常见的加密:异或运算、或者偏移异或运算等。(太复杂加密影响游戏性能)
Unity的AB文件是有特殊文件头的,是否成功可以对比。
便利:在分析以上,可以留意书写工具或脚本(一般就是python和C#)
Python:抓取数据特点文件,批量处理 (人工智能?)
noesisv 去读取 生成相应的文件并包含动作 纹理 骨骼等生成。
3dmax
手机游戏:Unity3d等一般有现成的工具
暂未研究
其他·
破解游戏(软件)可能跟提取资源有点类似
破解软件流程(猜):
然后找到程序入口,或读汇编或读什么。。
都需要使用到二进制或16进制处理工具
工具集
-
内存工具:CheatEngine 开源 github
教程:自带 和 52pj
类似WG 用内存工具去读CheatEngine
https://www.52pojie.cn/portal.php
CheatEngine 附着查看内存工具
https://www.cheatengine.org/ -
16进制查看和修改工具
HxD 查看二进制工具 https://mh-nexus.de/en/hxd/
HexWorkShop
HexEdit5 -
解压缩或解包工具
CriPakTools 解Cpk 其他资源一样 最终都是为了获得非解压或者加密文件,分析二进制获取想要的数据
https://github.com/kamikat/cpktools
CPKTool
7z.exe -
抓GPU模型数据工具
ninja ripper 在游戏运行去附着,抓显存中的数据
https://cgig.ru/ninjaripper/ -
模型研究工具
Hex2Obj
ModelResearcher
AMR
都是从2进制文件中解析资源数据 -
分析常用文件格式工具
HyperRipper 筛选纹理 (也可以自己手动操作字节流去分离)
下载:https://github.com/elbereth/DragonUnPACKer -
模型整合工具
noesisv 模型整合生成,扩展性强
下载:http://richwhitehouse.com/index.php?content=inc_projects.php -
反编译反汇编工具
IDA
ILSpy
Olleydb -
文件管理
Multicommander:http://multicommander.com/downloads mutilExCommander -
图片格式转换工具
XnView 可以很方便将图片格式进行相互转换
Nvidia的开发工具:可以将图片转为DDS格式
实例
Games:Ni no Kuni 2: Revenant Kingdom
重要数据点
模型相关数据(顶点数据、面数据、UVs数据、骨骼数据、动画数据、纹理贴图)
过程:
- 解Cpk CpkTool
- ILSpy反编译 文章中的工具NNKViewer 重新编写C#代码NewModelExtractorTool.cs
- 分析g4mg g4pkm g4md g4sk g4tx objbin 并找到他们之间隐藏的信息(难点)用到工具 HxD(阅读信息) ModelResearcher(阅读信息,查看模型,尝试数据) HyperRipper(分离纹理)
用工具生成 顶点偏移 顶点数 pad 3C-12 Float
面偏移 面数 pad 0 Short
UV偏移56 数量顶点数 pad56 Short
提取模型、贴图
自动化工具的问题
- 传入目录 √
批量解Cpk √
生成模型相关数据 从具体文件中截获数据 生成Obj √
目前数据 顶点 面 UVs 骨骼?
然后再从纹理文件中抓获DDs √
完成自动化抓取模型工具
结果 文件夹:模型 + 贴图 + 动画?
经验总结
工具使用
解压工具 7z CpkTools
2进制阅读工具 HxDSetup
贴图提取工具 HyperRipper (可以自己写Python去分离和C#)
GPU抓去工具 Ninjaripper
特殊程序 NNKViewer
ILSpy 反编译
Noesis 模型查看工具
自动化工具的书写
使用 exe 配合 python完成 (多线程+多进程+文件/文件夹操作)
BatchUnpackCpk.exe 输入目录 输出目录
批量解Cpk
ModelExtractor.exe 输入目录 输出目录 模型的obj 包括顶点、贴图、UVs
BatchUnpackTex.py 分离DDS文件
Python BatchUnpackTex.py ModelExtractor.exe 批量Cpk输出目录 输出目录
参考:
- https://www.reddit.com/r/Ni_no_Kuni/comments/88ysue/modding_ni_no_kuni_2_revenant_kingdom/
- http://forum.xentax.com/viewtopic.php?f=16&t=18088
char 1 个字节 -128 到 127 或者 0 到 255
unsigned char 1 个字节 0 到 255
signed char 1 个字节 -128 到 127
int 4 个字节 -2147483648 到 2147483647
unsigned int 4 个字节 0 到 4294967295
signed int 4 个字节 -2147483648 到 2147483647
short int 2 个字节 -32768 到 32767
unsigned short int 2 个字节 0 到 65,535
signed short int 2 个字节 -32768 到 32767
long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int 8 个字节 0 到 18,446,744,073,709,551,615
float 4 个字节 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字)
double 8 个字节 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字)
long double 16 个字节 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。
wchar_t 2 或 4 个字节 1 个宽字符