Unity3D研究院之Android二次加密.so二次加密DLL(八十二)
2015-10-14 17:34
429 查看
Unity3D研究院之Android二次加密.so二次加密DLL(八十二)
雨松MOMO 【Unity3D研究院之游戏开发】 围观3916次 42条评论 编辑日期:2015-07-17 字体:大 中 小<iframe id="cproIframe_u1121907_1" width="300" height="250" src="http://pos.baidu.com/acom?adn=4&at=134&aurl=&cad=1&ccd=24&cec=UTF-8&cfv=11&ch=0&col=zh-CN&conOP=0&cpa=1&dai=1&dis=0&layout_filter=rank%2Ctabcloud<r=http%3A%2F%2Fwww.xuanyusong.com%2Farchives%2F3553<u=http%3A%2F%2Fwww.xuanyusong.com%2Farchives%2F3571&lunum=6&n=92004029_cpr&pcs=1920x954&pis=10000x10000&ps=369x1329&psr=1920x1080&pss=1920x409&qn=e076dd127958a991&rad=&rsi0=300&rsi1=250&rsi5=4&rss0=%23FFFFFF&rss1=%23FFFFFF&rss2=%230000FF&rss3=%23444444&rss4=%23008000&rss5=&rss6=%23e10900&rss7=&scale=&skin=&td_id=1121907&tn=text_default_300_250&tpr=1444814692268&ts=1&version=2.0&xuanting=0&dtm=BAIDU_DUP2_SETJSONADSLOT&dc=2&di=u1121907&ti=Unity3D%E7%A0%94%E7%A9%B6%E9%99%A2%E4%B9%8BAndroid%E4%BA%8C%E6%AC%A1%E5%8A%A0%E5%AF%86.so%E4%BA%8C%E6%AC%A1%E5%8A%A0%E5%AF%86DLL%EF%BC%88%E5%85%AB%E5%8D%81%E4%BA%8C%EF%BC%89%20%7C%20%E9%9B%A8%E6%9D%BEMOMO%E7%A8%8B%E5%BA%8F%E7%A0%94%E7%A9%B6%E9%99%A2&tt=1444814692266.3.74.75" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; font-family: inherit;"></iframe>
上文中说了怎么给DLL加密来防止别人反编译你的C#代码。 Unity3D研究院之Android加密DLL与破解DLL .SO(八十一) 文章的最后我们发现IDA PRO神器可以解开libmono从而查到你的解密算法,这样你的C#代码又会被别人轻易的拿到。
这两天我就一直在寻找怎样才能更好的保护代码。终于找到了加密so的办法,此法我觉得防小白觉对够用。大神恐怕还是能解开,但是我觉得这就够了。我已经在项目中测试通过,也欢迎大家也能加入一起来测试的队伍。
在啰嗦一句在不远的将来可能我们也不用这么做了, 因为很快unity就全线l2cpp了。但是我觉得等真正稳定恐怕还有很多路要走,所以估计大部分正在开发的项目不会冒这个险升级。
阅读下面之前请大家先看一下这篇大神的文章。http://bbs.pediy.com/showthread.php?t=191649 文章写的很清晰。但是坦白说看了半天我没怎么看懂,逆向工程真是一门深奥的学问。。主要还是技术关注领域不在这里。文章的最后有作者给出的源码,大家记得下载下来。然后我就开始说我是怎么把这个加在unity3d上的。还有我遇到了那些坑。
它的例子工程下载解压后,开始对shellAdder1.c进行编译,编译的方法是
1 | gcc -o encry shellAdder1.c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> /* 32-bit ELF base types. */ typedef unsigned int Elf32_Addr; typedef unsigned short Elf32_Half; typedef unsigned int Elf32_Off; typedef signed int Elf32_Sword; typedef unsigned int Elf32_Word; #define EI_NIDENT 16 /* * ELF header. */ typedef struct { unsigned char e_ident[EI_NIDENT]; /* File identification. */ Elf32_Half e_type; /* File type. */ Elf32_Half e_machine; /* Machine architecture. */ Elf32_Word e_version; /* ELF format version. */ Elf32_Addr e_entry; /* Entry point. */ Elf32_Off e_phoff; /* Program header file offset. */ Elf32_Off e_shoff; /* Section header file offset. */ Elf32_Word e_flags; /* Architecture-specific flags. */ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */ Elf32_Half e_phentsize; /* Size of program header entry. */ Elf32_Half e_phnum; /* Number of program header entries. */ Elf32_Half e_shentsize; /* Size of section header entry. */ Elf32_Half e_shnum; /* Number of section header entries. */ Elf32_Half e_shstrndx; /* Section name strings section. */ } Elf32_Ehdr; /* * Section header. */ typedef struct { Elf32_Word sh_name; /* Section name (index into the section header string table). */ Elf32_Word sh_type; /* Section type. */ Elf32_Word sh_flags; /* Section flags. */ Elf32_Addr sh_addr; /* Address in memory image. */ Elf32_Off sh_offset; /* Offset in file. */ Elf32_Word sh_size; /* Size in bytes. */ Elf32_Word sh_link; /* Index of a related section. */ Elf32_Word sh_info; /* Depends on section type. */ Elf32_Word sh_addralign; /* Alignment in bytes. */ Elf32_Word sh_entsize; /* Size of each entry in section. */ } Elf32_Shdr; |
然后执行 encry libmono.so 就会把libmono.so里 名叫 mytext 的断 进行加密,你要觉得这个名子不好也可以换一个断名,加密后的libmono.so文件会替换原有的。
接着到mono/metadata/image.c里来编写解密.so断的代码。把下面这段代码拷贝到image.c的最上面,关键的两个地方我已添加注释了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | //SO---------------加密---------------------- #include <sys/types.h> #include <elf.h> #include <sys/mman.h> //注意上面说解密算法里面的断.mytext就是这里, //这里把getKey进行了加密,这样对方拿不到你的密钥都没法破解你的dll了 int getKey() __attribute__((section (".mytext"))); int getKey(){ return 2048; }; //这里就是.so初始化的时候,这里进行mytext断的解密工作 void init_getKey() __attribute__((constructor)); unsigned long getLibAddr(); void init_getKey(){ char name[15]; unsigned int nblock; unsigned int nsize; unsigned long base; unsigned long text_addr; unsigned int i; Elf32_Ehdr *ehdr; Elf32_Shdr *shdr; base = getLibAddr(); ehdr = (Elf32_Ehdr *)base; text_addr = ehdr->e_shoff + base; nblock = ehdr->e_entry >> 16; nsize = ehdr->e_entry & 0xffff; g_message("momo: nblock = %d\n", nblock); if(mprotect((void *) base, 4096 * nsize, PROT_READ | PROT_EXEC | PROT_WRITE) != 0){ g_message("momo: mem privilege change failed"); } //注意这里就是解密算法, 要和加密算法完全逆向才行不然就解不开了。 for(i=0;i< nblock; i++){ char *addr = (char*)(text_addr + i); *addr = ~(*addr); } if(mprotect((void *) base, 4096 * nsize, PROT_READ | PROT_EXEC) != 0){ g_message("momo: mem privilege change failed"); } g_message("momo: Decrypt success"); } unsigned long getLibAddr(){ unsigned long ret = 0; char name[] = "libmono.so"; char buf[4096], *temp; int pid; FILE *fp; pid = getpid(); sprintf(buf, "/proc/%d/maps", pid); fp = fopen(buf, "r"); if(fp == NULL) { g_message("momo: open failed"); goto _error; } while(fgets(buf, sizeof(buf), fp)){ if(strstr(buf, name)){ temp = strtok(buf, "-"); ret = strtoul(temp, NULL, 16); break; } } _error: fclose(fp); return ret; } //SO---------------加密---------------------- |
1 2 3 4 5 | if(strstr(name,"Assembly-CSharp.dll")){ //这里就能取到密钥,那么这个函数被加密了。 //IDA就看不到它了 g_message("momo: key = %d\n", getKey()); } |
可以测试一下加密的效果。用Ida 打开。这里的函数已经打不开了
![](http://www.xuanyusong.com/wp-content/uploads/2015/07/9A009440-D13E-4922-8528-865191277727.png)
这段密钥进行了保护那么就可以随意的做加密算法了。
![](http://www.xuanyusong.com/wp-content/uploads/2015/07/1F55F876-04DF-4E9C-84D8-317093035606.png)
我相信这个方法还是存在漏洞,肯定也有大神能破解。也希望各位大神不吝赐教,谢谢啦。使用上有问题欢迎在下面留言大家可以一起讨论。
本文固定链接: http://www.xuanyusong.com/archives/3571
转载请注明: 雨松MOMO 2015年07月17日 于 雨松MOMO程序研究院 发表
相关文章推荐
- Unity3D研究院之Android加密DLL与破解DLL .SO(八十一)
- Unity 移动端实现pad 端acceleration 控制移动、旋转
- Unity程序闪退与卡顿原因
- 全面理解Unity加载和内存管理
- [译]如何在Unity编辑器中添加你自己的工具
- Unity3D中脚本的执行顺序和编译顺序
- Unity中的特殊文件夹
- Unity3D研究院之手游开发中所有特殊的文件夹
- Unity各种路径
- Unity3D研究院之IOS Android支持中文与本地文件的读取写入(二十七)
- Unity中的Path对应各平台中的Path
- Unity学习路线之C#基础----基本变量
- Unity学习路线
- unity 音乐播放器的制作
- Unity更改渲染层级代码
- [Android交互]高德地图与Unity的交互
- 游戏开发设计模式之对象池模式(unity3d 示例实现)
- Shader-Vertex -像苹果关闭界面一样
- 游戏开发设计模式之对象池模式(unity3d 示例实现)
- Unity3d 异常处理- (二)