当前位置: 代码迷 >> Android >> 【Android应用保护技术探索之路系列】之5:对抗重编译
  详细解决方案

【Android应用保护技术探索之路系列】之5:对抗重编译

热度:70   发布时间:2016-04-27 23:50:13.0
【Android应用保护技术探索之路系列】之五:对抗重编译

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell

【Android应用保护技术探索之路系列】章节目录

【Android应用保护技术探索之路系列】之一:Android应用保护技术开篇
【Android应用保护技术探索之路系列】之二:对抗反编译
【Android应用保护技术探索之路系列】之三:对抗静态分析
【Android应用保护技术探索之路系列】之四:对抗动态调试
【Android应用保护技术探索之路系列】之五:对抗重编译

对抗重编译常用的有两种方式:检查签名和校验保护。

一 检查签名

每个Android应用在发布前都会进行签名,而签名所使用的密钥文件往往是签名者所独有的,所有签名往往会作为辨明应用身份的有效标识,

package com.droider.checksignature;import android.os.Bundle;import android.app.Activity;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.Signature;import android.graphics.Color;import android.view.Menu;import android.widget.TextView;public class MainActivity extends Activity {    private TextView text_info;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        setTitle("签名检查演示程序");        text_info = (TextView) findViewById(R.id.textView1);        int sig = getSignature("com.droider.checksignature");        if (sig != 2071749217) {            text_info.setTextColor(Color.RED);            text_info.setText("检测到程序签名不一致,该程序被重新打包过!");        } else {            text_info.setTextColor(Color.GREEN);            text_info.setText("该程序没有被重新打包过!");        }    }    public int getSignature(String packageName) {              PackageManager pm = this.getPackageManager();        PackageInfo pi = null;        int sig = 0;        try {            pi = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);            Signature[] s = pi.signatures;            sig = s[0].hashCode();          } catch (Exception e1) {            sig = 0;            e1.printStackTrace();        }        return sig;    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }}

二 校验保护

重编译Android应用的本质就是重编译classes.dex文件,代码经过重新编译后,生成的classes.dex文件的Hash值已经改变。我们可以通过检查classes.dex的Hash值来检查应用是否被重新打包过。

下面以检查CRC为例进行说明。

package com.droider.checkcrc;import java.io.IOException;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import android.os.Bundle;import android.app.Activity;import android.graphics.Color;import android.util.Log;import android.view.Menu;import android.widget.TextView;public class MainActivity extends Activity {    private TextView text_info;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        setTitle("校验保护演示程序");        text_info = (TextView) findViewById(R.id.textView1);        if (checkCRC()) {   //对比classes.dex的校验和            text_info.setTextColor(Color.GREEN);            text_info.setText("程序正常!");        } else {            text_info.setTextColor(Color.RED);            text_info.setText("程序被修改过!");        }    }    private boolean checkCRC() {        boolean beModified = false;        long crc = Long.parseLong(getString(R.string.crc));        ZipFile zf;        try {            zf = new ZipFile(getApplicationContext().getPackageCodePath());            ZipEntry ze = zf.getEntry("classes.dex");            Log.d("com.droider.checkcrc", String.valueOf(ze.getCrc()));            if (ze.getCrc() == crc) {                beModified = true;            }         } catch (IOException e) {            e.printStackTrace();            beModified = false;        }        return beModified;    }        @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }}

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案