美文网首页安全
Android 逆向工程:防止apk被破解的方法总结

Android 逆向工程:防止apk被破解的方法总结

作者: ImWiki | 来源:发表于2019-11-16 13:17 被阅读0次

保证apk安全是非常重要的工作,这篇文件文件我们来总结如何防逆向工程。

  1. Java代码混淆
  2. 资源文件混淆
  3. 使用HTTPS,校验密钥
  4. URL签名
  5. DEX加固
  6. so文件校验签名

Java代码混淆

Android 工程本身就已经有代码混淆的方法,我们只需要按照要求对代码进行混淆即可。建议开发者除了对自己编写的代码混淆,也要对引入的第三方代码进行混淆,这样可以大大降低代码被破解的风险。

资源文件混淆

推荐使用微信开源的 AndResGuard 对资源文件进行混淆,不但可以降低资源文件被盗用的风险,还可以降低APP的大小,实际测试使用 AndResGuard 后,apk降低了2M大小。

混淆前 混淆前 混淆后
混淆后
使用HTTPS,校验证书

使用HTTPS可以非常有效防止被抓包,避免APP请求的内容被破解,但是单纯引入HTTPS是不足够的,还是可以被抓包的,必须要对证书进行校验。
《Android 逆向工程:Charles + Android 实现 HTTPS 抓包》
《Android 网络安全:如何避免 Okhttp 的 HTTPS 请求被抓包》

URL签名

使用HTTPS可以避免被抓包,但是如果别人知道了请求的URL和参数,就可以直接请求URL获取数据,所以我们非常有必要在请求的URL增加签名,服务器确认这个请求是从APP发起了,而不是别人伪造的。
《Android 网络安全:URL签名验证的实现API防篡改》

DEX加固

加固也避免dex文件直接暴露在apk压缩文件中,但是加固也有明确的缺点,可能会影响启动的速度,apk体积增大,无法使用补丁,依然可以脱壳逆向。所以加固已经不再被推荐使用,基本上大公司的apk都不会使用加固技术。

so文件校验签名

这个是针对apk中有编写了C++代码的项目,一些重要的算法我们通常是写在C++中,比如URL签名算法,因为写在Java就意味着容易被破解。但是so文件也通常存在被盗用的风险,我们有必要在C++层对apk的签名进行校验,避免apk被重新打包,so被盗用。

可以从这个方法中读取Application:ActivityThread.currentActivityThread().getApplication()

不用直接通过传入context到C++层校验,因为context是可以伪造的。

int get_apk_signature_hash(JNIEnv *env) {
    // 不直接使用传入的context,避免是mock出来的,通过ActivityThread.currentActivityThread().getApplication()方式获取Application
    jclass ActivityThreadClass = env->FindClass("android/app/ActivityThread");
    jmethodID currentActivityThreadMethodID = env->GetStaticMethodID(ActivityThreadClass,"currentActivityThread","()Landroid/app/ActivityThread;");
    jobject ActivityThreadObject = env->CallStaticObjectMethod(ActivityThreadClass,
                                                               currentActivityThreadMethodID);
    jmethodID getApplication = env->GetMethodID(ActivityThreadClass, "getApplication","()Landroid/app/Application;");
    jobject context = env->CallObjectMethod(ActivityThreadObject, getApplication);


    jclass ContextWrapperClass = env->FindClass("android/content/ContextWrapper");
    //this.getPackageManager();
    jmethodID getPackageManagerMethodID = env->GetMethodID(ContextWrapperClass, "getPackageManager","()Landroid/content/pm/PackageManager;");


    jobject packageManagerObject = env->CallObjectMethod(context, getPackageManagerMethodID);

    //this.getPackageName();
    jmethodID getPackageNameMethodID = env->GetMethodID(ContextWrapperClass, "getPackageName",
                                                        "()Ljava/lang/String;");
    jstring packageName = (jstring) env->CallObjectMethod(context, getPackageNameMethodID);
    const char *tmp = env->GetStringUTFChars(packageName, NULL);
    std::string packageName_ = tmp;
    // 校验apk的包名
    int findPackage = packageName_.find("com.xxx.xxx");
    if(findPackage < 0){
        return -4;
    }

    // packageManager->getPackageInfo(packageName, GET_SIGNATURES);
    jclass PackageManagerClass = env->FindClass("android/content/pm/PackageManager");
    jclass PackageInfoClass = env->FindClass("android/content/pm/PackageInfo");

    jmethodID getPackageInfoMethodID = env->GetMethodID(PackageManagerClass, "getPackageInfo",
                                                        "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
    jobject packageInfo = env->CallObjectMethod(packageManagerObject, getPackageInfoMethodID,
                                                packageName, 0x40); //GET_SIGNATURES = 64;
    jfieldID fid = env->GetFieldID(PackageInfoClass, "signatures",
                                   "[Landroid/content/pm/Signature;");
    jobjectArray signatures = (jobjectArray) env->GetObjectField(packageInfo, fid);
    jobject sig = env->GetObjectArrayElement(signatures, 0);

    ContextWrapperClass = env->GetObjectClass(sig);
    getPackageInfoMethodID = env->GetMethodID(ContextWrapperClass, "hashCode", "()I");
    int sig_value = (int) env->CallIntMethod(sig, getPackageInfoMethodID);
    return sig_value;
}

上面的C++代码对应的Java代码(简化思路)

int signaturesHash = getApplication().getPackageManager()
  .getPackageInfo("com.xxx.xxx",0).signatures.hashCode();

相关文章

网友评论

    本文标题:Android 逆向工程:防止apk被破解的方法总结

    本文链接:https://www.haomeiwen.com/subject/nzhyictx.html