Unity3D应用防外挂与防破解

21 篇文章 1 订阅
3 篇文章 0 订阅

在我们的游戏开发过程中,我陆陆续续做了一些防外挂与防破解工作,这里记录总结一下。

##随机数校验
为了让玩家的操作体验更好,游戏开发之初,我决定把战斗计算放在前端实现,战斗结束之后,后端校验前端发来的数据。最简单直接的校验方法就是:按照前端的实现方法,后端实现战斗计算,逐条验证前端发来的战报。这种方法简单、直接,非常可靠,缺点一是维护前后端两份代码,比较麻烦,我不想做重复性工作;二是消耗服务器CPU资源。有什么方法不用这么麻烦呢?

对于战斗,玩家可以操作的数据分为可变固定数据。决定战斗结果关键因素:卡牌上场顺序、技能释放概率和部分伤害值,是随机的,也就是可变数据。要校验这块只需要校验随机数。

为此,我用线性冗余法,自己实现了随机数生成算法,前后端只要随机数种子相同,生成的随机数序列就是一模一样的。前端记录战斗过程中生成的随机数,后端逐个校验,非常简单,解决了可变数据被修改的问题。

##内存加密/校验
后来,我们的合作运营提醒我说,他们运营的上一款游戏,战斗也是前端计算的,出现过玩家用外挂修改攻击值/血量值的情况,找来玩家用的工具试了一下,效果非常犀利。可以直接把对方英雄血量改为1,然后一下击毙。这就是修改基础固定数据,防范方法很简单,内存加密或内存校验就可以了。

内存加密的简单方法是把关键数据加密,比如攻击值atk可以这样加密存取:

private int curATK;
private int curAtkKey;
public int CurATK {
	get {
		return curATK ^ curAtkKey;
	}
	set {
		curAtkKey = Random.Range(0, 0xffff);
		curATK = value^curAtkKey;
	}
}

这样内存修改工具就无法根据数值来找到修改了。或者也可以做内存校验:

private int curATK;
private int curRealAtk;
private int curAtkKey;
public int CurATK {
	get {
		if (curRealAtk != (curATK ^ curAtkKey))
			// cheat!!! report to server...
		return curATK ^ curAtkKey;
	}
	set {
		curRealAtk = value;
		curAtkKey = Random.Range(0, 0xffff);
		curATK = value^curAtkKey;
	}
}

##防破解
防破解主要是C#脚本加密。Unity3D生成的应用,逻辑脚本都编译到了Assembly-CSharp.dll中。打包时把它按byte加密,然后在应用启动时解密就可以了。

####加密方法
这个有很多种,根据自己的理解选一种就可以了。比如MD5、AES、xtea(cocos2d-x用的这个)、RSA等,都有开源实现。最简单是用mono自带的实现,也就是.net的安全类库实现,在System.Security.Cryptography中。

####解密
mono加载dll是在/mono/metadata/image.c中的mono_image_open_from_data_with_name。

MonoImage *
mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name)
{
	MonoCLIImageInfo *iinfo;
	MonoImage *image;
	char *datac;
	
	if (!data || !data_len) {
		if (status)
			*status = MONO_IMAGE_IMAGE_INVALID;
		return NULL;
	}
	
	// 我们在这里解密data
	
	// load image from data ...
	
	if (buffer != NULL)
		g_free(buffer);
	return register_image (image);
}

####编译mono
1. 下载资源

  • 注意unity mono与mono的不同,unity mono源码在https://github.com/Unity-Technologies/mono。
    我是在linux64位机器编译的,用的是Unity4.6,对应的ndk是r9,下载地址:
    https://github.com/Unity-Technologies/mono/tree/unity-4.6
    https://github.com/Unity-Technologies/krait-signal-handler
    http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2

  • 下载后解压
    /home/night/mono-unity-4.6
    /home/night/android-ndk-r9

  • 将krait_signal_handler复制到mono-unity-4.6/external/目录下,并重命名为android_krait_signal_handler。

2. 安装依赖

  • 安装编译工具:gcc、make、automake等

  • 安装依赖包:bison、gettext、libffi-dev、zlib、libtool等
    yum -y install xxx

