CN110096853A - 基于Mono的Unity安卓应用加固方法、存储介质 - Google Patents

基于Mono的Unity安卓应用加固方法、存储介质 Download PDF

Info

Publication number
CN110096853A
CN110096853A CN201910292296.1A CN201910292296A CN110096853A CN 110096853 A CN110096853 A CN 110096853A CN 201910292296 A CN201910292296 A CN 201910292296A CN 110096853 A CN110096853 A CN 110096853A
Authority
CN
China
Prior art keywords
dll
mono
function
file
unity
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
CN201910292296.1A
Other languages
English (en)
Other versions
CN110096853B (zh
Inventor
刘德建
官泉
陈宏展
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Fujian Tianqing Online Interactive Technology Co Ltd
Original Assignee
Fujian Tianqing Online Interactive Technology Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Fujian Tianqing Online Interactive Technology Co Ltd filed Critical Fujian Tianqing Online Interactive Technology Co Ltd
Priority to CN201910292296.1A priority Critical patent/CN110096853B/zh
Publication of CN110096853A publication Critical patent/CN110096853A/zh
Application granted granted Critical
Publication of CN110096853B publication Critical patent/CN110096853B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • G06F11/3624Software debugging by performing operations on the source code, e.g. via a compiler
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/10Protecting distributed programs or content, e.g. vending or licensing of copyrighted material ; Digital rights management [DRM]
    • G06F21/12Protecting executable software
    • G06F21/14Protecting executable software against software analysis or reverse engineering, e.g. by obfuscation
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/55Detecting local intrusion or implementing counter-measures
    • G06F21/56Computer malware detection or handling, e.g. anti-virus arrangements
    • G06F21/562Static detection
    • G06F21/563Static detection by source code analysis
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/55Detecting local intrusion or implementing counter-measures
    • G06F21/56Computer malware detection or handling, e.g. anti-virus arrangements
    • G06F21/562Static detection
    • G06F21/565Static detection by checking file integrity
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/55Detecting local intrusion or implementing counter-measures
    • G06F21/56Computer malware detection or handling, e.g. anti-virus arrangements
    • G06F21/566Dynamic detection, i.e. detection performed at run-time, e.g. emulation, suspicious activities
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F2221/00Indexing scheme relating to security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F2221/03Indexing scheme relating to G06F21/50, monitoring users, programs or devices to maintain the integrity of platforms
    • G06F2221/033Test or assess software

Landscapes

  • Engineering & Computer Science (AREA)
  • Computer Security & Cryptography (AREA)
  • Theoretical Computer Science (AREA)
  • Software Systems (AREA)
  • General Engineering & Computer Science (AREA)
  • Computer Hardware Design (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Health & Medical Sciences (AREA)
  • General Health & Medical Sciences (AREA)
  • Virology (AREA)
  • Technology Law (AREA)
  • Multimedia (AREA)
  • Quality & Reliability (AREA)
  • Storage Device Security (AREA)

Abstract

本发明提供基于Mono的Unity安卓应用加固方法、存储介质,方法包括:删除或随机变换DLL文件中的特征码和关键寻址地址;加密删除或随机变换后的DLL文件,得到已加固的DLL文件;配置Mono项目运行时,若识别到载入的是所述已加固的DLL文件,则执行包括:跳过特征值判断函数;调用预存储的对应所述加密的DLL解密函数;执行反调试线程;对所述DLL解密函数进行脱壳;配置完成后重编译Mono项目,并对其中的DLL解密函数进行加壳;删除或随机变换加壳后的Mono项目中的节信息。本发明能有效抵御各类逆向应用的还原源码和静态攻击,同时还能兼容高版本安卓机型,从而显著提高应用的安全性和加固方法的兼容性。

Description

基于Mono的Unity安卓应用加固方法、存储介质
技术领域
本发明涉及基于Mono的Unity安卓应用领域,具体涉及基于Mono的Unity安卓应用加固方法、存储介质。
背景技术
目前大量安卓应用面临逆向应用、盗版、恶意代码植入、破解修改等威胁。特别是基于开源Mono编译的Unity应用(如Unity游戏),容易被逆向工程直接查看源代码,然后进行修改。
为了防止上述情况的发生,现有技术采用了代码混淆、字符串加密以及特殊编码规则等,还有基于特定Section的Mono加壳技术,反调试等。但是仍然存在以下缺点:
1、进行代码混淆以及字符串加密,并不会防止代码被静态分析以及被逆向应用还原成源码,只是增加了静态分析的难度,对于应用(如游戏)内关键数值的修改并无实际影响。
2、针对Mono编译出的DLL进行加密,在Mono内进行解密的加固方法,容易被进行Mono源码比较,特别是针对mono_image_open_from_data_with_name函数的汇编代码,通过找出差异点,分析解密代码还原DLL,或者直接内存复制得到原始的DLL文件,再进行数值修改达到破解应用(游戏)的目的。
3、为了解决上述两个问题,现有技术采用了基于Section的Mono二次加固方案。该方案在原基础上对Mono内的解密函数设置Section字段,然后对其进行加壳保护,将地址存于文件头部,之后在初始阶段进行脱壳。但是,由于安卓7.0及更高版本对ELF格式的文件头进行了更加严格的检查,故该方法不适用于更新的安卓版本,导致兼容性降低。
因此,有必要提供一种基于Mono的Unity安卓应用加固方法、存储介质,以同时解决源码被还原、静态分析以及无法兼容高版本安卓系统等问题。
发明内容
本发明所要解决的技术问题是:提供基于Mono的Unity安卓应用加固方法、存储介质,能够克服现有加固方法存在的源码被还原或被静态分析的问题,从而显著提高应用安全性。
为了解决上述技术问题,本发明采用的技术方案为:
基于Mono的Unity安卓应用加固方法,包括:
删除或随机变换DLL文件中的特征码和关键寻址地址;
加密删除或随机变换后的DLL文件,得到已加固的DLL文件;
配置Mono项目运行时,若识别到载入的是所述已加固的DLL文件,则执行包括:跳过特征值判断函数;调用预存储的对应所述加密的DLL解密函数;执行反调试线程;对所述DLL解密函数进行脱壳;
重编译配置后的Mono项目;
对重编译后的Mono项目中的所述DLL解密函数进行加壳;
删除或随机变换加壳后的Mono项目中的节信息。
本发明提供的另一个技术方案为:
一种计算机可读存储介质,其上存储有计算机程序,所述程序在被处理器执行时,能实现上述基于Mono的Unity安卓应用加固方法所包含的步骤。
本发明的有益效果在于:本发明通过对DLL文件的特征值进行处理,可造成部分不可逆的效果,导致内存调试应用无法依据特征值找到该文件,也能使逆向工程无法自动还原出源码;通过对DLL文件的关键寻址地址进行处理,使逆向工程无法根据地址解析出调用函数的位置来自动还原出源码;通过对DLL文件进行加固,使得无法正确还原出汇编代码;进一步地,还通过增加反调试功能有效防止被动态调试,也因为之后的Mono加壳导致无法使用逆向应用静态分析出DLL解密算法。本发明运用在Uniyt应用,能有效抵御各类逆向应用的静态分析和还原源码,从而显著提高应用的安全性。
附图说明
图1为本发明实施例一种基于Mono的Unity安卓应用加固方法的流程示意图;
图2为本发明实施例一的S1步骤涉及的典型PE文件格式及对应修改部分标注图;
图3为本发明实施例二的S7步骤的加壳流程示意图;
图4为本发明实施例二的加壳流程涉及的ELE格式的连接视图及格式内简化流程示意图;
图5为本发明实施例二的S8步骤中需要处理的Section头信息示意图;
图6为本发明实施例二的S55步骤的脱壳流程示意图;
图7为本发明实施例二的脱壳流程中涉及的ELE格式的连接视图及格式内简化流程示意图;
图8为本发明实施例二的加固后收到反汇编攻击时的效果图。
具体实施方式
为详细说明本发明的技术内容、所实现目的及效果,以下结合实施方式并配合附图予以说明。
本发明最关键的构思在于:通过分别对DLL文件进行加固和对Mono进行深入改造,有效抵御各类逆向应用的静态分析和还原源码的攻击。
本发明涉及的技术术语解释:
请参照图1,本发明提供基于Mono的Unity安卓应用加固方法,包括:
删除或随机变换DLL文件中的特征码和关键寻址地址;
加密删除或随机变换后的DLL文件,得到已加固的DLL文件;
配置Mono项目运行时,若识别到载入的是所述已加固的DLL文件,则执行包括:跳过特征值判断函数;调用预存储的对应所述加密的DLL解密函数;执行反调试线程;对所述DLL解密函数进行脱壳;
重编译配置后的Mono项目;
对重编译后的Mono项目中的所述DLL解密函数进行加壳;
删除或随机变换加壳后的Mono项目中的节信息。
从上述描述可知,本发明的有益效果在于:本发明通过先对处理特征码和关键寻址地址之后的DLL文件进行加密,实现对DLL文件进行加固;而后然后对Mono进行加壳以及关键函数动态脱壳,实现对Mono进行深入改造的方案来代替外界现有的加固方案,实现既能有效防止源码被还原,又能有效防止被静态分析出DLL文件的解密算法,从而显著提高Unity应用的安全性。
进一步的,所述对重编译后的Mono项目中的所述DLL解密函数进行加壳,具体为:
使用连接视图对函数的动态符号表进行查找,获取重编译后的Mono项目中的所述DLL解密函数;加密所述DLL解密函数;
所述对所述DLL解密函数进行脱壳,具体为:
通过查找动态符号表,获取加密后的DLL解密函数,并对其进行解密。
由上述描述可知,在能够有效防止Unity应用被还原出源码或静态分析的基础上,还能通过使用执行视图的动态字符表查询方式进行加壳和脱壳,从而无需将解密算法地址存于头部,进而实现了对高版本安卓机型的兼容,显著提高应用加固方法的兼容性。
进一步的,还包括:
对已加固的DLL文件置入预设的加固标识;
Mono项目运行时,依据所述加固标识识别出已加固的DLL文件。
由上述描述可知,通过在加固后的DLL文件中置入标识,能实现依据标识快速识别出已加固的DLL文件并依据指定方式进行处理,不仅能保证方案实施地准确性,同时又能提高实施效率。
进一步的,所述配置,具体为:
添加Mono项目识别载入的是否为所述已加固的DLL文件的方法;
添加若识别为载入的是所述已加固的DLL文件,则删除Mono项目的特征值判断函数的方法;
添加在DLL文件载入时调用预存储的对应所述加密的DLL解密函数的方法;
添加反调试线程至Mono项目;
添加对所述DLL解密函数进行脱壳的方法至Mono项目。
由上述描述可知,通过上述配置对Mono项目进行深入改造,使Mono项目在执行时能够依据需求正确地对已加固的DLL文件进行相应处理。
进一步的,所述删除或随机变换DLL文件中的特征码和关键寻址地址,具体为:
分析windows的PE文件结构,依次执行包括:
删除或随机变换Net表内Meta数据流的特征名称;
删除或随机变换Net表内Meta数据头的特征签名和版本号;
删除或随机变换节表头内除内存偏移地址、文件偏移地址、数据长度、块属性以外的数据;
删除或随机变换Net头内Optional头中的Magic特征签名符号;
删除或随机变换Net头内的特征签名;
删除或随机变换Dos头内除指向NT头的偏移地址以外的其他数据。
由上述描述可知,通过对上述特征码和关键寻址地址进行处理,能对逆向工程造成混乱,也能防止逆向工具进行内存搜索,从而使其他可逆的保护均失效的情况下,应用依然能拥有不可逆的防护效果。
进一步的,所述调用预存储的对应所述加密的DLL解密函数,具体为:
Mono项目的载入DLL函数调用预存储的对应所述加密且属性设置为页面对齐的DLL解密函数,对已加固的DLL文件进行解密。
由上述描述可知,通过将预存储的DLL解密函数属性设置为页面对齐,能确保DLL解密函数在后续加壳过程中进行无损的二进制修改,进而提高加壳的保护力度。
进一步的,所述执行反调试线程,具体为:
通过预设在Mono项目的每个关键函数内部的时间判断方法,判断关键函数的执行时间是否超过阈值,若超过阈值,则判定对应的关键函数被调试。
进一步的,所述执行反调试线程,具体为:
通过循环执行预设在Mono项目内部的两个以上的反调试线程,判断Mono项目的关键函数是否被调用;其中,所述反调试线程包括:
检测当前系统占用端口是否含有调试器的默认端口号;
检测当前系统启动的进程的进程名中是否含有调试器的包名或者进程名;
检测当前系统启动的进程的父进程是否不为zygote进程;
检测当前系统启动的进程的进程状态,判断TracerPid是否不为0;
检测当前系统属性,查看命令是否在管理员权限下运行,判断返回值是否不为0。
由上述描述可知,同时提供两种反调试方式供选择,不仅能有效防止被动态调试,而且更具配置的灵活性。
进一步的,所述对重编译后的Mono项目中的所述DLL解密函数进行加壳,具体为:
打开重编译后得到的libmono.so文件;
使用连接视图解析libmono.so文件中的ELF头,获取节头表的起始地址、节数量以及各个节名称索引的起始地址;
依据节头表的起始地址和节数量,遍历节头表,获取各个节名称索引的起始地址对应的各个节名称;
依据各个节名称获取dynstr和动态符号表;
遍历动态符号表中的每个函数,从所述dynstr中获取当前遍历到的函数对应的函数名称,并匹配所述函数名称与待加壳的DLL解密函数的名称,若匹配成功,则对当前遍历到的函数的数据块进行加密。
由上述描述可知,通过使用连接视图对函数的动态符号表进行查找,然后找到DLL解密函数并进行加密,实现对Mono进行加壳,有效抵制使用逆向静态分析出DLL的解密算法的攻击方式。
进一步的,所述删除或随机变换加壳后的Mono项目中的节信息,具体为:
依据节头表的起始地址和节数量,遍历节头表,获取其中包括interp、hash、rel.dyn、rel.plt、plt、ext、cpde、rodata、init_array、fini_array、got以及data的节;
将所述节对应的起始地址、内存偏移地址和长度信息进行删除或随机变换。
由上述描述可知,通过对指定的节地址和长度信息进行处理,能对逆向应用造成混乱,从而有效防止逆向应用通过地址跳转找到对应函数进行静态分析。
进一步的,所述对所述DLL解密函数进行脱壳,具体为:
获取libmono.so文件;
使用连接视图解析libmono.so文件中的ELF头,获取程序头表;
获取程序头表中的dynamic节,遍历其内容得到dynstr和strtab;
遍历所述strtab中的每个函数,从所述dynstr中获取当前遍历到的函数对应的函数名称,并匹配所述函数名称与待脱壳的DLL解密函数的名称,若匹配成功,则获取当前遍历到的函数对应动态符号表的索引值;
依据所述索引值从动态符号表中获取待脱壳的函数数据块;
解密所述待脱壳的函数数据块。
由上述描述可知,因为使用执行视图的字符表查找方式进行脱壳,无需将解密算法地址存于头部,解决了高版本安卓机型的不兼容问题。
进一步的,所述解密所述待脱壳的函数数据块,具体为:
修改所述待脱壳的函数数据块的内存读写权限;
对所述待脱壳的函数数据块进行解密;
还原所述待脱壳的函数数据块的内存读写权限;
清除所述待脱壳的函数数据块在内存页的指令缓存。
由上述描述可知,在解密后及时还原读写权限,避免被借机攻击;通过清除指令缓存,使处理器重新从内存中读取指令,提高指令的安全性。
本发明提供的另一个技术方案为:
一种计算机可读存储介质,其上存储有计算机程序,所述程序在被处理器执行时,能实现上述基于Mono的Unity安卓应用加固方法所包含的步骤。
从上述描述可知,本发明的有益效果在于:对应本领域普通技术人员可以理解实现上述技术方案中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来实现的,所述的程序可存储于一计算机可读取的存储介质中,该程序在执行时,可包括如上述各方法的流程。同样的,所述存储介质中的流程在被执行后,将能获取与上述方法所述的有益效果完全相同的效果。
其中,所述的存储介质可以是磁盘、光碟、只读存储记忆体(Read-Only Memory,ROM)或随机存储记忆体(Random Access Memory,RAM)等。
实施例一
请参照图1和图2,本实施例提供基于Mono的Unity安卓应用加固方法,能同时解决现有的加固方法仍然存在的源码被还原和静态分析的问题。
请参阅图1,本实施例的方法包括:
(一)DLL加固;
由于Unity中DLL是由Mono生成的,之后载入也是由Mono解析并且载入,所以可以对DLL进行修改。
加固的具体流程包括:
S1:特征码处理;
在本实施例中,将采用直接删除(置0)或者随机变换(使用随机值替换原值),的方式来处理DLL文件的特征值。
具体的,需要分析windows的PE文件结构,并依次或无序性地执行以下步骤:
S11:对.Net Directory(即.Net表)内的MetaData Steams(即Meta数据流)内的特征名称如“#~”、“#Strings”、“#US”、“#GUID”、“#Blob”和“#-”进行随机变换或删除,从而防止逆向工具进行内存搜索。
S12:对.Net Directory内的MetaData Header(即Meta数据头)内的特征签名“BSJB”进行随机变换,版本号字符串进行删除,防止逆向工具进行内存搜索。
上述操作的目的是:带引号的特征符号是固定值,在内存中容易被破解人员进行内存搜索,从而找到这些符号,进而对整个DLL进行dump(就是镜像复制下来),然后破解。通过删除或随机变换,能有效被找到。
S13:删除Resource Directory(即资源表)的数据,在Unity中该数据无实际作用,对数据删除会对逆向工程造成混乱。
S14:删除Relocation Directory(即重定位表)的数据。在Unity中该数据无实际作用,对数据删除会对逆向工程造成混乱。
S15:对Section Headers(即节表头)内的内存偏移地址、文件偏移地址、数据长度、块属性进行保留,其在Mono动态加载时会进行使用,而后置0其他无实际作用的数据。
S16:对Nt Headers(即Nt头)内的Optional Header(即Optional头)中Magic特征签名符号“PE32”进行随机变换,防止逆向工具进行内存搜索。
S17:对Nt Headers(即Nt头)内的特征签名“PE\0\0”进行随机变换,防止逆向工具进行内存搜索。
S18:最对Dos Headers(即Dos头)内的指向NT头的偏移地址进行保留,使其能跳转至Nt头的数据,而后将其他无实际作用的数据删除。
对DLL文件的修改如图2所示。上述步骤将使应用在其他可逆的保护均失效的情况下依然拥有不可逆的防护作用。
S2:加密DLL文件;
具体的,可以使用简单异或或者取反等自定义的加密算法,也可以使用如AES、DES、TDEA、RC5等高级对称加密算法对S1步骤后得到的DLL文件进行全文或者部分加密或者多次加密。
该步骤将增加DLL被逆向的难度,且其解密算法将在后续被当做关键函数隐藏于Mono内,并且被加壳保护。
S3:植入已加固标记;
具体的,在加密后的DLL文件中置入自定义的加固标识,用于标识该DLL文件已加固,还用于应用运行时的Mono载入阶段被识别,也可以用于防止重复加固。
优选的,还包括:
S4:将S2加密的密钥或者其他需要的内容填充于DLL文件中自定义区域里。
(二)深度改造Mono;
为了能够正确地载入已加固的DLL文件以及保护解密函数和文件自身不被静态分析或动态调试,故需要对开源的Mono项目进行深度改造,以增加它的防护能力。
具体的,包括以下步骤:
S5:配置Mono项目在运行时,能自动执行以下内容:
(1)识别出载入的是已加固的DLL文件;
(2)对已加固的DLL文件执行包括:跳过特征值判断函数;调用预存储的对应所述加密的DLL解密函数;执行反调试线程;对所述DLL解密函数进行脱壳。
进一步具体的,所述配置的内容(即具体改造内容)包括:
S51:在Mono项目中添加识别载入的是否为所述已加固的DLL文件的方法;
该方法用于Mono项目在载入阶段能够依据S3添加的加固标识,识别出已加固的DLL文件。
S52:添加若识别为载入的是所述已加固的DLL文件,则删除Mono项目的特征值判断函数的方法;
Mono内有众多判断特征值是否存在以便于确定是否继续下一步的函数,通过添加该方法,能使已加固的DLL文件跳过这些判断而直接执行下一步骤。
S53:添加在DLL文件载入时调用预存储的对应所述加密的DLL解密函数的方法;
该方法仍然针对当载入的是已加固的DLL文件时所作的处理。通过在Mono的载入DLL函数里调用DLL解密函数来进行解密DLL,才能正确加载被加密的DLL。具体的,若Mono运行时载入的是已加固的DLL文件,则需要先进行解密操作:通过调用预编写的与S2的加密相对应的解密函数进行解密,在本实施例中,所述解密函数统称为DLL解密函数。
特别的,编写DLL解密函数后,将对其属性设置为页面对齐,因为只有被设置成页面对齐的函数才能确保在后续的加壳阶段,被加壳工具进行无损的二进制修改。所述调用具体添加在Mono的载入DLL函数里。
S54:添加反调试线程至Mono项目;
本实施例同时提供两种反调试方式供用户依据需求进行灵活选择:
第一种,是在Mono项目的每个关键函数内部增加时间判断,超过限定执行时间则判定对应的关键函数为被调试;
第二种,是在初始阶段新建线程,内部死循环进行各种条件判断,具体的条件判断含有但不限于以下几种:
1、根据/proc/net/tcp命令显示所有正在进行TCP连接的命令,检测当前系统占用端口是否含有调试器的默认端口号,如果含有就异常退出;
2、根据ps命令(即显示所有正在运行的进程的命令),检测当前系统启动的进程名是否含有调试器的包名或者进程名,如果含有就异常退出。
3、根据/proc/self/cmdline(即显示本进程状态的命令),检测自身的父进程是否为zygote,如果不是就异常退出;
4、根据proc/self/status(即显示本进程状态的命令),获取TracerPid判断是否为0,如果不是就异常退出;
5、根据getprop ro.secure(即获取系统属性),查看是否在管理员权限下运行的命令,判断返回值是否为0,如果不是就异常退出。
所述的异常退出,即代表应用存在被调试的情况,通过退出执行,保证应用安全。
S55:添加对所述DLL解密函数进行脱壳的方法至Mono项目。
由于后续会使用加壳应用将DLL解密函数进行加壳,所以需要在Mono的构造调用阶段对DLL解密函数进行脱壳,这样当Mono在运行时的载入DLL阶段,才能顺利调用DLL解密函数来解密DLL文件。
S6:重编译配置后的Mono项目;
重新编译Mono工程后将生成全新的含有自脱壳、反调试以及能解析被加固的Dll文件的libmono.so文件。
S7:对重编译后的Mono项目中的所述DLL解密函数进行加壳;
可以通过加壳工具对DLL解密函数以及其他关键函数进行加壳,具体的加壳方式与预先配置在Mono工程内的脱壳方法(上述S55)相对应。
S8:删除或随机变换加壳后的Mono项目中的节信息。
优选的,所述节信息为指定的Section的起始地址、内存偏移地址和长度。以此防止逆向应用通过地址跳转找到对应函数进行静态分析,该操作能对逆向应用造成混乱;同时,由于只对指定的节信息进行处理,能提高安卓高版本的兼容性。
S9:将加固后的Mono和加密后的DLL文件替换原来未被加固的文件,之后再进行打包和签名。
实施例二
请参照图3至图8,本实施例在实施例一的基础上做进一步扩展,使其还能同时兼容高版本的安卓机型,从而具备同时克服源码被还原、静态分析以及兼容性差等问题。
与实施例一相同的部分在此不进行复述,区别在于,本实施例将在上述(二)深度改造Mono阶段,分别对实施例一的“S7:对重编译后的Mono项目中的所述DLL解密函数进行加壳”以及“S55:添加对所述DLL解密函数进行脱壳的方法”的具体实现方式做进一步限定。具体限定为通过使用连接视图查找动态符号表的方式对DLL解密函数进行加壳和脱壳,使得解密函数的算法地址无需再存于头部,由此避免对高版本安卓记性的不兼容问题。
针对S7:对重编译后的Mono项目中的所述DLL解密函数进行加壳。
由于安卓下的Mono会编译成动态库文件,在非运行时可以使用连接视图对其进行加壳。加壳工具的主要执行流程如图3所示,具体的流程包括:
打开libmono.so文件,使用连接视图来分析,ELE格式的连接视图和对应格式内的简化流程如图4所示。具体的,首先,找到ELF Header(即ELF头)内的Section Header Table(即节头表)的起始地址和数量,以及各个Section(即节)名称索引的起始地址;然后,遍历Section Header Table(即图4中的SHT),根据各个Section的名称索引地址获得各个Section名称,从中查找.dynstr和.dynsym(即动态符号表)这两个Section的起始地址和长度;然后,获取.dynsym内的函数数量,之后遍历每个函数的名称索引,并从.dynstr(每个函数的名称保存在.dynstr段中)中同时获取函数名称,与待加壳的关键函数名进行比较,如果匹配,则获取该函数的起始地址和长度;然后,对数据块进行高级对称算法加密;最后,将加密后数据写回原函数的数据块内。
上述整个操作流程叫做“加壳”,其包含了找符号,然后对符号的函数数据块进行加密。“脱壳”的区别只在于最后是对找到的函数数据块进行解密。
在本实施例中,优选的,还将对实施例一的S8做进一步的限定,具体限定如下:
为了防止libmono.so被逆向应用快速静态分析,在非运行时使用连接视图查找Section Header Table(节头表)的起始地址和Section的总数量以及每个Section名称的起始地址之后,还包括:遍历Section Header Table找到要删除的指定的Section名称,具体有:.interp、.hash、.rel.dyn、.rel.plt、.plt、.text、.cpde、.rodata、.init_array、.fini_array、.got、.data。如图5所示,在Section Header Table里置0或者随机变换上述节头的起始地址、内存偏移地址和长度信息,图中框出的部分即为需要进行处理的部分。
更优的,其自定义的Section的地址和长度信息也可以删除。
针对S55:添加对所述DLL解密函数进行脱壳的方法。
由于上述加壳,对DLL解密函数进行了加壳,所以需要在Mono的构造调用阶段对该函数进行脱壳,这样当Mono在运行时载入Dll时才能顺利解密。
请参阅图6,具体的脱壳流程如下:
获取libmono.so文件;具体为:从/proc/self/maps(即显示当前进程的内存空间映射表)中获取当前进程映射的内存区域与访问权限,在其中找到自身文件名libmono.so,获取其在内存区域内的起始和结束地址。
由于安卓下的Mono会编译成动态库文件,在被加载到内存后,需要分析ELF格式中的执行视图。简略的ELF执行视图格式和对应脱壳的格式内流程如图7所示。具体的分析流程如下:
首先,根据上述获取的内存起始地址从ELF Header(即ELF头)中得到ProgramHeader Table(即程序头表)的起始地址;然后,需要在Program Header Table中查找偏移地址为0的类型为PT_LOAD的段的虚拟内存相对地址来校正libmono.so在内存的起始地址。
之后,查找类型为PT_DYNAMIC的段,从中获取到.dynamic节的起始地址和长度;再然后,遍历其内容得到.strtab,.symtab,.dynstr,.dynsym,.rel.dyn,.rel.plt,.hash,.gnu.hash等Section的内存起始地址和长度;
再然后,遍历.dynstr以及.strtab,具体遍历所述strtab中的每个函数,并从所述dynstr中获取当前遍历到的函数对应的函数名称,匹配所述函数名称与待脱壳的DLL解密函数的名称,若匹配成功,得到该函数在符号表中的索引值,依据索引值得到需要脱壳的函数的内存地址和长度。
最后,进行解密操作,分以下步骤:确认需脱壳的函数的内存地址和长度的内存访问权限,保存权限状态,然后增加写入的访问权限;之后,对函数数据进行算法解密;然后,还原该段数据的内存访问权限;最后,清除该段数据在内存页的处理器指令缓存,使处理器重新从内存中读取这段指令。
优选地,对于某些关键函数的动态脱壳、执行函数和加壳,只要在执行完该函数后再将最后的解密操作改成加密操作即可。其脱壳步骤将不在构造调用阶段执行。动态脱壳可以有效防止libmono.so在运行时阶段被内存镜像到外部存储进行分析。
本实施例增加的内容采取了动态地在符号表里查找函数地址的方式来对函数进行脱壳,使其能适用于高版本安卓对ELF格式筛查的严格要求。而本实施例所述的方案应用的Unity安卓应用中,有效抵御各类逆向应用的静态分析和还原源码,并且在高版本安卓机型上依然能正常运行,在Top100的机型中兼容性达到百分之百。
本实施例不仅可以应用到Unity安卓游戏,在所有的基于Mono编译的Unity安卓应用中,都可以采用该方案进行加固,都可在实际项目操作中得到了很好的实践检验。如图8所示,加固后的应用反汇编失效。
实施例三
本实施例对应实施例二,提供一具体运用场景:
方案针对使用Mono编译的且在安卓设备上运行的Unity应用或者游戏进行加固保护的方法。
首先,针对每个Unity版本的Mono工程生成一份加固后的libmono.so文件。具体是先获取Mono开源项目的源码,然后对Mono源码中添加判断载入的Dll是否含有加固标记,是则跳过判断Dll特征值的函数。
然后,增加对Dll文件进行解密的函数,并且对于该步骤所涉及的函数或者自认为需要加壳的关键函数的属性都设置成页面对齐。
然后,添加构造方法,构造方法内使用动态查找字符表方式找到被加壳的函数,然后进行脱壳。
为了防止脱壳和解密函数被逆向应用分析,还需要在构造方法内增加反调试线程。
最后,重新编译Mono项目生成libmono.so文件。
还需要编写一个加壳工具,对libmono.so中的已设置成页面对齐的Dll解密函数或者自定义需要加壳的关键函数进行加壳。加壳即使用连接视图对函数的符号表进行查找,然后找到函数数据进行加密。
然后,对指定的Section地址和长度信息进行置0或随机变换,得到最终已加固的libmono.so。
然后,再根据方案开发出一套加固工具,对Unity应用或者游戏Apk进行加固。工具源码将只有处理Dll的代码,而没有对Mono加固的代码,对于libmono.so文件将进行文件替换,以此提高安全性。
工具包含现有的zip解包技术对应用或者游戏Apk进行解压缩,提取出里面的Dll和libmono.so文件。
之后,可以根据方案指导对Dll删除特征值,然后对Dll进行加密,加入已加固标记,然后替换原来的Dll文件。
之后,获取该应用或者游戏的Unity版本号,对libmono.so替换成对应Unity版本且已预先加固的libmono.so。
最后,利用现有的zip打包技术还原成Apk文件。
当已加固的Unity应用或游戏运行时,会首先载入libmono.so,然后会调用libmono.so的构造方法,构造方法内会开启反调试线程,防止逆向应用动态调试;再使用动态查找符号表方式找到指定的函数进行解密;之后libmono.so会载入各种需要的Dll文件,根据Dll文件是否包含已加固的标记进行解析,如果发现已加固标记,则先对Dll进行算法解密,之后跳过后续各种Dll特征值的判断,使其正确执行。
实施例四
本实施例对应实施例一至实施例三,提供一种计算机可读存储介质,其上存储有计算机程序,所述程序在被处理器执行时,能实现上述实施例一至实施例三任意一个实施例所述的基于Mono的Unity安卓应用加固方法所包含的步骤。具体的步骤内容在此不进行复述,详细请参阅实施例一至实施例三的记载。
综上所述,本发明提供的基于Mono的Unity安卓应用加固方法、存储介质,能有效抵御各类逆向应用的还原源码和静态攻击,同时还能兼容高版本安卓机型,从而显著提高应用的安全性和加固方法的兼容性。
以上所述仅为本发明的实施例,并非因此限制本发明的专利范围,凡是利用本发明说明书及附图内容所作的等同变换,或直接或间接运用在相关的技术领域,均同理包括在本发明的专利保护范围内。

Claims (13)

1.基于Mono的Unity安卓应用加固方法,其特征在于,包括:
删除或随机变换DLL文件中的特征码和关键寻址地址;
加密删除或随机变换后的DLL文件,得到已加固的DLL文件;
配置Mono项目运行时,若识别到载入的是所述已加固的DLL文件,则执行包括:跳过特征值判断函数;调用预存储的对应所述加密的DLL解密函数;执行反调试线程;对所述DLL解密函数进行脱壳;
重编译配置后的Mono项目;
对重编译后的Mono项目中的所述DLL解密函数进行加壳;
删除或随机变换加壳后的Mono项目中的节信息。
2.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述对重编译后的Mono项目中的所述DLL解密函数进行加壳,具体为:
使用连接视图对函数的动态符号表进行查找,获取重编译后的Mono项目中的所述DLL解密函数;加密所述DLL解密函数;
所述对所述DLL解密函数进行脱壳,具体为:
通过查找动态符号表,获取加密后的DLL解密函数,并对其进行解密。
3.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,还包括:
对已加固的DLL文件置入预设的加固标识;
Mono项目运行时,依据所述加固标识识别出已加固的DLL文件。
4.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述配置,具体为:
添加Mono项目识别载入的是否为所述已加固的DLL文件的方法;
添加若识别为载入的是所述已加固的DLL文件,则删除Mono项目的特征值判断函数的方法;
添加在DLL文件载入时调用预存储的对应所述加密的DLL解密函数的方法;
添加反调试线程至Mono项目;
添加对所述DLL解密函数进行脱壳的方法至Mono项目。
5.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述删除或随机变换DLL文件中的特征码和关键寻址地址,具体为:
分析windows的PE文件结构,依次执行包括:
删除或随机变换Net表内Meta数据流的特征名称;
删除或随机变换Net表内Meta数据头的特征签名和版本号;
删除或随机变换节表头内除内存偏移地址、文件偏移地址、数据长度、块属性以外的数据;
删除或随机变换Net头内Optional头中的Magic特征签名符号;
删除或随机变换Net头内的特征签名;
删除或随机变换Dos头内除指向NT头的偏移地址以外的其他数据。
6.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述调用预存储的对应所述加密的DLL解密函数,具体为:
Mono项目的载入DLL函数调用预存储的对应所述加密且属性设置为页面对齐的DLL解密函数,对已加固的DLL文件进行解密。
7.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述执行反调试线程,具体为:
通过预设在Mono项目的每个关键函数内部的时间判断方法,判断关键函数的执行时间是否超过阈值,若超过阈值,则判定对应的关键函数被调试。
8.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述执行反调试线程,具体为:
通过循环执行预设在Mono项目内部的两个以上的反调试线程,判断Mono项目的关键函数是否被调用;其中,所述反调试线程包括:
检测当前系统占用端口是否含有调试器的默认端口号;
检测当前系统启动的进程的进程名中是否含有调试器的包名或者进程名;
检测当前系统启动的进程的父进程是否不为zygote进程;
检测当前系统启动的进程的进程状态,判断TracerPid是否不为0;
检测当前系统属性,查看命令是否在管理员权限下运行,判断返回值是否不为0。
9.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述对重编译后的Mono项目中的所述DLL解密函数进行加壳,具体为:
打开重编译后得到的libmono.so文件;
使用连接视图解析libmono.so文件中的ELF头,获取节头表的起始地址、节数量以及各个节名称索引的起始地址;
依据节头表的起始地址和节数量,遍历节头表,获取各个节名称索引的起始地址对应的各个节名称;
依据各个节名称获取dynstr和动态符号表;
遍历动态符号表中的每个函数,从所述dynstr中获取当前遍历到的函数对应的函数名称,并匹配所述函数名称与待加壳的DLL解密函数的名称,若匹配成功,则对当前遍历到的函数的数据块进行加密。
10.如权利要求9所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述删除或随机变换加壳后的Mono项目中的节信息,具体为:
依据节头表的起始地址和节数量,遍历节头表,获取其中包括interp、hash、rel.dyn、rel.plt、plt、ext、cpde、rodata、init_array、fini_array、got以及data的节;
将所述节对应的起始地址、内存偏移地址和长度信息进行删除或随机变换。
11.如权利要求1所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述对所述DLL解密函数进行脱壳,具体为:
获取libmono.so文件;
使用连接视图解析libmono.so文件中的ELF头,获取程序头表;
获取程序头表中的dynamic节,遍历其内容得到dynstr和strtab;
遍历所述strtab中的每个函数,从所述dynstr中获取当前遍历到的函数对应的函数名称,并匹配所述函数名称与待脱壳的DLL解密函数的名称,若匹配成功,则获取当前遍历到的函数对应动态符号表的索引值;
依据所述索引值从动态符号表中获取待脱壳的函数数据块;
解密所述待脱壳的函数数据块。
12.如权利要求11所述的基于Mono的Unity安卓应用加固方法,其特征在于,所述解密所述待脱壳的函数数据块,具体为:
修改所述待脱壳的函数数据块的内存读写权限;
对所述待脱壳的函数数据块进行解密;
还原所述待脱壳的函数数据块的内存读写权限;
清除所述待脱壳的函数数据块在内存页的指令缓存。
13.一种计算机可读存储介质,其上存储有计算机程序,其特征在于,所述程序在被处理器执行时,能实现上述权利要求1-12任意一项所述的基于Mono的Unity安卓应用加固方法所包含的步骤。
CN201910292296.1A 2019-04-12 2019-04-12 基于Mono的Unity安卓应用加固方法、存储介质 Active CN110096853B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201910292296.1A CN110096853B (zh) 2019-04-12 2019-04-12 基于Mono的Unity安卓应用加固方法、存储介质

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201910292296.1A CN110096853B (zh) 2019-04-12 2019-04-12 基于Mono的Unity安卓应用加固方法、存储介质

Publications (2)

Publication Number Publication Date
CN110096853A true CN110096853A (zh) 2019-08-06
CN110096853B CN110096853B (zh) 2022-10-21

Family

ID=67444731

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201910292296.1A Active CN110096853B (zh) 2019-04-12 2019-04-12 基于Mono的Unity安卓应用加固方法、存储介质

Country Status (1)

Country Link
CN (1) CN110096853B (zh)

Cited By (8)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111046349A (zh) * 2019-12-16 2020-04-21 北京智游网安科技有限公司 一种so库文件加固识别方法、智能终端及存储介质
CN111625784A (zh) * 2020-05-29 2020-09-04 重庆小雨点小额贷款有限公司 一种应用的反调试方法、相关装置及存储介质
CN111967002A (zh) * 2020-07-09 2020-11-20 国家计算机网络与信息安全管理中心 一种应用程序的加壳检测方法及装置
CN112559097A (zh) * 2020-12-28 2021-03-26 北京深思数盾科技股份有限公司 函数调用方法、装置及计算机可读存储介质
CN112800418A (zh) * 2020-12-31 2021-05-14 北京深思数盾科技股份有限公司 自定义程序集的文件保护方法及装置
CN113239380A (zh) * 2021-05-21 2021-08-10 杭州弗兰科信息安全科技有限公司 一种保护文件读写方法、装置、电子设备和存储介质
CN113886774A (zh) * 2021-12-07 2022-01-04 北京微步在线科技有限公司 一种反调试方法及装置
CN113987471A (zh) * 2021-10-29 2022-01-28 山西大鲲智联科技有限公司 可执行文件执行方法、装置、电子设备和计算机可读介质

Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20080222734A1 (en) * 2000-11-13 2008-09-11 Redlich Ron M Security System with Extraction, Reconstruction and Secure Recovery and Storage of Data
CN103617401A (zh) * 2013-11-25 2014-03-05 北京深思数盾科技有限公司 一种数据文件保护方法及装置
CN104978522A (zh) * 2014-04-10 2015-10-14 北京启明星辰信息安全技术有限公司 一种检测恶意代码的方法和装置
CN106022130A (zh) * 2016-05-20 2016-10-12 中国科学院信息工程研究所 加固应用程序的脱壳方法及装置
CN106846442A (zh) * 2017-03-06 2017-06-13 西安电子科技大学 基于Unity3D的三维虚拟人群场景生成方法
CN107908964A (zh) * 2017-10-17 2018-04-13 珠海金山网络游戏科技有限公司 一种针对Android平台Unity3D游戏中加壳文件的安全检测方法及装置

Patent Citations (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20080222734A1 (en) * 2000-11-13 2008-09-11 Redlich Ron M Security System with Extraction, Reconstruction and Secure Recovery and Storage of Data
CN103617401A (zh) * 2013-11-25 2014-03-05 北京深思数盾科技有限公司 一种数据文件保护方法及装置
CN104978522A (zh) * 2014-04-10 2015-10-14 北京启明星辰信息安全技术有限公司 一种检测恶意代码的方法和装置
CN106022130A (zh) * 2016-05-20 2016-10-12 中国科学院信息工程研究所 加固应用程序的脱壳方法及装置
CN106846442A (zh) * 2017-03-06 2017-06-13 西安电子科技大学 基于Unity3D的三维虚拟人群场景生成方法
CN107908964A (zh) * 2017-10-17 2018-04-13 珠海金山网络游戏科技有限公司 一种针对Android平台Unity3D游戏中加壳文件的安全检测方法及装置

Cited By (11)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111046349A (zh) * 2019-12-16 2020-04-21 北京智游网安科技有限公司 一种so库文件加固识别方法、智能终端及存储介质
CN111625784A (zh) * 2020-05-29 2020-09-04 重庆小雨点小额贷款有限公司 一种应用的反调试方法、相关装置及存储介质
CN111625784B (zh) * 2020-05-29 2023-09-12 重庆小雨点小额贷款有限公司 一种应用的反调试方法、相关装置及存储介质
CN111967002A (zh) * 2020-07-09 2020-11-20 国家计算机网络与信息安全管理中心 一种应用程序的加壳检测方法及装置
CN112559097A (zh) * 2020-12-28 2021-03-26 北京深思数盾科技股份有限公司 函数调用方法、装置及计算机可读存储介质
CN112559097B (zh) * 2020-12-28 2021-12-28 上海纬百科技有限公司 函数调用方法、装置及计算机可读存储介质
CN112800418A (zh) * 2020-12-31 2021-05-14 北京深思数盾科技股份有限公司 自定义程序集的文件保护方法及装置
CN112800418B (zh) * 2020-12-31 2022-05-13 北京深思数盾科技股份有限公司 自定义程序集的文件保护方法及装置
CN113239380A (zh) * 2021-05-21 2021-08-10 杭州弗兰科信息安全科技有限公司 一种保护文件读写方法、装置、电子设备和存储介质
CN113987471A (zh) * 2021-10-29 2022-01-28 山西大鲲智联科技有限公司 可执行文件执行方法、装置、电子设备和计算机可读介质
CN113886774A (zh) * 2021-12-07 2022-01-04 北京微步在线科技有限公司 一种反调试方法及装置

Also Published As

Publication number Publication date
CN110096853B (zh) 2022-10-21

Similar Documents

Publication Publication Date Title
CN110096853A (zh) 基于Mono的Unity安卓应用加固方法、存储介质
US9659157B2 (en) Systems and methods for watermarking software and other media
EP1410150B1 (en) Protecting software applications against software piracy
US7739737B2 (en) Method and apparatus to detect malicious software
US7870396B2 (en) Storage medium, method, and apparatus for creating a protected executable program
KR101719635B1 (ko) 동적 함수 호출 시스템들에서 공격적인 자기-수정을 위한 시스템 및 방법
US8176473B2 (en) Transformations for software obfuscation and individualization
US7409718B1 (en) Method of decrypting and analyzing encrypted malicious scripts
US8452740B2 (en) Method and system for security of file input and output of application programs
CN108932406A (zh) 虚拟化软件保护方法和装置
US11250110B2 (en) Method to secure a software code
CN106650327A (zh) 基于动态恢复so文件的Android应用加固方法
CN111881449A (zh) 恶意代码辅助分析方法及装置
US11256786B2 (en) Method to secure a software code
CN110472425A (zh) 基于Mono的Unity插件加密方法、存储介质
US20080127038A1 (en) Apparatus and method for detecting self-executable compressed file
CN104615935B (zh) 一种面向Xen虚拟化平台的隐藏方法
US9965621B2 (en) Program protection device
Rogers et al. DEFENSIVE BINARY CODE INSTRUMENTATION TO PROTECT AGAINST BUFFER OVERFLOW ATTACKS
Balachandran Software protection through obfuscation
Oakley Exploiting the Hard-Working DWARF: Trojan and Exploit Techniques Without Native Executable Code
Jhi et al. VaPD: A Value-Based Approach to Obfuscation-Resilient Software Plagiarism Detection

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant