目前加固对于App开发人员来说,不管是App Store的审核4.3问题,还是为了防止逆向工程、篡改、反编译等问题,加固都算是一个必备的选择了。

但是加固技术在一步步升级的同时,其固有的安全缺陷和兼容性问题却始终未能得到解决。

目前,加固技术已经发展到第五代--虚机源码保护,使用代码类型更广泛,App保护级别更高,兼容性更强。那么,这一波技术升级,能解决上面的安全和兼容性问题吗?我们先挨个看看各代技术的优势和缺陷吧。

第一代加固技术:动态加载

第一代加固技术中的动态加载功能通常被用于保护应用程序中的核心代码,以及防止恶意攻击者对代码进行反编译、逆向工程等操作。动态加载功能通常包括以下几个步骤:

1.加密:将应用程序中的核心代码进行加密处理,以防止恶意攻击者对代码进行解密操作。

2.动态加载:在应用程序启动时,动态加载器会将加密后的代码加载到内存中,并对其进行解密操作。

3.代码完整性检查:在加载代码后,动态加载器会对代码进行完整性检查,以确保代码没有被篡改或修改。

4.运行时保护:在应用程序运行期间,动态加载器会对代码进行保护,以防止攻击者利用漏洞对代码进行攻击或修改。

核心代码

