首页
社区
课程
招聘
[原创]某渊某音游的dll保护分析,以及偷学一点Unity代码保护思路
发表于: 2019-4-28 02:35 17328

[原创]某渊某音游的dll保护分析,以及偷学一点Unity代码保护思路

2019-4-28 02:35
17328

本人虽然是个手残,却非常喜欢尝试各种音游,即使被虐到爆炸也停不下来。

最近看上一款某渊的音游,它的判定线移动打拍的玩法挺不错的,于是乎又手贱买了,然后被虐到体无完肤。
本着至少要给自己爽一下的原则,就准备对它下毒手了。

首先拆一下压缩包,发现是unity引擎,而且还是Assembly-CSharp.dll的方式,感觉也许会轻松不少(并不是

拖出来,上dnSpy,理所当然地出错。

拖进UltraEditor,发现可以明显地看出PE文件结构,就是有点怪而已。所以这应该不是那种简单地把整个dll文件套个加密算法,然后加载的时候解密那种方法。
大概是加密了关键部分,然后在解析的时候再解密吧。


试一下能不能Dump,ida附加,结果游戏直接闪退,估计是有反调试之类的,咱一个逆向萌新,对安卓方面的反调和反反调完全不懂,瞬间懵逼。
于是咱打算换一个歪门邪道,用GG修改器的Dump功能,这个游戏似乎没有针对GG修改器做什么。
Dump下整个游戏进程,然后在里面搜索DLL,把文件提取出来,但是发现,其他什么UnityEngine什么的都有,唯独缺了Assembly-CSharp.dll。
抱着不祥的预感在内存中搜索6D 7A 90 00 03 00 00 00 04,发现dll文件本身在内存中没有半点变化……


估计是魔改mono文件,然后用自己的一套来解析的吧……
拖libmono.so到ida里面,结果发现libmono.so也被搞了……

看一下Hex,被大量无意义字节填充了,估计是在载入so的时候再将原函数填回去……

还真是到处搞事情啊,不过so方面不比dll,到了内存里面你总得把这些函数给我还回来吧。
还是上GG(真好用),把libmono.so给Dump出来,记得选范围时要完整,宁可范围搞大一点,也别少选
修复一下Dump出来的文件,可以参考这里:内存dump 获得基于Unity3d的游戏相关代码

再拖进IDA,现在就没问题了


通过之前的试探,我们大概可以猜测一下dll被加载的过程,首先是原文件读入内存,再通过魔改后的mono使用自己的一套方法来解析文件。
看其他dll都没有事,所以在这个魔改后的mono中应该分开了两种不同的加载方式。
mono加载dll的时候,首先是进 mono_image_open_from_data_with_name这个函数(这个应该就不用细说了),然后走到 do_mono_image_load对PE文件进行分析。
static MonoImage *
do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
		    gboolean care_about_cli, gboolean care_about_pecoff)
{
	MonoCLIImageInfo *iinfo;
	MonoDotNetHeader *header;

	mono_profiler_module_event (image, MONO_PROFILE_START_LOAD);

	/* if MONO_SECURITY_MODE_CORE_CLR is set then determine if this image is platform code */
	image->core_clr_platform_code = mono_security_core_clr_determine_platform_image (image);

	mono_image_init (image);

	iinfo = image->image_info;
	header = &iinfo->cli_header;
		
	if (status)
		*status = MONO_IMAGE_IMAGE_INVALID;

	if (care_about_pecoff == FALSE)
		goto done;

	if (!mono_verifier_verify_pe_data (image, NULL))
		goto invalid_image;

	if (!mono_image_load_pe_data (image))
		goto invalid_image;
	
	if (care_about_cli == FALSE) {
		goto done;
	}

	if (!mono_verifier_verify_cli_data (image, NULL))
		goto invalid_image;

	if (!mono_image_load_cli_data (image))
		goto invalid_image;

	if (!mono_verifier_verify_table_data (image, NULL))
		goto invalid_image;
	
#ifndef USE_COREE
	/* if the last bit is not set, then the image is mixed mode with native code */
	if (!(iinfo->cli_cli_header.ch_flags & 1))
		goto invalid_image;
#endif

	mono_image_load_names (image);

	load_modules (image);

done:
	mono_profiler_module_loaded (image, MONO_PROFILE_OK);
	if (status)
		*status = MONO_IMAGE_OK;

	return image;

invalid_image:
	mono_profiler_module_loaded (image, MONO_PROFILE_FAILED);
	mono_image_close (image);
		return NULL;
}

首先是mono_image_load_pe_data函数对PE文件进行解析,这里有一个检验MZ头的步骤,而这个dll的头部是mz,所以这里应该有问题

