以下是一些罕用的办法:

1.应用代码混同工具:

代码混同能够使反编译后的代码难以浏览和了解,从而减少二次打包的难度。

在 Android 开发中,罕用的代码混同工具是 ProGuard。上面是在 Android Studio 中配置 ProGuard 的相干代码:

1) 在 app 的 build.gradle 文件中,增加以下代码:

android {    // 省略其余配置    buildTypes {        release {            minifyEnabled true            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'        }    }}

2) 在我的项目根目录下创立 proguard-rules.pro 文件,用于指定混同规定。以下是一些罕用的规定:

# 根本规定-optimizationpasses 5  # 优化次数-dontusemixedcaseclassnames  # 不应用混合大小写的类名-dontskipnonpubliclibraryclasses  # 不跳过非公共库的类-dontpreverify  # 不预验证# 代码混同规定-keep class com.example.** {*;}  # 保留 com.example 包及其子包中的所有类-keepclassmembers class com.example.** {*;}  # 保留 com.example 包及其子包中的所有类成员-dontwarn com.example.**  # 不正告 com.example 包及其子包中的类# 其余规定-keepattributes Signature-keepattributes *Annotation*

以上代码只是一个简略示例,理论的混同规定须要依据具体的利用进行调整和优化。实现以上步骤后,在进行 release 版本打包时,ProGuard 会主动对代码进行混同和优化,从而减少利用的安全性。

2.加固APK:

能够应用一些加固工具对APK进行加密,使得歹意攻击者难以间接获取到APK包,从而缩小二次打包的危险。

在 Android 开发中,罕用的加固工具有 DexProtector 和 Bangcle 等,这些工具提供了命令行和 Gradle 插件两种形式进行加固。上面是应用 DexProtector Gradle 插件进行加固的相干代码:

1) 在 app 的 build.gradle 文件中,增加以下代码:

buildscript {    repositories {        maven {            url 'https://oss.sonatype.org/content/repositories/snapshots/'        }    }    dependencies {        classpath 'com.android.tools.build:gradle:3.5.3'        classpath 'com.android.tools.build:gradle:3.5.3'        classpath 'com.jeppsson:gradle-dexprotector:2.1.1-SNAPSHOT'    }}apply plugin: 'dexprotector'dexProtector {    target 'all'    productFlavors {        demo {            enable true            activationUrl 'https://www.dexprotector.com/activation'            activationKey '1234567890'            libraryPath 'libs/dexprotector.jar'            configurationFile 'dexprotector.xml'        }    }    release {        enable true        activationUrl 'https://www.dexprotector.com/activation'        activationKey '1234567890'        libraryPath 'libs/dexprotector.jar'        configurationFile 'dexprotector.xml'    }}

2)在我的项目根目录下创立 dexprotector.xml 文件,用于指定加固配置。以下是一些罕用的配置:

<?xml version="1.0" encoding="UTF-8"?><resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@drawable/icon" tools:keepClassesWithMembers="true">    <!-- 保留指定类和类成员不被混同 -->    <keep>        <class name="com.example.MyActivity"/>        <class name="com.example.MyFragment"/>        <class name="com.example.MyService"/>        <class name="com.example.MyReceiver"/>        <class name="com.example.MyApplication"/>        <class name="com.example.MyClass"/>        <class name="com.example.MyInterface"/>        <class name="com.example.MyEnum"/>        <class name="com.example.MyAnnotation"/>        <method name="onCreate" class="com.example.MyActivity"/>        <method name="onCreateView" class="com.example.MyFragment"/>        <method name="onStartCommand" class="com.example.MyService"/>        <method name="onReceive" class="com.example.MyReceiver"/>        <method name="onCreate" class="com.example.MyApplication"/>        <field name="myField" class="com.example.MyClass"/>        <method name="myMethod" class="com.example.MyInterface"/>        <field name="myEnum" class="com.example.MyEnum"/>        <class name="com.example.MyAnnotation"/>    </keep>    <!-- 重命名指定类和类成员 -->    <rename>        <class name="com.example.MyClass" to="com.example.RenamedClass"/>        <method name="myMethod" class="com.example.MyInterface" to="renamedMethod"/>        <field name="myField" class="com.example.MyClass" to="renamedField"/>        <class name="com.example.MyAnnotation" to="RenamedAnnotation"/>    </rename>    <!-- 加密指定类和资源 -->    <encrypt>        <class name="com.example.MyClass

