作者:郭孝星
微博:郭孝星的新浪微博
邮箱:[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; }}
版权声明:本文为博主原创文章,未经博主允许不得转载。