3. 修改设置
进入目录/home/night/mono-unity-4.6
  • 设置环境变量 export ANDROID_NDK_ROOT=/home/night/android-ndk-r9

  • 编辑./external/buildscripts/build_runtime_android.sh

  1. 找到这一行,perl ${BUILDSCRIPTSDIR}/PrepareAndroidSDK.pl,确保设置了ndk版本-ndk=r9;我编译的时候提示找不到ndk目录(设置了环境变量),可以在文件开头,export ANDROID_PLATFORM=android-9之后设置export ANDROID_NDK_ROOT=/home/night/android-ndk-r9。
  2. 在64位机器上,找到HOST_ENV=linux-x86,改为HOST_ENV=linux-x86_64
  3. 找到这一行-fpic -g -funwind-tables,去掉-g(编release版本)。
  4. 注释掉这两行,我们不需要ARMv5/v6的so
#clean_build “$CCFLAGS_ARMv5_CPU” “$LDFLAGS_ARMv5″ “$OUTDIR/armv5″
#clean_build “$CCFLAGS_ARMv6_VFP” “$LDFLAGS_ARMv5″ “$OUTDIR/armv6_vfp”
  • 编辑./external/android_krait_signal_handler/build.pl,将#!/usr/bin/env perl –w改为#!/usr/bin/perl –w,因为有设备兼容问题

  • 编辑mono-unity-4.6/external/android_krait_signal_handler/PrepareAndroidSDK.pm
    拉到最后,找到sub PrepareNDK,在判断ndk版本号是否相等之前加入移除" (64-bit)"的代码

sub PrepareNDK
	...
	
	# remove the possible '(64-bit)' from the end
	my @curr_arr = split(' ', $current);
	$current = $curr_arr[0];

	if ($ndk eq $current)
	...
  • 执行./external/buildscripts/build_runtime_android.sh
    如果出现以下提示,说明编译成功,生成的so在./builds/embedruntimes/android/armv7a/目录下。
    Build SUCCESS!
    Build failed? Android STATIC/SHARED library cannot be found… Found 4 libs under builds/embedruntimes/ android
    如果报错,可以看config.log文件,里面记录了错误的详细原因。

PS. 如果想编译Windows平台的mono.dll,需要用Visual Studio Command Prompt,打开,然后进入./msvc目录,执行msbuild.exe mono.sln /p:Configuration=Release_eglib

转载请注明出处: http://blog.csdn.net/ynnmnm/article/details/48784335。作者:夜风。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity3D塔游戏是使用Unity游戏引擎开发的一种游戏类型。Unity是一款功能强大的游戏引擎,可以用来创建各种类型的游戏,包括3D塔游戏。在开发Unity3D塔游戏时,可以使用一些现成的资源,例如Unity3D塔游戏源码3D Tower Defense Kit 1.7,它提供了一些基本的游戏功能和模板,可以帮助开发者更快速地创建一个基本的塔游戏。 在开始开发Unity3D塔游戏时,首先需要进行游戏设计,确定游戏的目标、规则和玩法。接着,可以使用Unity的编辑器来创建游戏场景,并添加一些基本的元素,比如地图、敌人和御塔。对于御塔的创建,可以使用Unity的3D对象来制作御塔模型,并将其添加到游戏场景中。 在游戏进行过程中,玩家需要选择和放置御塔来抵御敌人的进攻。御塔可以根据设定的规则自动攻击敌人,玩家需要策略性地选择御塔的位置和类型,以有效地保护基地。同时,玩家还可以升级和升级御塔,增强其攻击能力和御能力,以对抗更强大的敌人。 总之,Unity3D塔游戏是一种使用Unity游戏引擎开发的游戏类型,玩家需要选择和放置御塔来抵御敌人的进攻,并使用策略性和升级能力来保护基地。通过使用现成的资源和Unity的编辑器,开发者可以更快速地创建一个基本的塔游戏。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [unity3D塔游戏源码3D Tower Defense Kit 1.7](https://download.csdn.net/download/qq_32065601/87258309)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Unity实现一个3D塔游戏](https://blog.csdn.net/voidinit/article/details/130370944)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值