用Java代码简单写了一个动态加载的核心代码:

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;public class DynamicLoader {private static final String KEY = "mysecretkey"; // 加密密钥private static final String FILE_PATH = "/path/to/encrypted/code"; // 加密后的代码文件路径private static final String MD5_CHECKSUM = "1234567890abcdef1234567890abcdef"; // 加密前的代码的MD5校验和public static void main(String[] args) throws Exception {byte[] encryptedCode = loadEncryptedCode(); // 加载加密后的代码byte[] decryptedCode = decrypt(encryptedCode); // 解密代码checkCodeIntegrity(decryptedCode); // 检查代码完整性runCode(decryptedCode); // 运行代码}// 加载加密后的代码private static byte[] loadEncryptedCode() throws Exception {File file = new File(FILE_PATH);FileInputStream fis = new FileInputStream(file);byte[] buffer = new byte[(int) file.length()];fis.read(buffer);fis.close();return buffer;}// 解密代码private static byte[] decrypt(byte[] encryptedData) throws Exception {Cipher cipher = Cipher.getInstance("AES");SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), "AES");cipher.init(Cipher.DECRYPT_MODE, keySpec);return cipher.doFinal(encryptedData);}// 检查代码完整性private static void checkCodeIntegrity(byte[] code) throws Exception {MessageDigest md = MessageDigest.getInstance("MD5");byte[] checksum = md.digest(code);String hex = bytesToHex(checksum);if (!hex.equals(MD5_CHECKSUM)) {throw new Exception("Code has been modified");}}// 运行代码private static void runCode(byte[] code) throws Exception {// 通过反射执行代码Class<?> clazz = new MyClassLoader().defineClass(null, code, 0, code.length);clazz.getDeclaredMethod("run").invoke(null);}// 将字节数组转换为十六进制字符串private static String bytesToHex(byte[] bytes) {StringBuilder sb = new StringBuilder();for (byte b : bytes) {sb.append(String.format("%02x", b));}return sb.toString();}// 自定义ClassLoader,用于加载解密后的代码private static class MyClassLoader extends ClassLoader {public Class<?> defineClass(String name, byte[] code, int off, int len) {return super.defineClass(name, code, off, len);}}}

PS0:由于动态加载的实现方式可能因操作系统等因素而异,以上代码示例仅供参考,不能直接用于实际应用。(自己根据需求更改)

PS1:【multidex组件的加固原理】:Android的DEX文件在设计之初程序普遍较小,所以在DEX文件设计时,只允许包含65535个函数引用。而随着Android应用的发展,大量的应用的代码已经超过了65535的限制,为了解决这个问题,Android5.0之后原生支持加载多个dex,而为了对旧版本的兼容,Android提供了multidex组件。该组件的实现原理与上面介绍的是一致的。

缺陷和对抗

第一代加固技术的缺陷是依赖Java的动态加载机制,而这个机制要求关键逻辑(Payload)部分必须解压,并且释放到文件系统,这就给了攻击机会去获取对应的文件。虽然可以通过关键逻辑(Payload)被加载后,被从文件系统删除,用于防止被复制,但是攻击者可以拦截对应的删除函数,阻止删除。

而关键逻辑(Payload)会被加密后保存,可用于对抗静态分析,但是攻击者可以通过自定义虚拟机,拦截动态加载机制所使用的关键函数,在这个函数内部,复制文件系统中的关键逻辑(Payload)文件。

第二代加固技术—不落地加载

第二代加固技术——不落地加载(Non-Resident Load,简称NRL)技术是一种加固技术,用于保护软件代码免受反向工程和恶意代码注入等攻击。它的核心思想是将软件代码分为两部分:一个不需要保护的加载器和一个需要保护的主程序,加载器负责将主程序加载到内存中并执行,主程序则通过加密和混淆等方式保护代码的安全性。

相比于动态加载,不落地加载在APK修改方面已经完善,能做到对开发的零干扰。

主要流程

NRL技术的主要流程如下:

1.加载器加载:加载器先将主程序的加密部分解密,然后将解密后的主程序加载到内存中。这个过程中,加载器需要读取主程序文件并将其解密。

2.反调试:为了防止被调试,主程序需要执行一些反调试的操作。例如,它可以检测调试器是否存在,或者检测是否有其他程序在对其进行调试。

3.解密和解压:主程序在内存中运行之前,需要进行解密和解压缩。这个过程中,主程序会调用相应的解密和解压缩函数,对自身进行解密和解压缩。

4.恢复IAT:IAT(Import Address Table)是用于动态链接库中的函数导入的数据结构,它记录了函数在内存中的地址。为了保护代码,主程序需要恢复IAT,并将函数地址解密和更新到IAT中。

5.启动主程序:主程序经过以上的准备工作之后,可以开始执行了。

核心代码

以下是一个不落地加载的核心代码示例,使用AWS Lambda作为后端处理函数。

在本示例中,使用AWS Lambda处理来自API网关的HTTP请求。API网关是一个完全托管的服务,可以将HTTP请求路由到不同的AWS Lambda函数。

要使用这个示例,需要一个AWS账户和AWS CLI(命令行界面)。

首先,创建一个新的Lambda函数:

  1. 打开AWS控制台,进入AWS Lambda控制台。
  2. 单击“创建函数”,然后选择“从模板创建函数”。
  3. 选择“api-gateway-authorizer-python”模板。
  4. 输入函数名称,并选择一个可用的区域。
  5. 单击“创建函数”。

接下来,创建一个API网关:

  1. 打开AWS控制台,进入API Gateway控制台。
  2. 单击“创建API”,然后选择“REST API”。
  3. 选择“新API”并输入API名称。
  4. 单击“创建API”。

现在,将API网关与Lambda函数关联:

  1. 在API Gateway控制台中,选择您创建的API网关。
  2. 在左侧菜单中,选择“资源”。
  3. 单击“创建资源”。
  4. 输入资源名称,并单击“创建资源”。
  5. 选择新创建的资源,并在“操作”下拉菜单中选择“创建方法”。
  6. 选择“POST”方法,并单击“确认”。
  7. 在“POST - Setup”页面中,选择“使用Lambda代理集成”并选择您的Lambda函数。
  8. 单击“保存”。

ok,我们已经将API网关与Lambda函数关联,并准备好处理来自API网关的HTTP请求。

下面是一个示例代码,用来处理Lambda函数中的请求,计算两个数字的和:

import jsondef lambda_handler(event, context):# 解析请求正文中的JSON数据body = json.loads(event['body'])num1 = int(body['num1'])num2 = int(body['num2'])# 计算两个数字的和result = num1 + num2# 返回结果response = {"statusCode": 200,"body": json.dumps({"result": result})}return response

缺陷与对抗

不落地加载技术并不是完美的,存在一些缺陷和对抗方法:

  1. 病毒和恶意软件可能会利用不落地加载技术来隐藏它们自己的代码,从而避免被杀毒软件和安全监测系统检测到。相应的对抗包括使用反病毒软件和安全监测系统来检测和清除恶意软件。
  2. 在使用不落地加载技术时,应用程序的代码和数据是以明文形式存储在磁盘上的,这意味着攻击者可以轻松地使用工具来查看或修改这些数据。相应的对抗包括对于需要保护的敏感数据和代码,可以使用加密技术来保护它们以及使用虚拟化技术来隔离应用程序的运行环境,以防止恶意软件修改应用程序的代码和数据和使用硬件安全模块(HSM)来保护关键数据和代码,以防止它们被未经授权的人员访问和修改。
  3. 一些恶意软件会通过修改系统配置文件或在启动过程中拦截不落地加载技术来绕过它的保护。相应的对抗包括实施安全的启动过程,包括使用数字签名验证和安全启动链(Secure Boot),以确保系统和应用程序的完整性和安全性。

第三代加固技术—指令抽离

由于第二代加固技术仅仅对文件级别进行加密,其带来的问题是内存中的Payload是连续的,可以被攻击者轻易获取。第三代加固技术对这部分进行了改进,将保护级别降到了函数级别。

指令抽离技术是一种安全性较高的代码加固技术,它将敏感指令从程序代码中提取出来,形成一个独立的指令库,程序运行时通过调用这个指令库来完成敏感操作,从而避免了指令在程序中明文存在的风险。

指令抽离技术的加固流程:

  1. 分析程序代码,确定哪些指令需要抽离。通常来说,涉及加密、解密、授权认证、协议处理等敏感操作的指令都需要被抽离。
  2. 编写指令库,将敏感指令实现为一个独立的代码库,并进行加密处理,确保指令库的安全性。
  3. 修改程序代码,将敏感指令的调用替换为调用指令库中的相应指令。
  4. 对指令库进行签名和校验,确保指令库的完整性和安全性。
  5. 隐藏指令库的位置和调用方式,增加攻击者的攻击难度。
  6. 对程序进行混淆处理,增加攻击者分析代码的难度。
  7. 对程序进行安全性测试和漏洞扫描,确保程序的安全性。
  8. 对程序进行发布和更新,及时修复已知漏洞,确保程序的持续安全性。

核心代码

展示一个简单的示例代码:

// 原始程序代码
void encrypt(char* data, int len, char* key) {// 执行加密操作
}// 指令抽离后的程序代码
#include "encrypt_lib.h"void encrypt(char* data, int len, char* key) {encrypt_lib(data, len, key);
}

