某游戏的Assembly-CSharp.dll加密

本文讲述了作者通过逆向工程分析,发现游戏加密的Assembly-CSharp.dll在Mono的加载过程中被inlinehook和VM处理。通过内存读取和文件保存技术,成功获取了未加密的源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天一朋友和我说某游戏的Assembly-CSharp.dll加密了,对于mono runtime的Unity游戏,Assembly-CSharp.dll是默认打包的代码库,拿到Assembly-CSharp.dll等同于拿到源码,作弊者可以把该文件拖到.net工程中充当SDK对游戏进行二次开发:

在这里插入图片描述

那么我不得不来看看,首先将游戏目录下的Assembly-CSharp.dll拖入dnspy看看:

在这里插入图片描述

果然加密了,dnspy无法还原出来了,吓得我赶紧又拖入010Editor看看文件的二进制数据:

在这里插入图片描述

连PE文件开头的4D5A(MZ头)都没了,看来是对整个文件进行了加密。

Mono加载il代码库是调用mono.dll的导出函数mono_image_open_from_data_with_name完成的,如果某游戏对Assembly-CSharp.dll进行加密,那么肯定会在该导出函数或者里面的调用进行解密,否则该模块将无法正确加载,那么就来看看。用x64dbg打开游戏进程,设置入口断点,找到mono.dll的导出函数mono_image_open_from_data_with_name:

在这里插入图片描述

双击进入内存中查看:

在这里插入图片描述

好家伙,开头直接inline hook,一个大大的jmp明摆着告诉你快来分析我,那么这里跳转过去的代码肯定就是对比是否是需要解密的文件,然后进行解密的地方了。跟过去看看,跟了一层之后,发现代码直接被vm了:

在这里插入图片描述

那对我这种没有能力还原vm的人来说,就凉凉了了呀。那有没有可能,他里面没有做这么多操作,对源加密数据的地址解密完后,直接传入后面的过程呢?抱着这个希望,对mono_image_open_from_data_with_name下断,我把mono源码中这个函数的原型贴在这里:

在这里插入图片描述

第一个参数是模块数据地址,第二个是长度,最后一个参数是模块名,对应寄存器和堆栈中的数据分别是rcx、rdx、rsp+0x30。那么下断点,不断观察[rsp+0x30]中的数据,出现字符串”Assembly-CSharp.dll”的时候就停:

在这里插入图片描述

就是现在,观察rcx和rdx寄存器里的数据:

在这里插入图片描述

Rcx是Assembly-CSharp.dll的二进制数据,rdx是该模块的大小,在内存中看一下rcx保存的地址:

在这里插入图片描述

不错,就是我们在010Editor中查看的文件数据,那么我就在外面等它,等它跑完这个被魔改过的mono_image_open_from_data_with_name函数,单步步过…

在这里插入图片描述

哈哈,熟悉的4D5A出现了,那么这个肯定就是解密后的Assembly-CSharp.dll的数据了,而且经过上面的hook,知道了此文件大小是0x91010,十进制就是593936,也就是580kb左右。由于mono这个函数此时还没有将磁盘上的二进制文件加载进内存映像里进行管理,所以这部分的模块数据就是未被加密的Assembly-CSharp.dll PE文件数据,只需要将其每个字节原封不动地读取保存成PE文件即可。

那么写个简单的内存读取+文件保存的代码,填好对应的进程ID,数据地址和数据大小:

在这里插入图片描述

运行:
在这里插入图片描述

用010Editor查看:

在这里插入图片描述

再次拖到dnspy中:

在这里插入图片描述

没想到这么简单被我拿到了源码~

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值