Android APK 加固--开发者角度(零)

Android APK 加固–开发者角度(零)

1.APK加固介绍

Android应用程序使用的开发语言是Java语言,由于蚕蛹的是这种解释性语言,所以代码可以被反编译。如果没有经过混淆或是加密,会非常让人容易读懂,换言之就是容易被破解。为了能够使我们的apk更好的保护起来,Android的开发以及安全人员对APK进行了一系列的加固措施。对APK加固从开发者的角度来看,以下是常用的手段和方式:

1.使用proguard对apk中的源码进行混淆
2.对apk反编译之后的smali进行混淆
3.对apk中的字符串进行加密
4.对apk中的文件进行校验

2.使用proguard对apk中的源码进行混淆

AndroidStudio默认已经有proguard的支持,在小牧目录安排app下的build.gradle中有配置信息,只需要将false变为true即可。
默认只有release的配置,而工程默认是debug的,所以想要为debug上添加混淆要在release后面添加debug模式。
在这里插入图片描述
Proguard的混淆结果会处处到/build/outputs/mapping/release/目录或是/build/outputs/mapping/debug/,一共有四个输出文件:

1.dump.txt:描述APK中所有类文件的内部结构
2.mapping.txt:提供混淆前后类名,方法名和成员变量的对应关系。
3.seeds.txt:列出没有被混淆的类和成员
4.usage.txt:列出从apk中移除的代码

混淆之后可能出错,出错异常的分析:
http://simplyadvanced.net/blog/android-how-to-decode-proguards-obfuscated-code-from-stack-trace/
Proguard 包括四个功能,shrinker(压缩),optimizer(优化),obfuscator(混淆),preverifier(预校验)

3.对反编译之后的smali进行混淆

源码经过混淆之后,在一个产品级的apk中对apk的保护是有一定帮助的,而对于一些有一定经验的破解者,他们还是会找到比较关键的地方,一般这种方式都是经过反编译之后进行分析的,那么如果我们效仿windows下的保护软件,对smali代码进行混淆,那么某种程度上加大了破解者的分析难度。比较方便的混淆方式就是代码乱序。

1.代码乱序
原理:

我们在分析smali代码时,一般会借助于反编译工具反编译成java代码,代码乱序的主要目的就是想要将smali代码乱序之后,使反编译的效果大打折扣,这样就会挡住很短菜鸟,至少可以减慢分析速度。

2.对apk中的字符串进行加密

在开发过程中字符串的使用不可避免,但是这些字符串极可能是破解的关键点,比如服务器的地址和错误提示这些敏感的字符串信息。如果这些字符串采用硬编码的方式,很容易通过静态分析获取。

1.采用StringBuilder拼接的方式。
2.编码混淆:在硬编码的时候将字符串先转换成16进制的数组或者Unicode编码,在使用的时候在回转字符串,这种方式比StringBuider方式更难直接识别。
3.加密处理:先将字符串在本地进行加密处理,后将密文硬编码进去,运行时再进行解密。可以将解密方法通过JNI实现。

4.对apk中的文件进行校验

在apk中包括代码和资源以及签名文件,一般我们会对可执行文件进行校验,还有证书的签名进行校验,以及apk本身的校验。

1. 对apk中的dex文件进行校验

classes.dex是android虚拟机的可执行文件,我们所写的java代码骑士都在这里面,所有很多赌赢程序的篡改都是针对classes.dex文件的。

1.编写代码

代码比较简单,这里是通过计算好的crc保存在string.xml文件里,当然我们可以随便那一个值代替,等开发完成后替换掉。

private void verifyDex(){
	Long dexCrc = Long.parseLong(this.getString(R.string.crc_value));
	String apkPath = this.getPackageCodePath();
	try{
		ZipFile zipFile = new ZipFile(apkPath);
		ZipEntry dexEntry = zipFile.getEntry("classes.dex");
		//计算classex.dex的crc
		long dexEntryCrc = dexEntry.getCrc();
		Log.d("DEX",dexEntryCrc+" ");
		//对比
		if(dexCrc == dexEntryCrc){
			Log.d("DEX","dex hasn't been modified");
		}else{
			Log.d("DEX","dex has ben modified");
		}
	}catch (IOException e){
		e.printStackTrace();
	}
}
2.对apk中的apk进行校验

与DEX校验不同apk校验必须把计算好的Hash值放在网络服务端,因为对APK的任何改动都会印象到最后的Hash值。
校验代码:

private void verifyApk(){
//获取data/app/**/base.apk 路径
	String apkPath = getPackageResourcePath();
	MessageDigest msgDigest;
	try{
		//获取apk并计算MD5
		msgDigest = MessageDigest.getInstance("MD5");
		byte[] bytes = new byte[4096];
		int count;
		FileInputStream fis;
		fis = new FileInputStream(new File(apkPath));
		while((count = fis.read(bytes))>0){
			msgDigest.update(bytes,0,count);
			}
			//计算出MD5值
			BigInteger bInt = new BigInteger(1,msgDigest.digest);
			String md5 = bInt.toString(16;
			fis.close();
			Log.d("apk",md5);
			//获取服务端的md5对比
			}catch(){
			}
3.对apk中的签名进行校验

每个APK都会经过开发者独有的整数进行签名,如果破解者对APK进行二次打包一般会用自己的签名证书 打包。这时候我们就可以通过校验签名证书的MD5值进行校验。
校验代码:

public void verifySignature(){
	String packageName = this.getPackageName();
	PackageManager pm = this.getPackageManager();
	PackageInfo pi;
	String md5 = "";
	try{
		pi = pm.getPackageInfo(packageName,PackageManager.GET_SIGNATURES);
		Signature[] s=pi.signatures;
		//计算md5值
		//获取服务端签名证书,对比
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值