缺陷与对抗

缺陷:

  1. 需要对程序进行修改:指令抽离技术需要对程序进行修改,将敏感指令的调用替换为调用指令库中的相应指令,这可能会影响程序的性能和稳定性。
  2. 增加程序的复杂性:指令抽离技术会增加程序的复杂性和开发难度,需要进行全面的测试和评估,确保加固后的程序仍然满足业务需求和性能要求。
  3. 指令库的安全性:指令库的安全性非常重要,如果指令库被攻击者窃取或篡改,可能导致程序的安全性被破坏。
  4. 反向工程:攻击者可以使用反向工程技术来分析程序和指令库,发现和利用漏洞,从而破坏程序的安全性。

对抗:

  1. 优化指令库:指令库的安全性非常重要,需要采用加密、签名、校验等措施来保护指令库的安全性。
  2. 混淆程序代码:通过对程序代码进行混淆,可以增加攻击者分析代码的难度,从而提高程序的安全性。
  3. 加强安全测试:对程序进行全面的安全测试和漏洞扫描,及时发现和修复安全漏洞,确保程序的安全性。
  4. 多层加密和验证:可以在指令抽离的基础上增加多层加密和验证,从而增加攻击者攻击的难度和成本。

第四代加固技术—指令转换/VMP

第三代加固技术在函数级别的保护,使用Android虚拟机内的解释器执行代码,带来可能被记录的缺陷,第四代加固技术使用自己的解释器来避免第三代的缺陷。而自定义的解释器无法对Android系统内的其他函数进行直接调用,必须使用JAVA的JNI接口进行调用。其主要实现由两种:

