以下权限非需要不声明使用
CAMERA:访问相机
READ_EXTERNAL_STORAGE:读取SD卡上的内容
WRITE_EXTERNAL_STORAGE:修改/删除SD卡中的内容
RECORD_AUDIO:录音
READ_CONTACTS:读取联系人数据
前三者通过第三方免费或者付费进行,so加固暂未发现免费渠道
注意点:通过第三方加固后的签名sha1读取对比会返回fales,需要在第三方加固后重新签名,如果是第三方加固有选项记得勾上自动签名,故第三方加固提供签名校验的话自己不需要再写代码验证,验证反而会比对不一致。
app下build.gradle的android->builTypes->release中 minfyEnabled true开启全局混淆
根据代码需求,决定混淆代码是分包混淆还是在app中一起混淆
混淆代码写在proguard-rules.pro中
- #1.基本指令区
- -optimizationpasses 5 #代码进行迭代优化的次数
- -dontusemixedcaseclassnames #指定不同时产生混淆大小写混合的类名
- -dontskipnonpubliclibraryclasses #指定不去忽略非公共的库的类
- -dontskipnonpubliclibraryclassmembers #指定不去忽略非公共的库的类的成员
- #-dontpreverify #android不需要
- -verbose #生成映射文件
- -ignorewarnings #除apk运行时产生的警告导致程序异常终止
- -printmapping proguardMapping.txt #指定映射文件的名称
- -optimizations !code/simplification/cast,!field/*,!class/merging/* #指定混淆时采用的算法,常用的谷歌推荐
- -keepattributes *Annotation*,InnerClasses #保护代码中的Annotation不被混淆
- -keepattributes Signature #避免混淆泛型
- -keepattributes SourceFile,LineNumberTable #抛出异常时保留代码行号
- #2.默认保留区
- -keep public class * extends android.app.Activity
- -keep public class * extends androidx.appcompat.app.AppCompatActivity
- -keep public class * extends android.app.Application
- -keep public class * extends android.app.Service
- -keep public class * extends android.content.BroadcastReceiver
- -keep public class * extends android.content.ContentProvider
- -keep public class * extends android.app.backup.BackupAgentHelper
- -keep public class * extends android.preference.Preference
- -keep public class * extends android.view.View
- -keep class android.support.** {*;}
- -keep public class * extends android.view.View{
- *** get*();
- void set*(***);
- public
(android.content.Context); - public
(android.content.Context, android.util.AttributeSet); - public
(android.content.Context, android.util.AttributeSet, int); - }
- -keepclasseswithmembers class * {
- public
(android.content.Context, android.util.AttributeSet); - public
(android.content.Context, android.util.AttributeSet, int); - }
- -keepclassmembers class * implements java.io
- -keep class com.example.test.JavaBean.** { *; }//.**为该文件夹下所有文件
- -keep class com.example.test.TestBean { *; }//特指TestBean
引用第三方库的,记得加上第三方库提供的混淆内容
注意:Arouter除了它提供的混淆代码,@Route的path路径也是不能被混淆的,如果是用java类集中保存的路径,记得不要混淆
- # 保留Parcelable序列化类不被混淆
- -keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
- # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
- -keepclassmembers class * {
- void *(**On*Event);
- void *(**On*Listener);
- }
5、待补充。。。
WebView.getSettings().setSavePassword(false) 关闭保存密码功能
三个方案:
1、使用webview的activity组件设置不导出,即android:exported=false
2、需要导出,则禁止使用File域:WebView.getSettings.setAllowFileAccess(false)
3、需要File,则禁止调用JavaScript:WebView.getSettings.setJavaScriptEnabled(false)
在Webview加载前
webView.removeJavascriptInterface("searchBoxJavaBridge_");
webView.removeJavascriptInterface("accessibility");
webView.removeJavascriptInterface("accessibilityTraversal");
不会搞。。。
专业密钥白盒,没钱
打包到so里,要加固so,没钱
给了一个动态生成密钥的方法,看了,没屁用,还是存在硬编码
不会
求助于第三方加固反动态调试,没钱
AndroidManifest中,application标签里添加allowBackup=false,关闭数据备份功能
要么还是可以依赖于花了钱的第三方,贫穷啊
有点生气,全是第三方库里调用的,不知道怎么搞,不懂免费加固之后还能不能检测到这个,焦急等待中
android:longClickable=false
怎么说呢,除去登录修改密码啥的,我挺需要复制黏贴的,自己检查吧,敏感页面应当不允许
都是我使用的接口地址
大佬求带
先换了调用方法,通过传参在方法里返回完整的接口,新的报告还没出来,不知道管不管用,待更新
明明是用strings保存“用户名”,“密码”的字样的,根据资源名称含password、pwd、user等被误认为存了真实用户名密码密钥,哼你不智能不跟你计较
但确实,不要在资源文件中储存密码密钥等信息。我用工具破解了免费加固后的APK,资源文件的内容一览无余且百分比正确,不知道付费的能不能保护到位
有条件的,可以加固下资源文件
给每个activity设置android:taskAffinity="" 设置为空
解决方案:由于使用了singleTask,配合taskAffinity=""就会出现上述情况,也就是每个activity的task都不相同
使用setFlags(Intent.FALG_ACTIVITY_SINGLE_TOP|FALG_ACTIVITY_CLEAR_TOP)启动activity来代替launchMode="singleTask"
方法一:通过暴露api的方法来实现startActivity
方法二:通过路由跳转(我使用的ARouter)
方法:使用ARouter时,navigation() 改为 navigation(context)
(PS:看了下源码,当navigation()时,最终的context会被赋值为ARouter初始化sARouter.init(application)中的application,如果调用了navigation(context)最终的context就会赋值为输入的context,而源码中,有这样一个判断,当context不是一个Activity时,intent的FLAG就会设置为singleTask模式,故同样导致了上述问题的存在)
第三方库里,没辙,大佬求带
而且吧,也不都是访问,还有做字符串比较用的,虽然我不懂为什么要这样
救救孩子吧
针对敏感页面onCreate添加代码
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);//在setContentView前调用
如果只需要应用内传递的广播:
1、通过LocalBroadcastManager实现动态注册,数据传递仅限应用内
2、也说可以静态注册BroadcastReceiver,并禁止导出exported=false(未实践)
或者,动态注册registerReceiver时,指定BroadcastReceiver接收时校验permission(未实践):
registerReceiver(BroadcastReceiver, IntentFilter, broadcastPermission,android.os.Handle)
都指向我intent发送广播的代码,是因为new Intent(action) 的action值都保存在java类里的缘故吗?还是我应该写intent.setAction(action) ?
这个,应该不重要吧。。。
第三方能搞,自己也可以搞,但我都加固了,感觉之前还检验模拟器和root有一点点多此一举
注意:
1、由于现在出了鸿蒙系统,检测硬件是否符合真机特征时,android.os.Build.BOOTLOADER值鸿蒙的和模拟器的一样,存在被误判
2、Android target 29开始,普通开发者无法获取手机的IMSI和IMEI值了,也就不能通过此判断真机和模拟器了
先这样吧,我提交上去测了