Android apk如何加固防止被破解(防止逆向编译)

现在主要工具是接触SDK,为了防止游戏包被破解编译,以及发现加密串,我来分享下以下几点:
防破解技术主要有四种实现方式:
1.代码混淆(ProGuard)技术
2.签名比对技术
3.NDK .so 动态库技术
4.动态加载技术
5.第三方平台加密以及检测漏洞

这个在 Android 安全之如何反编译与加密apk包 这篇文章中也提及到了相关的知识点。

  • 第一种: 代码混淆技术(ProGuard) 该技术主要是进行代码混淆,降低代码逆向编译后的可读性,但该技术无法防止加壳技术进行加壳(加入吸费、广告、病毒等代码),而且只要是细心的人,依然可以对代码依然可以对代码进行逆向分析,所以该技术并没有从根本解决破解问题,只是增加了破解难度。
  • 第二种: 签名比对技术 该技术主要防止加壳技术进行加壳,但代码逆向分析风险依然存在。而且该技术并不能根本解决被加壳问题,如果破解者将签名比对代码注释掉,再编译回来,该技术就被破解了。
  • 第三种: NDK .so动态库技术,该技术实现是将重要核心代码全部放在C文件中,利用NDK技术,将核心代码编译成.so动态库,再用JNI进行调用。该技术虽然能将核心代码保护起来,但被加壳风险依然存在。
  • 第四种: 动态加载技术,该技术在Java中是一个比较成熟的技术,而Android中该技术还没有被大家充分利用起来。
  • 第五种: 第三方平台使用

    主要讲解第四种方法,该技术可以有效的防止逆向分析、被破解、被加壳等问题,动态加载技术分为以下几步:

  • 将核心代码编译成dex文件的Jar包
  • 对jar包进行加密处理
  • 在程序主入口利用NDK进行解密
  • 再利用ClassLoader将jar包进行动态加载
  • 利用反射技术将ClassLoader 设置成系统的ClassLoader。

主要优点有:
       1.核心代码在被加密的jar中,所以破解者无法解压出class文件,如果加密秘钥被破解者拿到,那将是另外一层面的安全问题了。
      2.该技术也可以有效防止加壳技术,代码是动态加载上来的,破解者的壳程序无法加入到已加密的jar包中,及时破解者注入壳程序入口,壳程序因为不在ClassLoader 的jar包中,所以也无法被执行起来,除非破解者替换ClassLoader的jar包,关掉NDK解密代码.但这种安装到手机上,已经不在是我们的应用,用户一定会将其卸载掉。

所以综合起来比较,第四种动态加载技术是最安全的,但效率问题,本人并没做严格测试,粗略实验了一下,效率并没有明显降低。

