2015-09-08 11,687 ℃
前言
前面一直讲Assembly-CSharp.dll的修改,这次换个修改方式,从游戏的数据文件入手,事先声明这修改对国服无效,结算的时候会数据错误,如果有兴趣可以继续往下看
国服的那点保护
国服的Assembly-CSharp.dll跟日服不一样,做了一点处理,一开始还想用动态调试把它dump出来,结果用IDA载入后发现那段代码实在是太简单了
首先载入libmono.so,跟DLL载入有关的函数就那几个,直接跳到mono_image_open_from_data_with_name,发现他重写了一个mono_image_open_from_data_with_name_0
int __fastcall mono_image_open_from_data_with_name_0(int a1, signed int a2) { int v2; // r6@2 int v3; // r10@3 int v4; // r5@3 int v5; // r6@4 int v6; // r5@5 char v7; // t1@6 if ( a2 > 256 ) { v2 = *(_DWORD *)(a1 + 32); if ( v2 ) { v3 = v2 ^ *(_DWORD *)(a1 + 40); v4 = (v2 ^ *(_DWORD *)(a1 + 36)) + v3; *(_DWORD *)(a1 + 40) = 0; *(_DWORD *)(a1 + 36) = 0; *(_DWORD *)(a1 + 32) = 0; if ( a2 > v4 ) { v5 = v4 - 2; *(_BYTE *)(a1 + v4 - 1) ^= *(_BYTE *)(a1 + v3); if ( v3 <= v4 - 2 ) { v6 = a1 + v4; do { v7 = *(_BYTE *)(v6-- - 1); --v5; *(_BYTE *)(v6 - 1) ^= v7; } while ( v3 <= v5 ); } } } } return mono_debug_init(a1, a2); }
依旧是C#代码
byte[] bytes = File.ReadAllBytes(fileName); if (bytes.Length > 256) { uint v2 = BitConverter.ToUInt32(bytes, 32); if (v2 != 0) { uint v3 = v2 ^ BitConverter.ToUInt32(bytes, 40); uint v4 = (v2 ^ BitConverter.ToUInt32(bytes, 36)) + v3; for (int i = 32; i < 44; i++) { bytes[i] = 0; } if (bytes.Length > v4) { int v5 = (int)v4 - 2; bytes[v4 - 1] ^= bytes[v3]; if (v3 <= v4 - 2) { int v6 = (int)v4; do { byte v7 = bytes[v6-- - 1]; --v5; bytes[v6 - 1] ^= v7; } while (v3 <= v5); } } File.WriteAllBytes(fileName, bytes); } }
直接丢进Managed文件夹下跑,就能把Assembly-CSharp.dll和Assembly-CSharp-firstpass.dll解密出来了
Reflector也会坑爹
日服的Assembly-CSharp.dll对变量名做了一些处理,虽然直接上de4dot就行,但是int_0,int_1什么的看上去还是有点蛋疼。不过国服的Assembly-CSharp.dll解密之后什么混淆也没加,而且经过研究后发现日服国服加密的密钥和算法都一样,所以直接从国服的Assembly-CSharp.dll里取出AES和AES2这两个类,然后就有一个蛋疼的情况。。。
用.NET Reflector 8.5.0.179反编译AES时,里面的3个SCRAMBLE_KEY都是错误的。。。第一次尝试解密CSV的时候被坑了一下,然后发现那3个SCRAMBLE_KEY应该都是长度为21的字节数组,但是Reflector却反编译成了长度为24的数组。至于为什么我也不知道,后来用ILSpy测试倒是能够正确反编译。所以用Reflector提取后需要把3个SCRAMBLE_KEY后面的3个0都删掉
解密与修改
解密就很简单了,直接调用AES的Decode函数就行,解密后文件是Unity3D的AssetBundle文件,直接上disunity就能拿到CSV文件,CSV文件还有可能再被加一层密(国服的enemy.csv),需要再调用AES2的DecryptRJ256函数。
至于CSV就根据喜好修改就行,重点就是如何打包回去,这里讲下手动打包的办法,用到的软件还是disunity。
首先了解一下Unity3D的AssetBundle的结构
AssetBundle->AssetFile->File (CSV)
disunity本身只提供了从AssetFile打包回AssetBundle的功能,所以需要修改AssetFile,先用bundle-extract命令从AssetBundle里拿到AssetFile,一般是一个”CAB”开头的文件,然后用修改后的CSV文件替换AssetFile里的内容,以及修改一些头信息,就能打包回去了,这里以国服的enemy.csv讲一个例子(虽然并不能用
用16进制编辑器打开”CAB”开头的文件
1是大端模式的文件总大小,2小端模式的object大小,用2减去1得到0x1060就是object开始的地方,如图2,其中3是CSV文件的大小,4开始一直到后面就是CSV文件的内容了,5是用来对齐的数据
具体修改就是替换4里面的内容,然后修改3,也即是CSV的大小,然后用CSV的大小除以8根据余数修改5,规律如下
余数 1 2 3 4 5 6 7 0
补0的个数 7 6 5 4 7 6 5 4
修改完3,4,5以后,看下现在”CAB”文件的大小,然后修改1,注意是大端模式,然后把1的值减去前面算的0x1060,修改2的值。至此就修改完毕了。
最后使用disunity的bundle-inject命令打包回AssetBundle,替换手机里的文件就行了
回来考个古
虽然也结合其它文章一起仔细“看”了,但还是完全看不懂。。这个门槛好高啊
您好,请问skill_role.csv的数据怎么看的
求解~skill_role.csv解完包后的数据该怎么看 看得我一脸懵逼
你好,對於程式什麼的我也只是初心而已…遇到了一點的問題希望dalao能夠解答一下
1:如果我沒理解錯誤的話1那8個位的16進制指的就是本文件以BYTE為單位的csv文件總大小吧?而2就是以最終文件總大小減去1060.hex吧?但是我依然沒能理解到底3該咋改…求高手指點
2:補0的意思是否把0加上去令最終01-0F都塞到以8為倍數呢?
感謝
看不懂的话,现在推荐你用AssetsBundleExtractor之类的东西去修改
(接上)能不吝赐教…._(:зゝ∠)_
你好歹先做了有问题了在问啊。。。
…在第一步就因为不知道调用哪些库和输入编码而…(瀑布汗)
这是基础的东西。。。
完全不懂解密反编译之类的萌新第一次尝试_(:зゝ∠)_
理了下大概的顺序
1.用VS把 您提供的代码编译出exe 在managed下运行 解出Assembly-CSharp.dll和Assembly-CSharp-firstpass.dll
2.用ILSpy打开解压后的这两个dll 取出AES和AES2两个类 对assets/bin/data 下的csv文件调用AES的Decode函数解密,解密后文件是Unity3D的AssetBundle文件。 这一步问题是比较大的 因为我现在手头没vs 还在下 。现在用ILSpy打开不了这两个dll 提示Specified argument was out of the range of valid values. 应该是未进行第一步的原因。之后取出类 对哪里的文件调用Decode解密都是不会做的点….
3.用disunity对AssetBundle文件进行操作。得到enemy enemy_ai_order等五个文件 这点是一个基友和我说的 他拿到的就是这五个文件的excel 此时就是卡牌和副本的数据了…csv转excel我倒是会(x( 0难度好不好!)
不知道操作顺序是不是这样的orz 等vs弄好了试试_(:зゝ∠)_ 希望大神
大神看看我那里出错了,一路都成功就是打包失败
我解enemy_party.csv这个文件,用bundle-extract解出CAB-Container-enemy_party.csv,然后什么都没改用bundle-inject打包这个文件,disunity出现[info] CAB-Container-enemy_party,但没有出现打包回去的文件
lz你好 能不能求一个解密csv文件的小工具呢
因为我第一层解密就是用小工具解的,应该也是你做的小工具
你是谁?我做的小工具?我写过的工具是直接一步到位的,不懂你在说什么
因为国服第一次解密拿到的TXT是一堆英文,看不出数据
所以你能解第一次为什么不能解第二次?
大神,国服 enemy二次加密有没小工具解密的
这种东西有必要吗?。。。
你好,非常感谢你的分享。就是我在反编译以后可以看到里面的AES2类和相关的函数了,但是在用这些函数解密csv的时候解出来的csv特别不正常。因为我是对官方给的数据包里面的csv文件跑的AES2里面的decode方法,不知道这样和你文中提到的先解密拿到csv再解密csv有没有什么不同。因为才开始玩这些东西,希望可以和大神多交流交流,多学习学习,谢谢啦~
我那个是正常的解密顺序,至于你用的其他方法。。。我不懂怎么跟你说。。。
非常感谢你的回复,现在已经弄好啦~
大神求教
用ilspy打开Assembly-CSharp.dll后,Class AES里面的变数和函数名字都变乱码了
对不起没见清楚就回覆了,用了de4dot后没问题了,感谢大神发这编教学文
大神能否看一下乖离语音那个acb和awb要怎么解。。贴吧有人说基本提取不能 是真的么
看了下语音文件好像是criware的专有格式,估计转成MP3这种常见格式有难度
对 是criware什么的。我研究了一下之后 吧acb和awb解开了。。得到了hca文件。。不过用一个hca播放器播放出来刺耳的杂音(经测试这个播放器可以播放其他的awb解出来的hca或者bin文件,可以播放的话 就可以转换成wav或者mp3了),所以应该是加密了,。然后我看到dll里有CriHcaDecoder这个名字的类的,不过c#学的不是很深= =用不来这dll导入的类 不晓得这个是不是解密的
dll是Assembly-CSharp-firstpass.dll这个dll
看了下这类返回AudioClip类型,很有可能是解码类。这类调用so里的函数,你要用的话可以用mono照着写个安卓程序调用,或者逆向出so里的函数
嗯 谢谢提示 我试试看
……解了card.csv和skill.csv 只看到了技能效果,实际数据却不在这里面……
技能上是一个{1}的参数,然而不知道参数存在哪个文件里_(:з」∠)_……求解怎么看具体数据
技能详细数据在skill_role.csv里
博主的背景竟然跟我之前桌面壁纸一样呢。。搜索csv解密 搜到这里,自己本来就是学软件的。就在折腾这个,但是想问一下博主 载入so文件是怎么个载入法?
用IDA载入SO文件,具体你可以百度一下
先要谢谢博主~已经解密成功啦。一切问题都和博主说的一样,R工具会多的几个0也是。不过我这边的dll倒是不用解密,直接用R工具或者ILSpy打开就能看到完整的代码,拿出来就能用。
感谢,刚被你拯救过的第一次尝试解包的咸鱼,C#都不会用,我愧对我的专业,愧对我的学校
博主,推荐个游戏给你
御姬之翼
也是UNITY3D的游戏,不过是香港制作,目前有港服台服DMM服3个服务器。并且开放了网页版和手机版数据通用。
游戏模式是MA那种。
已开服2年,目前貌似只有我一个人在做修改和辅助,很累啊。
有时间和兴趣的话,期待一起讨论这个游戏。我在百度御姬之翼吧ID叫kensougo
感谢你的推荐,不过我暂时不会去玩更多的新手游了
请问一下…
路径”files\patch1_Character_Assets\enemy\ems_001\camera”下的文件是没有加密的…
用disunity解不出东西…用记事本打开是UnityRaw开头的
知道这些是什么文件吗?解不出来强迫症要犯了…
谢谢!
UnityRaw开头的是未压缩的AssetBundle文件
disunity只能提取打包在AssetBundle(AssetFile)里的
AudioClip (.mp3)
Font (.ttf)
Mesh
TextAsset (.txt)
Shader
Texture2D
Cubemap
SubstanceArchive
MovieTexture
这9种文件
你那个文件夹下的,比如cm_0010_entry这个文件,里面打包的是AnimationClip,MonoScript,AssetBundle这3种类型的文件
disunity都不支持,所以提取不出来
谢谢!
非常感谢大触的教程!
虽然第一次用C#但还是解出来了
这下子可以整理更多数据了!(强迫症的我