Android 应用防止被二次打包方法

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

#####前言
“Android APP二次打包”则是盗版正规Android APP,破解后植入恶意代码重新打包。不管从性能、用户体验、外观它都跟正规APP一模一样但是背后它确悄悄运行着可怕的程序,它会在不知不觉中浪费手机电量、流量,恶意扣费、偷窥隐私等等行为。

二次打包问题只是Android应用安全风险中的一部分, 一般是通过反编译工具向应用中插入广告代码与相关配置,再在第三方应用市场、论坛发布。

对于打包党对于移动App带来的危害有以下几种:

- 插入自己广告或者删除原来广告;
- 恶意代码, 恶意扣费、木马等;
- 修改原来支付逻辑。
上述恶意行为严重危害移动产品和用户利益,同时也影响企业口碑。

关于移动App破解、数据泄露风险问题,以金融行业为例:众所周知数据是金融类应用产品重要资源之一,关乎企业生存与发展、但移动应用经常被破解、数据被抓包,导致本地存储数据以及用户名、密码等重要信息泄露。下面举例说明数据泄露案例。

#####金融类本地存储数据泄漏

#####数据抓包,泄漏用户名和密码

面对二次打包不少公司都有自己的防范措施,知名公司的APP几乎都是自己在程序内部做过处理防止其APP被二次打包,一旦打包后重新运行则程序自动退出。接下来,我就来详解一下如何防止APP被二次打包。

####如何解决移动App安全风险问题?
基于多年的移动安全经验积累,网易云易盾在移动APP安全风险问题上,从起始的开发阶段、中间的测试阶段再到结尾发布阶段,针对移动APP全生命周期进行安全防护。

注‘Android技术交流群752016839,欢迎大家加入交流,畅谈!本群有免费学习资料视频’

开发阶段——移动应用开发时接入安全组件,保护数据安全。其中,针对安全通信方面,实现数据高强度加密,结合传统的对称、非对称加密算法和hash算法,客户端加密数据只有认证服务端才能解密,从而防止了数据泄漏、数据窃取和篡改。另外,为了实现加强数据的安全强度,安全组件结合自适应特征算法和随机切换算法,保证不同时间、不同终端的算法和密钥的差异性。

测试阶段——对移动应用进行人工渗透测试,发现漏洞解决产品修复相关问题,包括:APP渗透测试和服务端渗透测试。

发布阶段——APP上架之前针对应用做安全加固,提高安全防护等级,上架之后做盗版监测。网易云易盾可针对dex文件进行加固防护,防止被静态反编译获取代码逻辑;保护应用在被非法二次打包后不能正常运行;防止通过使用调试器工具对应用进行非法破解;提供自研高稳定的设备指纹,防止潜在的刷单风险;加密资源文件,防止apk资源文件被破解;对so文件进行加固保护,防止native代码被逆向分析;对游戏提供加固保护,让游戏免受破解、外挂等威胁。