//   1.Jar包加密加密解密文件//
public static boolean enOrDecryptFile(byte[] paramArrayOfByte,
        String sourceFilePath, String destFilePath,int mode){
    File sourceFile = new File(sourceFilePath);
    File destFile = new File(destFilePath);
    CipherOutputStream cout = null;
    FileInputStream in  = null;
    FileOutputStream out = null;
    if (sourceFile.exists() && sourceFile.isFile()) {
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        try {
            destFile.createNewFile();
            in = new FileInputStream(sourceFile);
            out = new FileOutputStream(destFile);
            // 获取密钥//
            init();
            SecretKeySpec secretKeySpec = new SecretKeySpec(defPassword, "AES");
            Cipher cipher;
            cipher = Cipher.getInstance("AES");
            cipher.init(mode, secretKeySpec);
            cout = new CipherOutputStream(out, cipher);
            byte[] cache = new byte[CACHE_SIZE];
            int nRead = 0;
            while ((nRead = in.read(cache)) != -1) {
                cout.write(cache, 0, nRead);
                cout.flush();
            }
        }catch (IOException e) {
            e.printStackTrace();
            return false;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return false ;
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return false ;
        }catch (InvalidKeyException e) {
            e.printStackTrace();
            return false;
        }finally{
                if(cout != null){
                    try {
                        cout.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(out != null){
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(in != null){
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }
        return true;
    }
    return false;
}  

jar用SDK\platform-tools\下的dx命令进行dex格式转化

dx   --dex    --output=生成的目标文件的地址(绝对路径)     需要转化的jar文件(绝对路径)
                       例如:dx --dex --output=H:\classdex.jar     H:\dujinyang-KARL.jar

然后再用加密工具将生成jar文件进行加密处理

最后通过代码动态加载:

File file = new File("/data/data/" + base.getPackageName() + "/.cache/");
        if (!file.exists()) {
            file.mkdirs();
        }
        try {
            Runtime.getRuntime().exec("chmod 755 " + file.getAbsolutePath()).waitFor();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        Util.copyJarFile(this);
        Object currentActivityThread = RefInvoke.invokeStaticMethod(
                "android.app.ActivityThread", "currentActivityThread",
                new Class[] {}, new Object[] {});
        String packageName = getPackageName();
        HashMap mPackages = (HashMap) RefInvoke.getFieldOjbect(
                "android.app.ActivityThread", currentActivityThread,
                "mPackages");
        WeakReference wr = (WeakReference) mPackages.get(packageName);
        MyClassLoader dLoader = new MyClassLoader("/data/data/"
                + base.getPackageName() + "/.cache/classdex.jar", "/data/data/"
                + base.getPackageName() + "/.cache", "/data/data/"
                + base.getPackageName() + "/.cache/", base.getClassLoader());
        try {
            Class<?>  class1 = dLoader.loadClass("com.example.test.TestActivity");
            Log.i("b364","----------->class1: "+class1);
        } catch (ClassNotFoundException e){
            Log.i("b364","----------->class not found Exception!");
            e.printStackTrace();
        }
        Log.i("b364","------>PackageInfo: "+wr.get());
        // DexClassLoader dLoader = new DexClassLoader(apkFileName, odexPath,
        // libPath, (ClassLoader) RefInvoke.getFieldOjbect(
        // "android.app.LoadedApk", wr.get(), "mClassLoader"));
        RefInvoke.setFieldOjbect("android.app.LoadedApk", "mClassLoader",
                wr.get(), dLoader);  

处理完成,如果在Application中做特别处理也是可行的。之前就有人分析了爱加密的加密方式,不过这里不做阐述,有兴趣可以一起讨论。

下篇文章中我们来讲讲如何 逆向apk的动态库

时间: 2024-08-25 19:51:47

Android apk如何加固防止被破解(防止逆向编译)的相关文章

Android APK反编译图文教程_Android

在学习Android开发的过程你,你往往会去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局可能会让你爱不释手,作为一个开发者,你可能会很想知道这些效果界面是怎么去实现的,这时,你便可以对改应用的APK进行反编译查看.下面是我参考了一些文章后简单的教程详解. (注:反编译不是让各位开发者去对一个应用破解搞重装什么的,主要目的是为了促进开发者学习,借鉴好的代码,提升自我开发水平.) 测试环境:         win 7  使用工具:        apktool (资源文件获取)  下载 

Android Apk去掉签名以及重新签名的方法_Android

Android Apk去掉签名以及重新签名的方法 Android开发中很重要的一部就是用自己的密钥给Apk文件签名,不经过签名的Apk文件一般是无法安装的,就算装了最后也是失败. 网上流传的"勾选允许安装未知来源的应用"其实跟签不签名没啥关系,说白了就是允许安装不从电子市场上下载的应用而已. 近几日需要修改一个Apk中JNI调用的.so文件,苦于没有apk源代码,只好研究了一下签名相关的问题.当然有很多第三方工具可以做到,但其实JDK中已经提供了强大的签名工具jarsigner. 1.

android apk更新、安装问题

问题描述 android apk更新.安装问题 在开发程序更新的模块,程序下载完成后调用android自带的更新工具进行安装, Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive"); context.startActivity(intent); 但是

Android APK反编译查看源码及资源文件

本文主要介绍如何反编译Android应用程序查看源代码.资源文件和xml文件以及修改后重新打包成APK.鼓励大家反编译去学习他人的设计而不是将应用换壳后混乱市场.也可以直接使用网友整理的 anti-droid. Android APK实际就是个Zip文件,可以解压缩后反编译查看源代码和资源文件.以下以微信为例: 我们可以右击APK文件,"打开方式"选择Winrar压缩文件管理器,截图如下: 是不是跟程序的目录结构很像,源码已经被压缩在了classes.dex文件中.这里我们可以直接查看

google play-googleplay android APK 超过50M如何解决

问题描述 googleplay android APK 超过50M如何解决 mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, GoogleDownloaderService.class); public void onServiceConnected(Messenger m) 例子里说,调用createStub的时候会回调onServiceConnected 但是怎么都没有调用,这是为什么呢? 解决方案 压缩你

android apk 明明在eclipse中显示安装成功

问题描述 android apk 明明在eclipse中显示安装成功 apk显示安装成功 我手机也闪了一下 但是之后就没反应了 手机上也没apk 是代码问题么 解决方案 已解决,配置文件中错误 解决方案二: apk文件安装成功后,Android AVD桌面上不显示图标 解决方案三: 你也可以把手机开发者选项的错误提示打开 方便找到错误

android apk 和全站仪通过蓝牙通信

问题描述 android apk 和全站仪通过蓝牙通信 android apk 和全站仪通过蓝牙通信测试,这个具体是一个什么样的实现思路 解决方案 Ble4.0?通信测试测试啥?如果用蓝牙实现通信功能的话,需要硬件和软件配合,类似于穿戴那种,至于如何实现,硬件:单片机(arm)+ble,软件:apk+支持ble的手机.

新人求助:android apk直接控制开发板上的4个led灯,实现流水灯

问题描述 新人求助:android apk直接控制开发板上的4个led灯,实现流水灯 在android系统的文件目录下有如下4个文件路径,分别控制4个led亮与灭,写入1亮,0灭 public String path_led1="/sys/devices/platform/leds-gpio/leds/led1/brightness"; public String path_led2="/sys/devices/platform/leds-gpio/leds/led2/bri

IIS 添加mime 支持 apk,exe,.woff,IIS MIME设置 ,Android apk下载的MIME 设置 苹果ISO .ipa下载mime 设置

原文:IIS 添加mime 支持 apk,exe,.woff,IIS MIME设置 ,Android apk下载的MIME 设置 苹果ISO .ipa下载mime 设置 站点--右键属性--http头 扩展名  mime类型.apk      application/vnd.android.package-archive.exe      application/octet-stream.woff     application/x-font-woff 字体.ipa      applicati