A、DEX文件内的函数被标记为native,内容被抽离并转换成一个符合JNI要求的动态库。 动态库内通过JNI和Android系统进行交互。

B、DEX文件内的函数被标记为native,内容被抽离并转换成自定义的指令格式,该格式使用自定义接收器执行,和A一样需要使用JNI和Android系统进行调用。

兼容性第四代VMP加固技术一般配合第三代加固技术使用,所以第三代的所有兼容性问题,指令转换/VMP加固也存在。缺陷与对抗不论使用指令转换/VMP加固的A方案或者B方案,其必须通过虚拟机提供的JNI接口与虚拟机进行交互,攻击者可以直接将指令转换/VMP加固方案当作黑盒,通过自定义的JNI接口对象,对黑盒内部进行探测、记录和分析,进而得到完整DEX程序。

(第四代加固DEX文件恢复)另外,第四代VMP加固技术只实现Java代码保护,没有做到使用VMP技术来保护C/C++等代码,安全保护能力有所欠缺。

下一代加固技术—虚机源码保护

跟第四代的VMP加固技术相比,虚机源码保护加固是用虚机技术保护所有的代码,包括Java,Kotlin,C/C++,Objective-C,Swift等多种代码,具备极高的兼容性;使App得到更高安全级别的保护,运行更加稳定。

虚机源码保护为用户提供一套完整的工具链,首先把用户待保护的核心代码编译成中间的二进制文件,随后生成独特的虚机源码保护执行环境和只能在该环境下执行的运行程序。

虚机源码保护会在App内部隔离出独立的执行环境,该核心代码的运行程序在此独立的执行环境里运行。即便App本身被破解,这部分核心代码仍然不可见。

(虚机源码保护加固流程)生成的虚机源码保护拥有独特的可变指令集,极大的提高了指令跟踪、逆向分析的难度。

同时,虚机源码保护还提供了反调试能力和监控能力。虚机源码保护可以通过自身的探针感知到环境的变化,实时探测到外界对本环境的调试、注入等非正常执行流程变化,将调试动作引入程序陷阱,并发出警报,进而进行实时更新,提高安全强度。

结语

加固技术发展及其攻防对抗的更迭,伴随着互联网技术发展不断升级。

作为“正义”的一方,我们深信邪不能胜正,而虚机源码保护加固作为当前领先的加固技术,在未来很长一段时间,能够为App提供足够强度的保护,为企业和开发者的业务发展保驾护航。

免费试用:加固产品

