码迷,mamicode.com
首页 > 移动开发 > 详细

安卓防止反编译

时间:2014-09-09 12:59:58      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:c++   安卓   java   jni   反编译   

<strong><span style="font-size:24px;">众所周知安卓很容易被反编译,即使做了防止反编译处理许多代码也可以看的到,目前用的比较多的手段是jni,即:把核心代码放到c++中,然后做出so库,这样的话安全性提高不少,但如果不对so库进行特殊处理的话,通过查看反编译后的java代码就会推测出你定义的调用so库的接口,别人就可以仿造你的接口,然后调用你的so库。
其实我们可以再每次调用so库时都在so库中的函数中判断一下安卓的公钥是不是你的,从而阻止他们使用你的so库,具体代码及工程如下</span></strong>



#include"com_example_singjni_MainActivity.h"
#include <stdio.h>
#include <stdlib.h>



//
//获取公钥的java代码
//public void getSingInfo() {
//        try {
//        	String pn=getPackageName();
//
//            PackageInfo packageInfo = getPackageManager().getPackageInfo(
//                    pn, PackageManager.GET_SIGNATURES);
//            Signature[] signs = packageInfo.signatures;
//            Signature sign = signs[0];
//            parseSignature(sign.toByteArray());
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//
//    public void parseSignature(byte[] signature) {
//    	ByteArrayInputStream bi=new ByteArrayInputStream(signature);
//        try {
//            CertificateFactory certFactory = CertificateFactory
//                    .getInstance("X.509");
//            X509Certificate cert = (X509Certificate) certFactory
//                    .generateCertificate(new ByteArrayInputStream(signature));
//            String pubKey = cert.getPublicKey().toString();
//            String signNumber = cert.getSerialNumber().toString();
//
//
//            System.out.println("signName:" + cert.getSigAlgName());
//            System.out.println("pubKey:" + pubKey);
//            System.out.println("signNumber:" + signNumber);
//            System.out.println("subjectDN:"+cert.getSubjectDN().toString());
//			 } catch ( Exception e) {
//				e.printStackTrace();
//			}
//		}


//核心代码如下    ,其他可以忽略
JNIEXPORT jstring JNICALL Java_com_example_singjni_MainActivity_sing__Landroid_content_Context_2
  (JNIEnv * env, jobject ob1, jobject thiz){



	jclass thisClass=env->GetObjectClass(thiz);
	jmethodID getPNId=env->GetMethodID(thisClass,"getPackageName","()Ljava/lang/String;");
	jstring packName=(jstring)env->CallObjectMethod(thiz,getPNId);


	jmethodID getPMId=env->GetMethodID(thisClass,"getPackageManager","()Landroid/content/pm/PackageManager;");
	jobject packManger=env->CallObjectMethod(thiz,getPMId);

	jmethodID getPIId=env->GetMethodID(env->GetObjectClass(packManger),"getPackageInfo","(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
	jobject packageInfo=env->CallObjectMethod(packManger,getPIId,packName,0x00000040);


	jfieldID signaturesId=env->GetFieldID(env->GetObjectClass(packageInfo),"signatures","[Landroid/content/pm/Signature;");
	jobject signatures=env->GetObjectField(packageInfo,signaturesId);
	jobjectArray signaturesArray=(jobjectArray)signatures;

	//signature=signs[0]
	jobject signature=env->GetObjectArrayElement(signaturesArray,0);
	jmethodID signatureBytesMId=env->GetMethodID(env->GetObjectClass(signature),"toByteArray","()[B");
	//sign.toByteArray()
	jobject signatureBytes=env->CallObjectMethod(signature,signatureBytesMId);
///////////////// public void parseSignature(byte[] signature) {}/////////////////////////////////////////////////////////////////

	jclass certificateFactoryClass=env->FindClass("java/security/cert/CertificateFactory");
	jmethodID getInstanceMId=env->GetStaticMethodID(certificateFactoryClass,"getInstance","(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;");
	jobject certFactory=env->CallStaticObjectMethod(certificateFactoryClass,getInstanceMId,env->NewStringUTF("X.509"));
///////////////////////////////////
	jclass byteInStreamClass=env->FindClass("java/io/ByteArrayInputStream");
	jmethodID byteArrayInStreamConMId= env->GetMethodID(byteInStreamClass,"<init>","([B)V");
	jobject byteArrayInStream=env->NewObject(byteInStreamClass,byteArrayInStreamConMId,signatureBytes);

	jmethodID generateCertificateMId=env->GetMethodID(certificateFactoryClass,"generateCertificate","(Ljava/io/InputStream;)Ljava/security/cert/Certificate;");
	jobject certificate=env->CallObjectMethod(certFactory,generateCertificateMId,byteArrayInStream);


	jmethodID getPKMId=env->GetMethodID(env->GetObjectClass(certificate),"getPublicKey","()Ljava/security/PublicKey;");

	jobject publicKey=env->CallObjectMethod(certificate,getPKMId);
	jmethodID toStringMId=env->GetMethodID(env->GetObjectClass(publicKey),"toString","()Ljava/lang/String;");
	jstring publickeyStr=(jstring)env->CallObjectMethod(publicKey,toStringMId);
///////////////////////
	jmethodID equalsMId=env->GetMethodID(env->GetObjectClass(publickeyStr),"equals","(Ljava/lang/Object;)Z");
	jboolean isCorrect=env->CallBooleanMethod(publickeyStr,equalsMId,env->NewStringUTF("OpenSSLRSAPublicKey{modulus=123..你的公钥...,publicExponent=10001}"));
	if(!isCorrect)
		return env->NewStringUTF( "wrong");

	jstring jstr=env->NewStringUTF( "correct");
		return jstr;

}








JNIEXPORT jstring JNICALL Java_com_example_singjni_MainActivity_sing
  (JNIEnv * env, jobject thiz){

	jstring jstr=env->NewStringUTF( "");
	return jstr;

}




java端代码 

package com.example.singjni;

 
import java.io.ByteArrayInputStream;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
 

public class MainActivity extends  Activity {

	static{
		System.loadLibrary("jniso");
	}
	EditText et;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		et=(EditText) findViewById(R.id.et);
		
	
		String s=sing(this);

		et.setText(s);

		System.out.println(s);

		
	}

	
	
	public native String  sing();
	public native String  sing(Context context);

}


工程下载地址   点击打开链接

安卓防止反编译

标签:c++   安卓   java   jni   反编译   

原文地址:http://blog.csdn.net/qingchunweiliang/article/details/39139351

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!