anti-cracking / anti-reverse-engineering function

为防止自己的android应用被crack,可以在程序启动时做一些判断:

1.生成apk时,解压出其中的classes.dex,取得其CRC值,并将该值写入xml文件(如android:tag="4212136116");

2.在程序启动时取得该CRC值,与手机上安装的apk包中的classes.dex的实际CRC值比较即可。

下面给出了integrity check的示例代码。

 

当然该方法存在一些问题,hacker可以通过检查参数为(Context, String, String)的函数,如果其中含有

zipEntry的getCrc()函数和killProcess()函数,可以在该函数开始部分直接插入return,就可以绕过检查了。

 

改进方法参考:

参考:http://groups.google.com/group/android-developers/browse_thread/thread/5e8f76ea5371f674/4637cbf1c42dfd22?lnk=gst&q=anti-cracking#4637cbf1c42dfd22

 

/

Validates the application integrity against reverse engineering. 

If the validation fails the the application is terminated 

automatically without warning. 

 

@param context 

           Application context used for operations 

 

@param applicaionPackageName 

           Original application package name, you should 

           hard-codeencrypt this string and then pass it to this 

function un-encrypted, 

           do not use the java api to get this value. 

 

@param applicationCrc 

           Application CRC value 

public static void dapplicationIntegrityCheck(final Context context, 

        final String applicaionPackageName, 

        final String applicationCrc) 

    // Check that the application package name has not changed 

    if (applicaionPackageName != context.getPackageName()) 

    { 

        android.os.Process.killProcess(android.os.Process.myPid()); 

    } 

    // Check that the debuggable flag is set to False 

    try 

    { 

        if (0 != (context.getPackageManager().getPackageInfo(context.getPackageName(), 

                        PackageManager.GET_SIGNATURES).applicationInfo.flags &= 

                    ApplicationInfo.FLAG_DEBUGGABLE)) 

        { 

            android.os.Process.killProcess(android.os.Process.myPid()); 

        } 

    } 

    catch (Exception ex) 

    { 

        Log.e("HelperFunctions", "Error checking debuggable flag.", ex); 

    } 

    // Check that the debugger is not connected 

    if (Debug.isDebuggerConnected()) 

    { 

        android.os.Process.killProcess(android.os.Process.myPid()); 

    } 

    // CRC validation 

    try 

    { 

        ZipFile zipFile = new ZipFile(context.getPackageCodePath()); 

        ZipEntry zipEntry = zipFile.getEntry(new String(Common.CLASS_DEX)); 

        if (zipEntry.getCrc() != Long.parseLong(applicationCrc)) 

        { 

            android.os.Process.killProcess(android.os.Process.myPid()); 

        } 

        zipEntry = null; 

        zipFile = null; 

    } 

    catch (Exception ex) 

    { 

        Log.e("HelperFunctions", "Error checking crc.", ex); 

    } 

    // TO-DO: 

    // Check that the application name has not changed. 

    // Keep an encrypted string constant of the application 

    // name and then compare it with the application 

    // name string using the proper function to retrieve it 

}