加固技术一路“升级打怪”,会封顶于第五代虚机源码保护技术吗?相关推荐

  1. APP加固技术历程及未来级别方案:虚机源码保护

    传统App加固技术,前后经历了四代技术变更,保护级别每一代都有所提升,但其固有的安全缺陷和兼容性问题始终未能得到解决.而下一代加固技术-虚机源码保护,适用代码类型更广泛,App保护级别更高,兼容性更强 ...

  2. java源码保护技术,sourceguard

    sourceguard 项目记录了本人对java源码保护的一些探索实践. 项目结构 sourceguard-repack 实现原始jar文件的解包,对目标class文件加密和还原成jar文件 sour ...

  3. 农村出身,半路测试转开发,他一路升级打怪到华为19级B

    上周同学生日,晚上去他家吃饭,饭桌上遇到他的一个小叔,华为虽然已经搬到松山湖去了,他还是住深圳.席间听说前段时间刚升到了华为19级B,由于我也是做技术开发的,于是和他小叔(下文简称老邬)兴趣相投的聊了 ...

  4. 直播视频源码开发技术之平台测试之软件测试侧重点介绍

    随着移动互联网技术日新月异的发展,视频直播市场发生了巨大的变化,直播用户消费内容和交互方式也在不断升级,"全民直播"的开启使得越来越多的互联网创业者或者成熟企业进入视频直播源码开发 ...

  5. 技术人员升级打怪的方法论

    太白上仙自己在带团队方面有着非常充足的经验,由本上仙直接招到公司的小白 coder 中,在 18 年的时候就出了两个阿里的 P8 啦! 而跟着本上仙做过项目成长为 P8 已经有 7 个人了!唯一可惜的 ...

  6. 基于SSM技术的医院在线预约诊疗系统设计与实现 毕业设计-附源码011130

    医院在线预约诊疗系统的设计与实现 摘 要 随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理.在现实运用中,应用软件的工作规则和开发 ...

  7. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | 加固厂商在 ART 下使用的两种类加载器 | InMemoryDexClassLoader 源码 )

    文章目录 一.加固厂商在 ART 下使用的两种类加载器 ( InMemoryDexClassLoader | DexClassLoader ) 二.InMemoryDexClassLoader 源码分 ...

  8. 网站QQ全屏PHP代码,QQ技术导航升级版 超级导航美化版带后台版 PHP源码

    QQ技术导航升级版 超级导航美化版带后台版改进F2样式,主针对QQ教程网.卡盟.博客.提供更好收录的位置.改进QQ技术导航背景,增加整体美观效果.去掉死链页面,站长操作使用更加有扩大空间.优化后台登陆 ...

  9. 资料汇总更新|软件安装包、书籍、源码、技术文档、手册……

    大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注FPGA技术江湖,在"闯荡江湖"."行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢. ...

最新文章

  1. 前端小姐姐助你俘获女神心,双十一挑口红神器在此 | 开源项目
  2. 下列哪个是java的标识符_下列哪个不属于Java的正确标识符?A、publicB、sizeofC、cLAssD、_new...
  3. [链表]---链表相邻元素翻转
  4. CSDN中markdown字体颜色,大小,首行缩进,居中排布
  5. LeetCode 第 27 场双周赛(1125/1966,前57.2%)
  6. 2019值得学习的5种编程语言,程序员来告诉你
  7. 不用Oracle?基于MySQL数据库下亿级数据的分库分表
  8. Spark序列化入门
  9. 包含的前缀数目超过了最大值。最大值为 2_「西法带你学算法」一次搞定前缀和...
  10. [BZOJ4872][六省联考2017]分手是祝愿(期望DP)
  11. FileInputStreamFileOutputStream
  12. 2022年低压电工考试题库及模拟考试
  13. catia 快捷键 激活零件_CATIA教程:CATIA快捷键及学习技巧总结
  14. MicrosoftActiveSync 安装
  15. sap怎么删除服务器文件,SAP服务器的文件管理
  16. studio3下载安装使用
  17. 1300:鸡蛋的硬度
  18. Java---鼠标事件小实例
  19. ROS通信机制一---话题通信
  20. 希利苏斯起始任务_希利苏斯战地任务快速完成方法 大地之击半天入手

热门文章

  1. 如何更详细查看SAP 系统版本信息
  2. HTML5挂号,基于SSH的医院在线挂号
  3. 测绘技能大赛-无人机航测虚拟仿真(外业部分)
  4. POJ 1659【Havel-Hakimi 定理】
  5. 芯片及ASIC设计等
  6. gg 修改器游戏被保护_火柴人战争遗产无敌版修改器下载-火柴人战争遗产修改器手机版下载...
  7. 英特尔Mooly Eden:力压Jeff Bezos的《财富》科技创想家
  8. 存储过程IF --ELSE IF -- END IF 使用
  9. 阿斯利康中国东部总部正式启用;星奕昂生物完成4000万美元天使轮融资 | 医药健闻...
  10. jQuery翻页yunm.pager.js,涉及div局部刷新