Android 阻止反编译和 如何反编译重写打包

本文详细介绍了如何在Android开发中防止代码反编译,通过在default.properties文件中配置ProGuard并进行混淆,使得代码难以被反编译理解。同时,文章还提供了混淆代码后的检查方法及签名流程,包括使用dex2jar、apktool等工具进行反编译验证,并介绍了如何使用JDK对已混淆的APK进行签名。最后,文章提供了签名时所需参数和解决签名问题的方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

防止反编译

2.3版本以上在eclipse自动生成的default.properties文件中加上一句“proguard.config=proguard.cfg”可以对代码进行混淆,反编译后是很难看懂的。


2.3之前的SDK版本也没关系,把上面的proguard.cfg文件复制一份放到项目中,然后进行相同的操作即可。

上面的方法可能不行,因为Adt版本更新后发现两个 文件都 没有

试试这个吧

工程的根目录,会自动生成两个ProGuard的混淆文件:proguard-project.txt和project.properties(在老版本的ADT中,只会生成一个叫proguard.cfg的文件)。

看后面一段注释:
#To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home) ,意指要让ProGuard 来压缩和混淆代码,把这句注释去掉即可!所以,我们只要把这段 下面一句注释取消即可
示例:

# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt(就这句)

不过这里要注意:不能试图通过运行eclipse中的Run as 和 Debug as 菜单来生成混淆代码,必须 将apk导出才行,当然你可以选择“签名”或者“不签名”

  • 这样一步操作后,算是代码混淆完成了。那么怎么才能检验我们真的混淆了代码了呢?首先,我们能够看到在工程的根目录新生产了一个文件夹proguard,里面有四个文件,其内容如下:
dump.txt : 描述了apk中所有类 文件中内部的结构体。( Describes the internal structure of all the class files in the .apk file )
mapping.txt : 列出了原始的类、方法和名称与混淆代码见得映射。( Lists the mapping between the original and obfuscated class, method, and field names. )
seeds.txt : 列出了没有混淆的类和方法。( Lists the classes and members that are not obfuscated )
usage.txt : 列出congapk中删除的代码。( Lists the code that was stripped from the .apk )
同时使用反编译软件对新生成的apk反编译后会发现,里面的类名、方法和变量等,都变成了简单的a、b、c、d等毫无含义的字母,这样就达到了混淆的目的

反编译

1.用apktool 把apk–> 资源包(java代码变成smali文件看不懂的),可以修改资源包里面的文件。
2.apk后缀名改成zip或rar解压,获取 classes.dex 文件,用dex2jar转换成jar包(注:直接解压出来的资源文件是不能直接打开的,要用第一步的反编译工具)。
3.用jd-ui等java反编译工具直接查看java代码。
4.把java代码和第一版的资源包整到一起重新组成一个新的应用。
5.用apktool 重新编译。
6.用签名工具重新签名。
7.重新发布带新的签名的应用。
注:如果不用改java代码,只是换换风格和汉化2.3.4步则不用做。

需要的工具
dex2jar
apktool

另外有人做了个工具套装,集成了apktool dex2jar jd-ui

hackapk

那么如何签名呢

Java代码:

package com.wl.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

public class ReStrore {

    public static void main(String[] args) {

        // 说明 :
//      解决使用 JDK 1.7 对 Android apk 签名后程序无法安装的问题
        /*
        同样的程序发布过程,在同事的机器上(JDK 1.6)签名后可以正常安装,但是在我机器上(JDK 1.7)签名后安装说签名错误无法安装。

        找到了解决的办法,需要在签名程序 jarsigner 增加如下参数

        -digestalg SHA1 -sigalg MD5withRSA
        此参数对 JDK 1.6 没有影响。 
         */



    /*
     * You are trying to sign an already signed apk. You need to export an unsigned apk file and then sign it with jarsigner.
     * 只能给 未签名的  apk签名  
     * 已经签过名的不能再次签名 ---------------->
     * 
     * 解决办法 ----------->如何  给 已经签名的 apk  重新签名    -------->删除   好压删除  META-INF 目录 ,然后运行此程序即可  
     * 
     * 
     * 
    */  

        //sourcePath是要签名的apk路径,targetPath是签名后生成的文件路径,key为使用的keystore路径,passwd为keystore对应的密码,alias是keystore的别名。
        signApk("D:/HelloWorld.apk", "D:/HelloWorld3.apk", "D:/Keystore", "123456", "wangli");
//      getAlias("D:/Keystore", "123456");

    }


    public static boolean signApk(String sourcePath, String targetPath, String key,  
            String passwd, String alias) {  
        if (sourcePath == null || targetPath == null || passwd == null|| key == null)  
            return false;  

        File file = new File(sourcePath);  
        if (!file.exists())  
            return false;  

        file=new File(key);  
        if(!file.exists())  
            return false;         

        String jdk7Param = " -digestalg SHA1 -sigalg MD5withRSA";
        String cmd = "jarsigner -verbose -keystore " + key + jdk7Param+ " -signedjar " + targetPath + " " + sourcePath + " " + alias;  
        Process process=null;         
        try {  
            process = Runtime.getRuntime().exec(cmd);  
            OutputStream outputStream = process.getOutputStream();  
            outputStream.write(passwd.getBytes());  
            outputStream.close();  
            InputStream inputStream = process.getInputStream();  
            InputStreamReader reader = new InputStreamReader(inputStream);  
            BufferedReader bufferedReader = new BufferedReader(reader);  
            String line = null;  
            while ((line = bufferedReader.readLine()) != null) {  
                System.out.println(line);  
                if(line.contains("incorrect"))  
                    return false;  
            }  
            bufferedReader.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
            return false;  
        }  
        return true;  
    }  


//如果不知道怎么获取alias,可以使用下面的代码,alias可以在工程根目录下的alias.txt中查看:

    public static void getAlias(String key, String passwd){  
        String cmd = "cmd.exe /c keytool -list -v -keystore "+key+" -storepass "+passwd+" > ./alias.txt";  
        try {  
            Process process=null;  
            process= Runtime.getRuntime().exec(cmd);  
            if (process != null) {  
                InputStream inputStream = process.getErrorStream();  
                InputStreamReader reader = new InputStreamReader(inputStream);  
                BufferedReader bufferedReader = new BufferedReader(reader);  
                String line = null;  
                while ((line = bufferedReader.readLine()) != null) {  
                    System.out.println(line);  
                }  
                bufferedReader.close();  
                reader.close();  
                inputStream.close();  
                process.destroy();  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  







}

收工

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值