要实现代码内部防止APP被二次打包首先得了解APK的机器识别原理,APK的唯一识别是依靠包名和签名来做鉴定的,类似豌豆夹的洗白白、360手机卫士等安全软件对APK的山寨识别,他们就是依赖包名来确定APK然后通过签名来确定其是否山寨。所以说自己的程序内部在启动的时候可以通过获取APK本身的签名然后和正确的签名做对比来识别自己是否被二次打包。
![image.png](https://upload-images.jianshu.io/upload_images/13855150-aad9c6cc6a4203f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
通过PackageManag对象可以获取APK自身的签名。
![image.png](https://upload-images.jianshu.io/upload_images/13855150-fd4583600278e37f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
过对签名的码的分解得到一串20左右的字符串,此字符串则是APK的签名的MD5值,通过获取的签名MD5值与正确的MD5值进行对比,就可以识别其APK是否被盗版。

下图是一些已做过保护的APP的代码块分析:
![image.png](https://upload-images.jianshu.io/upload_images/13855150-1458cb7fe279870d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
上图是“XX省电王“的防止二次打包的关键代码
![image.png](https://upload-images.jianshu.io/upload_images/13855150-3356187e16727f21.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
上图是”XX电池管家”的防止二次打包的关键代码

以上两处都是smali层的代码,以上2处代码的截图都是下载量非常高的APP所做的防止二次打包的处理,其处理的代码肯定会使用到的关键代码是

Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature。

此方法能够起到一定的安全作用,一般的打包党面对它是无可奈何的,如果你了解一些smali语法它的作用就等于0了。

#####Android 应用加固的技术细节
此外,针对如何加固的技术细节问题,网易云资深安全工程师钟亚平在安卓巴士全球开发者论坛的活动中也做过《安卓App逆向与保护》的主题演讲:

安卓App安全包含很多内容,包括混淆代码、整体Dex加固、拆分 Dex 加固、虚拟机加固等方面。事实上,这些内容也是国内近几年Android App安全保护的一种主要趋势。

#####一、混淆代码
Java代码是非常容易反编译的,作为一种跨平台的、解释型语言,Java 源代码被编译成中间“字节码”存储于class文件中。由于跨平台的需要,这些字节码带有许多的语义信息,很容易被反编译成Java源代码。为了很好地保护Java源代码,开发者往往会对编译好的class文件进行混淆处理。

混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。ProGuard就是一个混淆代码的开源项目,能够对字节码进行混淆、缩减体积、优化等处理。

#####Proguard处理流程图如下所示,包含压缩、优化、混淆、预检四个主要环节:

- 1. 压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute);
- 2. 优化(Optimize):对字节码进行优化,移除无用的指令。优化代码,非入口节点类会加上---private/static/final,没有用到的参数会被删除,一些方法可能会变成内联代码;
- 3. 混淆(Obfuscate):使用a、b、c、d这样简短而无意义的名称,对类、字段和方法进行重命名;
- 4. 预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。
#####混淆代码逆向分析

如果想要反编译混淆代码,钟亚平分享了一个国外的工具DEGUADR,它能够通过统计的方式来解混淆。虽然这个工具的正确率达不到100%,但是能在一定程度上帮助反编译代码。

com.xxxxx.common.util.CryptoUtil网站也提供了一种反编译服务,如下所示:
~~~
java.lang.String a(byte[]) -> encodeToString
java.lang.String a(byte[],boolean,java.lang.String) ->a
byte[] a(byte[],byte[]) -> encrypt
byte[] b(byte[]) -> getKey
byte[] b(byte[],byte[]) -> decrypt
byte[] d(java.lang.String) -> getKey
java.lang.String a(byte,char[]) -> a
java.lang.String a(java.io.File) -> getHash
java.lang.String a(java.lang.String) -> c
java.lang.String b(java.lang.String) -> encode
~~~
#####二、整体Dex加固
为了加强Android保护强度,随着安全技术的发展,又出现了新型的“加固技术”。Dex加固是对Dex文件进行加壳防护,防止被静态反编译工具破解而泄露源码,最刚开始出现的是整体加固技术方案。

整体加固技术的原理如上所示,包括替换application/classes.dex、解密/动态加载原classes.dex、调用原application相关方法、将原application对象/名称设置到系统内部相关变量四大环节。其中最为关键的一步就是解密/动态加载原classes.dex,通过加密编译好的最终ex源码文件,然后在一个新项目中用新项目的application启动来解密原项目代码并加载到内存中,再把当前进程替换为解密后的代码,能够很好地隐藏源码并防止直接性的反编译。

#####整体Dex加固逆向分析

整体Dex加固逆向分析有两种常用的方法。其一是在内存中暴力搜索 dexn035,再 dump。以下是在32位系统中的效果示例:

另一种方法就是通过Hook dvmDexFileOpenPartial(void* addr, int len, DvmDex**)。

#####三、拆分Dex加固
随着业务规模发展到一定程度,不断地加入新功能、添加新的类库,代码在急剧膨胀的同时,相应的apk包的大小也急剧增加,那么简单的整体加固方案就不能很好地满足安全需求,在整体加固方案之外又出现了拆分加固的技术方案。

但是如上所示,Dex文件在加固时,针对中间缺失的一部分数据会以解密后的数据来替换,有的时候这种拆分替换也会导致数据不准确。那么到底应该拆分什么样的数据呢?就需要了解一下Dex文件的数据结构。

Dex文件结构极为复杂,以下图示选取了其中较为重要的内容。事实上,Dex文件是一个以class为核心组装起来的文件,其中最重要的是classdata和classcode两部分,有其特定的接口和指令数据,选取这两部分来拆分的话,即使拆分出来也不会泄露class数据和字节码数据,反编译出来也不完整,安全性较高。

#####拆分Dex加固逆向分析

对于Dex拆分加固的逆向分析,如下所示,可以用classdata替换从而组装成新的Dex文件,虽然和原来的Dex文件不会完全一致,但也在一定程度上复原了被拆分数据的样子。

但要注意的是,这种方法仅适用于被拆分出去的数据变形一次性完成,也就是说,在有其他保护思路的情况下尽量避免使用,而且即使有需要也尽量选在用到这个类的时候才去恢复。

此外还有一个更底层一些的工具dexhunter,这个工具较为前卫,但同时也有一些局限性,譬如部分指令数据会被优化,形成的代码界面不是很美观等等。

#####四、虚拟机加固
虚拟机加固也属于Dex拆分加固的一种,它是对字节做了一些变化处理。如下所示,这是一个正常安卓系统中的代码,在其中进行了虚拟机加固操作:

以add-int v0, v1, v2、sub-int v0, v1, v2、mul-int v0, v1, v2这三条指令进行替换,然后进行加固编译,这样子操作后,即使把替换后的数据恢复了,也不会以add-int v0, v1, v2、sub-int v0, v1, v2、mul-int v0, v1, v2这三条指令进行替换,然后进行加固编译,这样子操作后,即使把替换后的数据恢复了,也不会变形成为之前的字节码,安全系数较高。

#####虚拟机加固逆向分析—HOOK JNI 接口

这种方式下的逆向分析,一方面可以通过HOOK JNI 接口来实现,它有两种实现方式。

其一是类成员/静态变量操作相关接口,比如:

GetStaticDoubleField SetStaticDoubleField GetDoubleField SetDoubleField …
(byte, object, int, long…)

其二是反射调用类方法,比如:
~~~
*   CallVoidMethodA CallBooleanMethodA CallShortMethodA CallObjectMethodA …
*   CallStaticVoidMethodA CallStaticBooleanMethodA CallStaticShortMethodA CallStaticObjectMethodA …
*   (byte, int, long,double …)
*   CallObjectMethodA(JNIEnv* env, jobject object, jmethoID method, …)
~~~
通过HOOK JNI 接口实现虚拟机加固逆向分析

通过HOOK JNI 接口不用逆向底层,就可以了解App大致的调用流程。但是对于复杂的调用过程,或者虚拟化方法数量较多的情况,这种逆向分析手段看起来会比较混乱;对于不需要返射到Java层执行的指令,如算术、逻辑运算等,则无法监控到。

#####虚拟机加固逆向分析—分析指令操作码映射

另一方面,也可以通过分析指令操作码映射来逆向分析。在同一加固版本,或者映射关系相同的情况下,可以采取以下所示的方法:

但在实际情况中,每次加固时的映射关系都是随机变化的,如下所示,这种情况下就无法直接建立映射关系。

不依赖于操作码的映射关系只与虚拟机结构有关,所以需要根据偏移关系建立映射关系,从而进行逆向分析。

安卓App逆向保护作为开发工作中的重要内容,一直是网易云易盾致力提供的应用服务。后续,我们将在SO加密保护方面进行更加深入地研究,对SO里面的逻辑进行分析,保护Native代码不被逆向分析

####总结
Android应用做不到完全的防止二次打包。
##### 1、简单型

最简单的就像签名验证。验证编译之后的dex签名,md5等数据。

##### 2、微有点技术含量型

由native在运行时释放class到内存。释放bytes数据直接喂给classloader。

##### 3、难度型

对native本身再进行一些加固,加逆向坑(暗桩)增加破解难度。

##### 4、较难度型

Java代码执行代码的时候调用native操作,实现破解必须破解native部分。

注‘Android技术交流群752016839,欢迎大家加入交流,畅谈!本群有免费学习资料视频’

最后如果需要,部分必要算法转移到云端执行,最大限度的去保证防被破解和二次打包
 

如何防止 Android 应用二次打包 其中,my-release-key.keystore 是 keystore 文件名,my_alias 是数字证书别名,RSA 是使用的加密算法,2048 是密钥大小,validity 是证书有效期。在 Android 应用中集成反调试技术,可以在代码中检测是否处于调试状态,如果是,则采取相应的措施,例如退出应用或者强制关闭调试器。注意,某些设备可能存在定制化 ROM,例如小米、华为等,这些设备的系统属性可能与标准 Android 设备不同,需要进行额外的处理。 阅读详情

相关推荐

Android】逆向开发与反逆向开发入门知识(一)

警告:逆向开发相关知识请在法律规定范围内使用,请勿使用相关技术进行违法犯罪行为。

宾有为的博客 2157

移动开发技术学习资源D

研发团队在本领域有着多年的研究和经验,有成熟的、实际使用的产品。

以Flappy Bird破解为例介绍防止andriod apk反编译方法

很多开发者对apk的安全并不上心,觉得自己的加密技术已经很不错了,接下来我通过对Flappy Bird的安全分析来向大家展示下apk的安全还有哪些需要注意,并为大家介绍一个比较好用的防止andriod apk反编译方法  这款让无数人疯狂和欢喜的移动游戏,是近期大伙热议的焦点!这款游戏风靡全球,这款游戏的开发者也是日进斗金,日收入约5w美元,下面我们就分析下这款游戏的安全性:    首先是二次

tangong517的专栏 1583

Android 应用防止二次打包指南

二次打包问题只是Android应用安全风险中的一部分, 一般是通过反编译工具向应用中插入广告代码与相关配置,再在第三方应用市场、论坛发布。对于打包党对于移动App带来的危害有以下几种:1. 插入自己广告或者删除原来广告;2. 恶意代码, 恶意扣费、木马等;3. 修改原来支付逻辑。上述恶意行为严重危害移动产品和用户利益,同时也影响企业口碑。关于移动App破解、数据泄露风险问题,以金融行业为例:众所周...

网易数帆社区博客 1844

Android app 重打包攻击和应对之策

Although anyone can easily publish Android applications (or apps) in an app marketplace according to an open policy, decompiling the apps is also easy due to the structural characteristics of the ap

shentong1的专栏 3192

Android APP如何防止二次打包

本文转自博客园:爱加密——安卓反编译揭秘(爱加密系列教程九),仅供参考、交流使用!!! Android系统的开放性和免费性等特征让开发者和用户趋之若鹜,用户也渐渐习惯了Android应用的这种免费午餐,但在免费的背后却有着巨大的安全阴影。 “Android APP二次打包”则是盗版正规Android APP,破解后植入恶意代码重新打包。不管从性能、用户体验、外观它都跟正规APP一模一样

Y09lin的专栏 1556

安卓防逆向、防动态分析、渗透测试及加固

五大反逆向技术: 代码混淆、针对不同逆向工具保护技术、增加逆向难度(java代码native化)、动态加载技术、代码验证技术 代码混淆: 工具:proguard 常用操作:保留选项、压缩、优化、混淆。 功能: 混淆代码(注意使用混淆文件的时候需加入自己的具体操作以防程序无法运行) 删除无用Log:可删除调试和分析代码逻辑时的log,也可删除不使用的调试接口和测试环境 问题: 混淆错误:用到第三方j...

weixin_30895603的博客 280

Unity中针对Android Apk的签名验证(C#实现),防止二次打包

本文内容主体转载自:http://www.unitymanual.com/home.php?mod=space&uid=62584&do=blog&id=3148&cid=3949 当Unity开发的游戏以Android Apk的形式发布之后,经常会遇到的一种情况就是别人对我们的游戏进行二次打包,也就是用他们的签名替换掉我们的签名,从而堂而皇之的将胜利果实占为己有。面对这样的情况,我

FoxGame的专栏 1693

加固了就安全了?几个措施让你的 Android 应用更安全

1、背景 最近新开发了一款工具类型的软件 移动工具箱,然而某天下午忽然群里来了一个不速之客说我的软件被破解了。虽然,该软件无需付费并且没有广告(很良心 ???? ),也进行了安全加固,但是还是很轻易得被别人破解了。现象是,启动页换成了别人的页面,需要用户点击页面上的按钮分享几次破解者的信息才能进入应用。并且,每次打开应用都是如此。 看到这我的心情还是非常复杂的。一开始觉得自己做个应用都赚不到钱,还要被这些人利用。本是同根生,相煎何太急呀。然而,转念一想,这里有些东西还是可以学习一下,于是我去他们的链接下载了

你好,开发者 997

APP安全(一)-防二次打包(C、C++签名校验)

前言 由于Android系统的开放性,开发出来的APP很容易被逆向,修改代码逻、加入广告、病毒等二次打包后发布,对开发者和用户造成一定的损失。因此我们的APP运行过程中需要进行签名校验,以及使用加解密算法对数据进行处理,从而保证访问服务端的请求是我们信任的APK。签名校验如果放在Java语言层面,很容易被逆向,因此需要在C/C++层进行校验,从而增加破解的难度。 校验逻辑 APP启动时候初始化我...

mrRuby的博客 2222

安卓常见反破解方式

防止APKTool反编译         APKTool 是常用的APK反编译工具,可以说市场上99%的APK都可以用它反编译出来。XML等样式、配置、页面文件都能完全反编译出来。 首先要从APKTool的来历入手,APKTool是GOOGLE提供的APK编译工具,那么完全基于android原生框架构建的APK都是能被轻易破解的,反编译出来的目录都包括lib、res,assets等。通过改变这

maocaowu_csdn的专栏 474

Android签名机制

Android签名机制 简介 签名可以进行保护。 简介 利用签名比对,避免二次打包应用中获取安装应用签名和自己签名比对,进行保护。但不彻底,不论是应用层,还是native层实现都能被找到并注释掉来实现二次打包。 public static String getSignature(){ Context context = getApplicationContext(); ...

ThePromonkeyOf_HeLuo的博客 257

你发布的Android 应用安全吗?

前言 大家都知道,目前大多数的Android 是用Java语言写的,即使现在Google非常力荐kotlin,但是还有目前很多的项目还是使用Java编写,毕竟一个语言的替换是需要时间。因此,Java代码容易被反编译也是总所周知的,因此自己的防止被反编译还是需要重视的。 主要从四个方面来介绍本文: 1.Proguard混淆 2.对抗反编译工具 3.对抗安卓模拟器 4.对抗apk重打...

技术是个累积的过程 393

获取APK的签名MD5值

近日在360平台上架app,安全等级居然是0分,代码已经混淆了。看到有一项是防止二次打包,于是网上搜,有一篇文章:Android APP如何防止二次打包揭秘 不过最后没有和MD5值比较。下面是我结合网上的其他代码写的: /** * 校验应用签名 * * @param context */ public static boolean checkS

yanxing的专栏 1602

Apk应用文件混淆:Proguard(类文件优化混淆),DexGuard混淆(防二次打包)

> apk文件混淆 Proguard 写给Android开发者的混淆使用手册--http://blog.csdn.net/huihuibisheng/article/details/52928046   Proguard- http://www.saikoa.com/proguard  https://www.guardsquare.com/en/proguard SourceForge上非...

ShareUs的专栏 4034

Android应用程序的保护机制

提高Android应用程序的安全性

zhangquanit的专栏 1997

面试题丨android面试问题合集

加固技术:加固技术是指在应用程序中采取一系列措施,以防止恶意仿冒、非法修改和拆分程序,从而保护应用程序的安全性和完整性。常见的加固技术有代码混淆、签名验证、数据加密和、Root权限控制等。脱壳技术:脱壳技术是一种反编译技术,用于将已经加固过的安卓应用程序反编译为可读的源代码,以便分析和研究应用程序的内部结构和原理。通常,脱壳技术可以分为两大类:静态脱壳技术和动态脱壳技术。静态脱壳技术是指在不执行应用程序的情况下,通过反汇编和反编译来分析应用程序的原始代码;

m0_64973256的博客 1703
上一篇: 第三方框架隔离-移动架构师篇
下一篇: Android利用intent实现分享功能
北辰丶
博客等级 码龄8年 67粉丝 197原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值