【Unity】代码加密(二)dll加密so加密

写在前面

libmono的编译方法请参见我的前一篇文章【Unity】代码加密(一)编译libmono
如需转载,请注明出自喵喵丸的博客http://blog.csdn.net/u011643833/article/details/49102423

加密Dll

【这一部分操作我在Windows VS中完成(用的C)】
这个其实可以用任何你熟悉的语言来实现,只要和你的解密方法相对应即可。我所做的流程是这样的:

  • 读取从Unity导出Android工程中Assembly-CSharp.dll
  • 读取的字节流,进行加密(这里说道的读取以及下面所述输出,指的是文件读写)
  • 输出加密后的字节流,生成新的dll,名字依旧是Assembly-CSharp.dll,覆盖原文件。

(加密后,查看文件内容可发现与未加密之前明显的不同)

解密Dll

【这一部分操作我在Ubuntu中完成】

  • 从源码根目录文件夹下,找到/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) 说一下要注意的几个参数。
  • data 需要加密的字节流
  • data_len data字节流长度
  • need_copy 是否需要深拷贝

  • 代码形式参考下面(自己添加的部分参照两段 Add-Addend注释 之间的代码)

MonoImage* mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name){
    //..

    //*********************************Add*********************************//
    char *refKey;
    //取得自己解密所需的秘钥(下方so加密中再进行叙述)
    refKey = getKey();
    //..
    //*******************************Addend*******************************//

    //...
    if (!data || !data_len){
        if(status)
            *status = MONO_IMAGE_IMAGE_INVALID;
        return NULL;
    }

    //*********************************Add*********************************//
    ifstrstr(name, "Assembly-CSharp.dll")){
        char* decodeResult = (char *) malloc (data_len * sizeof(char));
        //..
        //Assembly-CShap.dll字节流(即data)解密(与加密算法对应) 
        //refKey为秘钥 将解密结果注入decodeResult中 (这部分就请大家自己填充)
        //..
        memcpy(data, decodeResult, data_len);
        free(decodeResult);
        decodeResult = NULL;

        datac = data;
    }else{
        datac = data;
    }
    //*******************************Addend*******************************//

    //自己修改的代码一定要放到原文中下面代码的前面、否则自己解密后的内容会得不到正常的拷贝
    if (need_copy){
        datac = g_try_malloc (data_len);
        if (!datac){
            if (status)
                *status = MONO_IMAGE_ERROR_ERRNO;
            return NULL;    
        }
        memcpy (datac, data, data_len);
    }

    //..
    //其余代码

}
  • 第一段Add-Addend 说明:这部分作用是取到你即将在下面so加密中藏起来的加密秘钥,在测试时,可以先写成明文的秘钥填充refKey,完成so加密后,使用getKey()函数取代。
  • 第二段Add-Addend说明:这部分将参数中传入的data做解密。调试时,先把这部分代码正确性做以验证(反正是C嘛。。在VS里面写个命令行。。把加密过的Assembly-CSharp.dll解密后,与未加密前的Assembly-CSharp.dll文件进行文件对比,即可验证代码正确性),再放入上面代码段之中。

加密so

【这一部分操作我在Ubuntu中完成】

为了解决我们在libmono.so中藏不起来秘钥的这个问题,在雨松Momo大大的博客指导下,已经可以解决啦~
其实解决这个问题的过程雨松Momo阐述的已经很明白了,重点的部分在于编译出encry可执行文件。编译过程我就不赘述了,只是说一下自己遇到的几个不太一样的点

  • 我下载了shelldemo后直接编译并没有遇到Momo所遇到的缺少elf.h文件的报错。正确编译了(可能和Mono下载到的版本有些出入,但是后续工作完成后发现功能上是没有问题的)
  • shellAdder1.c中, 存在变量target_section[] = "xxxxxx";,这里的target_section需要与你写入image.c中int getKey() __attribute__((section (".xxxxxx")));section字段对应。这篇文章对section的说明比较明确,也是Momo推荐的,我在看的时候其实对0x1、0x2、0x3疑惑了好久,结果发现是标题。。。
  • image.c中解密section的方法写在哪Momo已经明确的标注了,那么shellAdder1.c中加密section的方法在哪呢?—–打开shellAdder1.c文件,搜索符号取反’~’(我下载的版本在90行的左右)这里就是加密方法所在的地方。既然找到了加密解密section的位置,大家自行填充想要的算法即可。
  • 如何快速的验证加密成功了呢~其一,可以观察libmono.so文件内容(其实根本不直观);其二,IDA搜索getKey,没有加密成功你就可以看到这个函数内容;其三,第一次执行encry libmono.so时,正常执行,第二次执行encry同一文件,报错为找不到section字段。证明已经加密过了~

调试以及Tips

这里是自己觉得有一些助益的小经验吧

  • 作业的顺序,基本和这两篇博客大标题的顺序一致,最好一项一项在工程中验证,循序渐进。
  • 调试工程,需要有至少一处的交互,或者活动的GameObject,以便观察。比如说:点击反馈的事件(不能正常解密的dll 或者so,会显示第一个静态的镜头,如果没有一些反馈,比较难验证你的解密是否真的做成功了)
  • 不要选择windows来编译libmono,这个在前一篇有说过,windows用cygwin来做难度和Linux(我没用Mac实验)来比,是指数级的。后来Linux成功完成所有工作之后,我又尝试在windows上面做了一次,还是失败了。
  • 关于如何将加密的源码文件加入libmono编译过程中,这方面其实我很抓瞎的,虽然解决了,但是方法很野蛮。在 mono-unity-x.x/mono/metadata 目录下有三个makefile文件, 在这三个文件中搜索image关键字,在搜索到的位置前面,添加你需要编译的.h .c文件。这样就可以在image.c中引用你新添加的文件了。

其实,当时遇到好多想说明的问题,可是如今却是回忆不起来。暂时只写到这边。
如果大家在加密时候遇到了问题,欢迎留言。我会努力解答。

(:з」∠)事实证明,为了举一反三 勤快的笔头子是重要的

淘宝花钱买的最新版!需要的拿去! This asset obfuscates your code to make it harder for bad guys to reverse engineer your projects. Specifically designed for Unity, it seamlessly links in with its build process. The top priority of this package is to work straight out of the box with no extra steps required. While other obfuscators can stop a game from working, Beebyte's obfuscator looks for specific Unity related code that must be protected. The contents of your source files are unchanged, the obfuscation targets the compiled assembly. Features: - Supports IL2CPP - Supports Assembly Definition Files (Unity 2017.3+) - Removes Namespaces without any conflicts - Recognises Unity related code that must not be changed - Renames Classes (including MonoBehaviours) - Renames Methods - Renames Parameters - Renames Fields - Renames Properties - Renames Events - String literal obfuscation - Adds fake methods - Easy and extensive customisation using the Unity inspector window - Consistent name translations are possible across multiple builds and developers - Semantically secure cryptographic naming convention for renamed members The asset works for both Unity Free and Unity Pro version 4.2.0 onwards (including Unity 5 & 2017 & 2018). Build targets include Standalone, Android, iOS, WebGL, UWP. Other platforms are not guaranteed or supported but may become supported at a future date. IL2CPP builds are much harder to reverse engineer but strings and member information (class, method names etc) are visible in the global-metadata.dat file. Obfuscation will apply to this file adding further security. Why not complement your security with the Anti-Cheat Toolkit - a great third party asset. For more information about the Obfuscator, please see the FAQ
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值