Unity3D应用防外挂与防破解

原创 2015年09月28日 16:59:34

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

随机数校验

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

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。作者:夜风。

Unity3D避免玩家作弊

Unity3D避免玩家作弊 如果你的Unity项目快上线了,我强烈建议你看一下Anti-Cheat这个插件。因为IOS和Android分别越狱和Root后玩家可以使用 @八门神器 @烧饼修改器 等一...
  • husheng0
  • husheng0
  • 2015-08-06 23:03:58
  • 840

如何防止Unity3D代码被反编译?

在网上找了好久,还是没有找到可行的方法,市面上的除了腾讯的Unity3D游戏之外都可以使用DisUnity拆包,DotNetReflector很简单地进行反编译,再通过dot4net进行反混淆。想请教...
  • pizi0475
  • pizi0475
  • 2015-11-11 18:13:51
  • 2206

如何防范unity代码被偷!

解密无非就为了 修改游戏功能数据、提取游戏资源、加入自己想加的广告等等加密就是保护游戏资源不被恶意修改 关于Unity C#代码部分的加密,混淆,可以去搜索一下Codeguard这个插件,它可以防止...
  • u012896140
  • u012896140
  • 2015-05-17 14:35:11
  • 483

单机 & 弱联网手游 防破解、金币修改 简单措施

手游常用破解方法 对于一个弱联网或者单机游戏,可以从以下方面去破解: 1、找得到存档文件的,直接破解修改存档文件。 2、找不到存档文件,就在游戏运行时借助一些软件来修改数值,比如用各种修改器手游...
  • cp790621656
  • cp790621656
  • 2015-07-10 23:48:13
  • 5334

.net程序可以轻松被反编译 大家都是采取什么措施防御呢

听说要用 混淆器 查了查资料 混淆器好像也能被反编译 这微软到底是想干什么啊?请高人指点指点,怎么才能做到不让反编译,然后说下用哪个混淆器好吗?基本上不太可能做到完全不让反编译。也就是能给增加一点难度...
  • h57020877
  • h57020877
  • 2010-10-02 10:41:00
  • 1341

Unity3D 导出的apk进行混淆和加固(防止反编译)

前言: 对于辛辛苦苦完成的apk程序被人轻易的反编译了,那就得不偿失了,这篇文章就是解决Unity打包出来的apk进行代码加固和混淆。   准备资料: 1:Obfuscator.zip  作用...
  • u013075726
  • u013075726
  • 2016-10-24 12:17:21
  • 1597

【Unity】防反编译之windows平台加密dll

功能取决于需求,在实现这功能之前,却有一个小小的插曲,有同学认为,并不需要去实现游戏加密,再怎样也会被破解,何必浪费精力。虽然这样说,但是我们所做的加密至少也会增加一点破解成本,不会让我们辛苦写的代码...
  • swj524152416
  • swj524152416
  • 2017-04-10 14:01:59
  • 2377

Unity3D 3.1 破解(外挂修改内存版)

  • 2010年11月14日 10:44
  • 45KB
  • 下载

编译unity-mono( 写给超级初学者的朋友)

为什么要编译mono?相比看到这篇文章的朋友应该都不需要再多问为什么,那么为了呼应标题,笔者还是想再简明扼要的阐述一下,以便不知道干啥的朋友还可以知道要干啥. unity生成的apk包,实际上就是一个...
  • qq_22393417
  • qq_22393417
  • 2016-12-02 17:38:10
  • 5648

Unity3D -- 避免代码被反编译

写在前面的话:本文转自雨松大大的文章,里面内容亲测(自己操作了一次,真的很强大),这里只不过是自己记录一下。 雨松大大的原文地址是:http://www.xuanyusong.com/archive...
  • honey199396
  • honey199396
  • 2016-09-19 16:10:02
  • 730
收藏助手
不良信息举报
您举报文章:Unity3D应用防外挂与防破解
举报原因:
原因补充:

(最多只允许输入30个字)