3.对APK进行数字签名:

数字签名能够确保APK的完整性和真实性,能够使攻击者无奈在不扭转APK签名的状况下进行二次打包。

在 Android Studio 中,能够应用以下步骤对 APK 进行数字签名:

1)在我的项目根目录下创立一个 keystore 文件,用于存储数字证书和私钥。能够应用 keytool 工具生成一个新的 keystore,命令如下:

keytool -genkey -v -keystore my-release-key.keystore -alias my_alias -keyalg RSA -keysize 2048 -validity 10000

其中,my-release-key.keystore 是 keystore 文件名,my_alias 是数字证书别名,RSA 是应用的加密算法,2048 是密钥大小,validity 是证书有效期。

2)在我的项目的 build.gradle 文件中增加以下代码:

android {    ...    signingConfigs {        release {            storeFile file("my-release-key.keystore")            storePassword "password"            keyAlias "my_alias"            keyPassword "password"        }    }    buildTypes {        release {            ...            signingConfig signingConfigs.release        }    }    ...}

其中,storeFile 指定 keystore 文件门路,storePassword 和 keyPassword 是 keystore 明码和数字证书明码,keyAlias 是数字证书别名。

3)在 Android Studio 中,应用 Build -> Generate Signed Bundle/APK 菜单项抉择要签名的 APK,抉择 release build type,输出 keystore 和数字证书明码,即可对 APK 进行数字签名。

4.检测利用运行环境:

利用能够检测以后运行的环境是否为实在设施,如果检测到运行环境不是实在设施,则利用能够主动敞开,以防止被二次打包。

要检测利用的运行环境,能够应用 Android 提供的 Build 类。以下是一些罕用的办法:

1)检测设施的 CPU 架构:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {    for (String abi : Build.SUPPORTED_ABIS) {        Log.i("MyApp", "Supported ABI: " + abi);    }} else {    Log.i("MyApp", "ABI: " + Build.CPU_ABI);}

2)检测设施的屏幕分辨率:

DisplayMetrics metrics = getResources().getDisplayMetrics();int screenWidth = metrics.widthPixels;int screenHeight = metrics.heightPixels;

3)检测设施的操作系统版本:

int sdkVersion = Build.VERSION.SDK_INT;String osVersion = Build.VERSION.RELEASE;

4)检测设施的品牌和型号:

String brand = Build.BRAND;String model = Build.MODEL;

5)检测利用的包名和版本号:

String packageName = getPackageName();PackageManager packageManager = getPackageManager();try {    PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);    String versionName = packageInfo.versionName;    int versionCode = packageInfo.versionCode;} catch (PackageManager.NameNotFoundException e) {    e.printStackTrace();}

留神,某些设施可能存在定制化 ROM,例如小米、华为等,这些设施的零碎属性可能与规范 Android 设施不同,须要进行额定的解决。

5.在利用中集成反调试技术:

能够在利用中增加一些反调试代码,以使攻击者无奈通过调试工具获取利用的代码和资源。

在 Android 利用中集成反调试技术,能够在代码中检测是否处于调试状态,如果是,则采取相应的措施,例如退出利用或者强制敞开调试器。以下是一种罕用的反调试技术实现办法:

public class DebugDetector {    public static boolean isDebugging() {        return Debug.isDebuggerConnected() || Debug.waitingForDebugger();    }    public static void detectDebugging() {        if (isDebugging()) {            Log.e("DebugDetector", "Debugging detected, exiting...");            System.exit(0);        }    }}

在利用中须要应用反调试技术时,能够调用 DebugDetector.detectDebugging() 办法进行检测。如果检测到正在进行调试,则会输入谬误日志并退出利用。

须要留神的是,一些调试器可能会屏蔽调试检测,因而此种反调试技术并不能齐全保障利用不被调试。

以上。