Android程序反破解技术

    0x1

    对抗反编译可以大概分为以下几点:

    1、对抗反编译工具,例如apktool、dex2jar等

    2、对抗静态编译,分为代码混淆技术、NDK保护、apk加壳保护。

    3、对抗动态调试,分为检测调试器、检测模拟器。

    4、防止重编译,分为检查签名,校验保护。

    更多相关内容请参考《Android软件安全与逆向分析》。


   0x02

   对抗反编译工具,例如dex2jar,通常是在分析dex2jar源码后,来找到漏洞,在java源码中加入会触发dex2jar异常的代码,从而使dex2jar不能正常使用。

   dex2jar测试版本是0.0.7.8,源码地址https://github.com/jltxgcy/AntiCrack/tree/master/Antidex2jar。这个工程是通过在java源码中加入下面函数导致dex2jar不能正常使用的。

    private int position(int idx) { // bits big-endian in each unit
        return 1 << (BITS_PER_UNIT - 1 - (idx % BITS_PER_UNIT));        
    }

    0x03

    对抗静态编译

    1、代码混淆技术请参考Android 混淆机制。

    2、NDK保护,就是把原来在java层实现的逻辑,挪到C/C++层去实现,因为C/C++层代码反编译后生成的arm汇编,更加难以分析。

    3、apk加壳保护,请参考Android中的Apk的加固(加壳)原理解析和实现。


    0x04

    对抗动态调试

    1、检测调试器,我们已经在Android native反调试方式及使用IDA绕过反调试一文中,详细说明了有几种方式可以用来反调试器。

    另外在这里面介绍一个java层的反调试器,https://github.com/jltxgcy/AntiCrack/tree/master/Antidebug/src/com/droider/antidebug。

    2、检测模拟器,当我们的程序运行在模拟器中,我们可以推测出我们的程序正在被动态分析,这时我们可以使我们的程序退出。工程地址:https://github.com/jltxgcy/AntiCrack/tree/master/CheckQemu。

    检测模拟器的方法有很多,参考Android安全–检测是否为Android模拟器。


    0x05

    防止重编译。

    1、检测签名

    在java层检测签名,工程地址如下:https://github.com/jltxgcy/AntiCrack/tree/master/CheckSignature。核心的代码是:

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;
    }
    获取签名后,然后和正确的签名信息对比,如果对比成功,说明签名信息没有被更改。


    2、校验保护

    重编译Android软件的实质是重新编译classes.dex文件,代码经过重新编译后,生成的classes.dex文件的Hash值已经改变。

    工程地址:https://github.com/jltxgcy/AntiCrack/tree/master/CheckCRC。

    核心代码如下:

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;
    }   

你可能感兴趣的:(Android程序反破解技术)