static MonoImage *
do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
		    gboolean care_about_cli, gboolean care_about_pecoff)
{
	MonoCLIImageInfo *iinfo;
	MonoDotNetHeader *header;

	mono_profiler_module_event (image, MONO_PROFILE_START_LOAD);

	/* if MONO_SECURITY_MODE_CORE_CLR is set then determine if this image is platform code */
	image->core_clr_platform_code = mono_security_core_clr_determine_platform_image (image);

	mono_image_init (image);

	iinfo = image->image_info;
	header = &iinfo->cli_header;
		
	if (status)
		*status = MONO_IMAGE_IMAGE_INVALID;

	if (care_about_pecoff == FALSE)
		goto done;

	if (!mono_verifier_verify_pe_data (image, NULL))
		goto invalid_image;

	if (!mono_image_load_pe_data (image))
		goto invalid_image;
	
	if (care_about_cli == FALSE) {
		goto done;
	}

	if (!mono_verifier_verify_cli_data (image, NULL))
		goto invalid_image;

	if (!mono_image_load_cli_data (image))
		goto invalid_image;

	if (!mono_verifier_verify_table_data (image, NULL))
		goto invalid_image;
	
#ifndef USE_COREE
	/* if the last bit is not set, then the image is mixed mode with native code */
	if (!(iinfo->cli_cli_header.ch_flags & 1))
		goto invalid_image;
#endif

	mono_image_load_names (image);

	load_modules (image);

done:
	mono_profiler_module_loaded (image, MONO_PROFILE_OK);
	if (status)
		*status = MONO_IMAGE_OK;

	return image;

invalid_image:
	mono_profiler_module_loaded (image, MONO_PROFILE_FAILED);
	mono_image_close (image);
		return NULL;
}

首先是mono_image_load_pe_data函数对PE文件进行解析,这里有一个检验MZ头的步骤,而这个dll的头部是mz,所以这里应该有问题

不仅仅认正常的MZ,也认修改后的mz,没错了。

顺着加载过程摸下去,我们还可以找到魔改后同时认可PE和pe的部分


修改这里两处标识后之后,继续尝试读取dll文件,仍旧失败,根据失败原因继续走,发现时dll文件的段头被加密了,在mono中对应部分找到解密方法

段头的每一项都被单独处理,加密过程中密钥会随着改变的一个流加密,有伪代码的情况下还原解密方法没什么难度。

继续读取,发现PE结构解析部分没有问题,但还是出错了,继续往后跟,发现是.Net部分读取时出了问题
在#~读取的时候,其中的各个项都出现读取失败的情况,但是奇怪的是,最开始的几个项读取正常。在load_tables函数中发现,读取MaskValid时做了处理,将MaskValid和MaskSorted异或后再保存

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 20
支持
分享
打赏 + 6.00雪花
打赏次数 3 雪花 + 6.00
 
赞赏  gtict   +2.00 2019/04/29
赞赏  Editor   +2.00 2019/04/28 精品文章~
赞赏  junkboy   +2.00 2019/04/28 感谢分享~
最新回复 (28)
雪    币: 10704
活跃值: (809)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
分析的很好,
2019-4-28 08:14
0
雪    币: 4550
活跃值: (2495)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
3
666
2019-4-28 08:43
0
雪    币: 6885
活跃值: (3161)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
2019-4-28 08:46
0
雪    币: 36
活跃值: (1061)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
mark 66666
2019-4-28 09:30
0
雪    币: 26588
活跃值: (63252)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
6
感谢分享~
2019-4-28 10:02
0
雪    币: 11716
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
mark    看看 opcode 替换
2019-4-28 11:16
0
雪    币: 2290
活跃值: (2180)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
8
分析的不错,学习了~
2019-4-28 16:35
0
雪    币: 68
活跃值: (782)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
mark
2019-4-28 16:39
0
雪    币: 191
活跃值: (195)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
下面自动回复一万个赞
2019-4-28 17:09
0
雪    币: 4687
活跃值: (253)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
其实想要窜改也不见得非要dump出来看,可以hook mono 运行方法调用的核心函数,对方法和参数过 打印 然后你懂得
2019-4-28 17:44
0
雪    币: 3400
活跃值: (2656)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
12
bjhrwzh 其实想要窜改也不见得非要dump出来看,可以hook mono 运行方法调用的核心函数,对方法和参数过 打印 然后你懂得
这样过不了Opcode那一关呀,而且这里主要就是要分析dll保护的机制
2019-4-28 19:15
0
雪    币: 6266
活跃值: (1276)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
现在的萌新都是大佬假扮的
2019-4-29 23:07
0
雪    币: 48
活跃值: (3414)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
好牛掰
2019-5-4 12:18
0
雪    币: 9057
活跃值: (1615)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
15
看不懂,但是把它看完了
2019-5-5 12:28
0
雪    币: 14488
活跃值: (17488)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
16
mark,楼主辛苦了
2019-5-5 21:15
0
雪    币: 120
活跃值: (1597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
mark 楼主辛苦
2019-5-9 09:22
0
雪    币: 237
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
楼主牛皮,类似网易盾的保护,开始流行起来了
2019-5-12 22:29
0
雪    币: 248
活跃值: (3789)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
路过,看一下
2019-5-13 01:54
0
雪    币: 10017
活跃值: (3457)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
搞了两星期,大佬好毅力
2019-5-16 16:22
0
雪    币: 386
活跃值: (98)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
易盾没这个nb,楼主nb
2019-6-21 20:35
0
雪    币: 13
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
66666666666666
最后于 2019-7-23 00:31 被在线求大神编辑 ,原因: 写错了
2019-7-23 00:20
0
雪    币: 13
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
666666666
最后于 2019-7-23 00:33 被在线求大神编辑 ,原因: 。。。
2019-7-23 00:24
0
雪    币: 13
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
路过。。。。。
最后于 2019-7-23 00:38 被在线求大神编辑 ,原因: 。。。
2019-7-23 00:30
0
雪    币: 286
活跃值: (381)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
mark一下
2019-10-21 16:37
0
游客
登录 | 注册 方可回帖
返回
//