你发布的Android 应用安全吗?

大家都知道,目前大多数的Android 是用Java语言写的,即使现在Google非常力荐kotlin,但是还有目前很多的项目还是使用Java编写,毕竟一个语言的替换是需要时间。因此,Java代码容易被反编译也是总所周知的,因此自己的防止被反编译还是需要重视的。

主要从四个方面来介绍本文:

1.Proguard混淆

2.对抗反编译工具

3.对抗安卓模拟器

4.对抗apk重打包

Proguard混淆

Proguard 基础

Proguard 是一个混淆代码的开源项目,Proguard主要的作用是混淆,当然他还有着对字节码进行缩减体积、优化等功能,我主要关注的是混淆。

概念

下面两张图片分别是混淆了和没有混淆的图片(网上找的图):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这样可以看出来,假如混淆和没有假如混淆的区别之大。使用混淆之后的类名就完全变了,自然假如混淆后,针对反编译还是有效果。

基本语法:

-include {filename} 从给定的文件中读取配置参数
-basedirectory {directoryname} 指定基础目录为以后相对的档案名称
-injars {class_path} 指定要处理的应用程序jar,war,ear和目录
-outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。

保留选项
-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件

压缩
-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}

优化
-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

混淆
-dontobfuscate 不混淆输入的类文件
-printmapping {filename}
-applymapping {filename} 重用映射增加混淆
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,…} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and

InnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量

实际代码:

-ignorewarnings # 忽略警告,避免打包时某些警告出现
-optimizationpasses 5 # 指定代码的压缩级别
-dontusemixedcaseclassnames # 是否使用大小写混合
-dontskipnonpubliclibraryclasses # 是否混淆第三方jar
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/,!class/merging/ # 混淆时所采用的算法

-libraryjars libs/treecore.jar

-dontwarn android.support.v4.** #缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。
-dontwarn android.os.**
-keep class android.support.v4.** { ; } # 保持哪些类不被混淆
-keep class com.baidu.
* { ; }
-keep class vi.com.gdi.bgl.android.**{
;}
-keep class android.os.**{*;}

-keep interface android.support.v4.app.** { ; }
-keep public class * extends android.support.v4.
*
-keep public class * extends android.app.Fragment

-keep public class * extends android.app.Activity
-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.support.v4.widget
-keep public class * extends com.sqlcrypt.database
-keep public class * extends com.sqlcrypt.database.sqlite
-keep public class * extends com.treecore.**
-keep public class * extends de.greenrobot.dao.**

-keepclasseswithmembernames class * { # 保持 native 方法不被混淆
native ;
}

-keepclasseswithmembers class * { # 保持自定义控件类不被混淆
public (android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * { # 保持自定义控件类不被混淆
public (android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity { //保持类成员
public void *(android.view.View);
}

-keepclassmembers enum * { # 保持枚举 enum 类不被混淆
public static **[] values();
public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆
public static final android.os.Parcelable$Creator *;
}

-keep class MyClass; # 保持自己定义的类不被混淆

**注意: ** 在Android中有一部分是不能够被混淆的,混淆了之后就会出现异常:

  • 四大组件由于在Mainfest中注册了,所以不能被混淆
  • jin调用的Java的接口方法
  • 系统接口方法
  • R文件的混淆可能会导致引用错误(如果有地方使用反射机制,R文件被混淆之后就会找不到资源)

防止反编译

防止反编译方法

1 . Proguard混淆不仅仅可以混淆代码,还能反编译工具失效或者奔溃

2 . 使用现在国内的APK加固方法,就我所知目前你想要在360市场和腾讯的市场上发布应用,都要必须要使用他们对应的市场的加固方式:360加固和乐固加固

我们常用的反编译工具有哪些呢?

  • apkTool
  • baksmali
  • dex2.jar
  • JEB

我们通过上面的两种方法可以让这些反编译工具反编译出来不易阅读甚至让反编译工具失效或者。

由于前面已经提到过混淆的方法就不在赘述,使用国内的APK加固方法就更加的简单了,到指定的官网下载工具加固即可,文档描述很详细。

防止模拟器

防止模拟器逆向分析

原因:一般被处于逆向分析状态是在Android模拟器中运行的,所以我们只需要在代码中判断我们当前的APK是否运行在模拟器中即可。

检测是否是模拟器 一般有一下几种方式:

  • 检测模拟器上的几个特殊文件
  • 检测模拟器上的特殊号码
  • 检测设备IDS是不是“000000000000000”
  • 检测是否还有传感器、蓝牙
  • 检测手机上才有的硬件信息
  • 检测手机的运营商

下面我用代码来演示一下:

检查IDS

/**

  • 检查IDS
  • @param context
  • @return
    */
    public static boolean chechDeviceIDS(Context context) {
    @SuppressLint(“ServiceCast”)
    TelephonyManager telecomManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    @SuppressLint(“MissingPermission”)
    String deviceId = telecomManager.getDeviceId();
    if (deviceId.equalsIgnoreCase(DEVICE_ID)) {
    Log.e(TAG, “chechDeviceIDS==” + DEVICE_ID);
    return true;
    }
    return false;
    }

检查模拟器特有文件

/**

  • 检查模拟器特有的文件
  • @param context
  • @return
    */
    public static boolean chechDeviceFile(Context context) {
    for (int i = 0; i < DEVICE_FILE.length; i++) {
    String file_name = DEVICE_FILE[i];
    File qemu_file = new File(file_name);
    if (qemu_file.exists()) {
    Log.e(TAG, “chechDeviceFile==” + true);
    return true;
    }
    }
    return false;
    }

检查模拟器特有号码

/**

  • 检查特有电话号码
  • @param context
  • @return
    */
    public static boolean chechDevicePhone(Context context) {
    @SuppressLint(“ServiceCast”)
    TelephonyManager telecomManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    @SuppressLint(“MissingPermission”)
    String phoneNumber = telecomManager.getLine1Number();
    for (String phone : DEVICE_PHONE) {
    if (phone.equalsIgnoreCase(phoneNumber)) {
    Log.e(TAG, “chechDevicePhone==” + phoneNumber);
    自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

我一直以来都有整理练习大厂面试题的习惯,有随时跳出舒服圈的准备,也许求职者已经很满意现在的工作,薪酬,觉得习惯而且安逸。

不过如果公司突然倒闭,或者部门被裁减,还能找到这样或者更好的工作吗?

我建议各位,多刷刷面试题,知道最新的技术,每三个月可以去面试一两家公司,因为你已经有不错的工作了,所以可以带着轻松的心态去面试,同时也可以增加面试的经验。

我可以将最近整理的一线互联网公司面试真题+解析分享给大家,大概花了三个月的时间整理2246页,帮助大家学习进步。

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是部分内容截图:

部分目录截图

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

的时间整理2246页,帮助大家学习进步。

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是部分内容截图:

[外链图片转存中…(img-toehNBZv-1712371857677)]

[外链图片转存中…(img-bRGyzuTf-1712371857678)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值