您的位置:首页 > 编程语言 > Java开发

关于jdk中类装载器ClassLoader扩展和JNI技术(JavaNativeInterface)以及类文件的加密解密算法

2012-06-21 09:00 781 查看
1、自定义Classloader的代码如下:
package com.test.start;
import java.io.IOException;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.net.URL;

import java.net.URLClassLoader;

import java.nio.ByteBuffer;

import java.security.AccessControlContext;

import java.security.AccessController;

import java.security.CodeSigner;

import java.security.CodeSource;

import java.security.PrivilegedActionException;

import java.security.PrivilegedExceptionAction;

import java.security.ProtectionDomain;

import java.util.jar.Attributes;

import java.util.jar.Attributes.Name;

import java.util.jar.Manifest;

import sun.misc.Resource;

import sun.misc.URLClassPath;
public class CommonClassLoader extends URLClassLoader

{

private URLClassPath ucp;

private AccessControlContext acc;

private Method getProtectionDomainMethod;
public CommonClassLoader(URL[] urls)

{

super(urls);

}
public CommonClassLoader(URL[] urls, ClassLoader parent) {

super(urls);

}
protected void addURL(URL arg0)

{

super.addURL(arg0);

}
//系统方法
protected Class<?> findClass(String name)

throws ClassNotFoundException

{

try

{

check();

return

((Class)AccessController.doPrivileged(new PrivilegedExceptionAction(this, name) {

public Object run() throws ClassNotFoundException {

String path = this.val$name.replace('.', '/').concat(".class");

Resource res = CommonClassLoader.access$0(this.this$0).getResource(path, false);

if (res != null)

try {

return CommonClassLoader.access$1(this.this$0, this.val$name, res);

} catch (IOException e) {

throw new ClassNotFoundException(this.val$name, e);

}
throw new ClassNotFoundException(this.val$name);

}

}

, this.acc));

} catch (PrivilegedActionException pae) {

throw ((ClassNotFoundException)pae.getException());

}

}
//修改后的系统方法
private Class defineClass(String name, Resource res)

throws IOException

{

int i = name.lastIndexOf(46);

URL url = res.getCodeSourceURL();

if (i != -1) {

String pkgname = name.substring(0, i);
Package pkg = getPackage(pkgname);

Manifest man = res.getManifest();

if (pkg != null)

{

if (pkg.isSealed())

{

if (pkg.isSealed(url)) break label172;

throw new SecurityException(

"sealing violation: package " + pkgname + " is sealed");

}
if ((man == null) || (!(isSealed(pkgname, man)))) break label172;

throw new SecurityException(

"sealing violation: can't seal package " + pkgname +

": already loaded");

}
if (man != null)

definePackage(pkgname, man, url);

else {

definePackage(pkgname, null, null, null, null, null, null, null);

}
}
label172: ByteBuffer bb = res.getByteBuffer();

if (bb != null)

{

CodeSigner[] signers = res.getCodeSigners();

CodeSource cs = new CodeSource(url, signers);

byte[] b = getBytes(bb);

return defineClassInternal(name, b, 0, b.length, cs);

}

byte[] b = res.getBytes();
CodeSigner[] signers = res.getCodeSigners();

CodeSource cs = new CodeSource(url, signers);

return defineClassInternal(name, b, 0, b.length, cs);

}
//系统方法
private boolean isSealed(String name, Manifest man)

{

String path = name.replace('.', '/').concat("/");

Attributes attr = man.getAttributes(path);

String sealed = null;

if (attr != null)

sealed = attr.getValue(Attributes.Name.SEALED);
if (sealed == null)

if ((attr = man.getMainAttributes()) != null)

sealed = attr.getValue(Attributes.Name.SEALED);

return "true".equalsIgnoreCase(sealed);

}
//自定义方法 检测父类的属性初始化给子类调用,使用java反射技术实现。
private void check()

{

try {

if (this.ucp == null)

{

Field fieldOfucp = getClass().getSuperclass().getDeclaredField("ucp");//获取private类型的字段

fieldOfucp.setAccessible(true);//设置private类型修饰的字段可以访问

this.ucp = ((URLClassPath)fieldOfucp.get(this));//访问private类型修饰的字段

}

if (this.acc == null)

{

Field fieldOfacc = getClass().getSuperclass().getDeclaredField("acc");

fieldOfacc.setAccessible(true);

this.acc = ((AccessControlContext)fieldOfacc.get(this));

}

if (this.getProtectionDomainMethod != null) return;
this.getProtectionDomainMethod = getClass().getSuperclass().getSuperclass().getDeclaredMethod("getProtectionDomain", new Class[] { CodeSource.class });

this.getProtectionDomainMethod.setAccessible(true);

}

catch (Exception ex)

{

ex.printStackTrace();

}

}
//自定义方法 字节缓冲中的字节获取
private byte[] getBytes(ByteBuffer b)

{

int len = b.remaining();

byte[] tb = new byte[len];
if (!(b.isDirect()))

if (b.hasArray()) {

System.arraycopy(b.array(), b.position() + b.arrayOffset(), tb, 0, len);

}

else

b.get(tb);

return tb;

}
//自定义方法 让加密的的class文件交给解密方法来执行装载否则由系统来装载
protected final Class<?> defineClassInternal(String name, byte[] b, int off, int len, CodeSource cs)

{

Class clz = null;

try

{

if (cs == null) {

clz = defineClass0(name, b, off, len); break label75:

}

clz = defineClass1(name, b, off, len, getProtectionDomainInternal(cs));

}

catch (ClassFormatError ex)

{

if (cs == null)

return super.defineClass(name, b, off, len);
return super.defineClass(name, b, off, len, getProtectionDomainInternal(cs));

}

if (clz == null)

{

if (cs == null)

label75: return super.defineClass(name, b, off, len);
return super.defineClass(name, b, off, len, getProtectionDomainInternal(cs));

}

return clz;

}
//系统方法
protected ProtectionDomain getProtectionDomainInternal(CodeSource cs)

{

try {

return ((ProtectionDomain)this.getProtectionDomainMethod.invoke(this, new Object[] { cs }));

}

catch (IllegalArgumentException e) {

e.printStackTrace();

}

catch (IllegalAccessException e) {

e.printStackTrace();

}

catch (InvocationTargetException e) {

e.printStackTrace();

}

return null;

}
//自定义方法 调用dll文件中的解密算法来解密class文件并装载到jvm中
private native Class<?> defineClass0(String paramString, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
private native Class<?> defineClass1(String paramString, byte[] paramArrayOfByte, int paramInt1, int paramInt2, ProtectionDomain paramProtectionDomain);

}

2、c++实现加密和解密算法以及JNI技术的应用实例:
#include"jni.h"

#include"com_test_start_CommonClassLoader.h"

static void arraycopy(JNIEnv *env,jbyteArray sb,int spo,jbyteArray db,int start,int len);

static jbyteArray encrypt(JNIEnv *env,jbyteArray b,jint len);

static jbyteArray getValidateCode(JNIEnv *env);

static jbyteArray getCode(JNIEnv *env);

/*

* Clasbs: com_test_start_CommonClassLoader

* Method: defineClass0

* Signature: (Ljava/lang/String;[BII)Ljava/lang/Class;

*/

JNIEXPORT jclass JNICALL Java_com_test_start_CommonClassLoader_defineClass0

(JNIEnv *env, jobject loader, jstring name, jbyteArray buffer, jint start, jint len)

{

jbyteArray temp=env->NewByteArray(len);//new一个数组,并申请一块内存

arraycopy(env,buffer,start,temp,start,len);//数组的复制相当于System.copy()方法

jbyteArray byte0=encrypt(env,temp,len);//进行class文件的解密操作

if(byte0==NULL)

{

env->DeleteLocalRef(temp);//释放内存

return NULL;

}

jsize size=env->GetArrayLength(byte0);//技术数组的长度相当于Array的length属性

jclass classLoader=env->GetSuperclass(env->GetSuperclass(env->GetSuperclass(env->GetObjectClass(loader))));//获取父类装载器

jmethodID mid=env->GetMethodID(classLoader,"defineClass","(Ljava/lang/String;[BII)Ljava/lang/Class;");//获取defineClass方法
defineClass jclass cls=(jclass)env->CallObjectMethod(loader,mid,name,byte0,start,size);//调用Classloader的defineClass定义一个类到jvm中

env->DeleteLocalRef(byte0);//释放内存

return cls;

}
/*

* Class: com_test_start_CommonClassLoader

* Method: defineClass1

* Signature: (Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;

*/

JNIEXPORT jclass JNICALL Java_com_test_start_CommonClassLoader_defineClass1

(JNIEnv *env, jobject loader, jstring name, jbyteArray buffer, jint start, jint len, jobject pro)

{

jbyteArray temp=env->NewByteArray(len);

arraycopy(env,buffer,start,temp,start,len);

jbyteArray byte0=encrypt(env,temp,len);

if(byte0==NULL)

{

env->DeleteLocalRef(temp);

return NULL;

}

jsize size=env->GetArrayLength(byte0);

jclass classLoader=env->GetSuperclass(env->GetSuperclass(env->GetSuperclass(env->GetObjectClass(loader))));

jmethodID mid=env->GetMethodID(classLoader,"defineClass","(Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;");

jclass cls=(jclass)env->CallObjectMethod(loader,mid,name,byte0,start,size,pro);

env->DeleteLocalRef(byte0);

return cls;

}

/*

getCode,密钥,用于加密

*/

static jbyteArray getCode(JNIEnv *env)

{

char char0[]={'0','1','2','3','4','5','6','7','8','9'};

char char1[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','s','y','z'};

char char2[36];

int i=0;

int j=0;

int k=0;

while(i<36)

{

if(i>=12&&j<10)

{

char2[i]=char0[j];

j++;

}

else if(i>=23&&k<26)

{

char2[i]=char1[k];

k++;

}

else

{

char2[i]=char1[k];

k++;

}

i++;

}

jbyteArray code=env->NewByteArray(36);

env->SetByteArrayRegion(code,0,36,(jbyte*)char2);

return code;

}

/*

getValidateCode,验证码用于区分是否是加密文件

*/

static jbyteArray getValidateCode(JNIEnv *env)

{

char char0[]={'0','1','2','3','4','5','6','7'};

jbyteArray char1=env->NewByteArray(8);

env->SetByteArrayRegion(char1,0,8,(jbyte *)char0);

return char1;

}

/*

encrypt,解密操作

*/

static jbyteArray encrypt(JNIEnv *env,jbyteArray b,jint len)

{

int i = 0;

jint j = 0;

int k =len;

jbyte* bb = (env->GetByteArrayElements(b,JNI_FALSE));

while (i < k) {

j = bb[i];

if ((j >= 48) && (j <= 57)) {

j = (((j - 48) + 5) % 10) + 48;

} else if ((j >= 65) && (j <= 90)) {

j = (((j - 65) + 13) % 26) + 65;

} else if ((j >= 97) && (j <= 122)) {

j = (((j - 97) + 13) % 26) + 97;

}

bb[i]=(jbyte)j;

i++;

}

env->SetByteArrayRegion(b,0,k,bb);

int length=500;//长度

int start=0;//起始次数

jbyteArray temp=getCode(env);//密钥

int mode=(k-8)%(length+36);//剩余部分

int count=(k-8)/(length+36);//总次数

int spo=0;//源位置

int dpo=0;//目标位置

int size=count*length+mode;//大小

jbyteArray byte0=env->NewByteArray(size);//密文大小

if(count>0)

{//进行解密

while(start<count)

{

arraycopy(env,b, spo, byte0, dpo, length);

spo=spo+length+36;

dpo=dpo+length;

start++;

}

}

if(mode>0)

{//复制剩余部分

arraycopy(env,b, spo, byte0, dpo, mode);

spo=spo+mode;

}

//校验码

jbyteArray validateCode0=getValidateCode(env);

jbyte* validateCode=env->GetByteArrayElements(validateCode0,JNI_FALSE);

jbyteArray validate0=env->NewByteArray(8);

arraycopy(env,b, spo, validate0, 0,8);

jbyte* validate=env->GetByteArrayElements(validate0,JNI_FALSE);

for(int index=0;index<8;index++)

{//校验解码是否成功

if(validate[index]!=validateCode[index])

{

return NULL;

}

}

env->DeleteLocalRef(validate0);

env->DeleteLocalRef(validateCode0);

env->DeleteLocalRef(temp);

return byte0;

}

/*

decrypt,加密操作

*/

static jbyteArray decrypt(JNIEnv *env,jbyteArray b,jboolean end)

{

int length=500;//长度

int start=0;//起始次数

int count=env->GetArrayLength(b)/length;//总次数

jbyteArray temp=getCode(env);//密钥

int spo=0;//源位置

int dpo=0;//目标位置

int mode=env->GetArrayLength(b)%length;//剩余部分

int size=count*(length+36)+mode;//大小

if(end==JNI_TRUE)

{//是否结束

size=size+8;

}

jbyteArray byte0=env->NewByteArray(size);//密文大小

if(count>0)

{//进行加密

while(start<count)

{

arraycopy(env,b, spo, byte0, dpo, length);

arraycopy(env,temp, 0, byte0, dpo+length, 36);

spo=spo+length;

dpo=dpo+length+36;

start++;

}

}

if(mode>0)

{//复制剩余部分

arraycopy(env,b, spo, byte0, dpo, mode);

dpo=dpo+mode;

}

if(end==JNI_TRUE)

{//结束位置加校验码

jbyteArray validateCode=getValidateCode(env);

arraycopy(env,validateCode, 0, byte0, dpo, 8);

env->DeleteLocalRef(validateCode);

}

jbyte * byte1=env->GetByteArrayElements(byte0,0);

//转换字节位置

int i = 0;

int j = 0;

int k = size;

while (i < k) {

j = byte1[i];

if ((j >= 48) && (j <= 57)) {

j = (((j - 48) + 5) % 10) + 48;

} else if ((j >= 65) && (j <= 90)) {

j = (((j - 65) + 13) % 26) + 65;

} else if ((j >= 97) && (j <= 122)) {

j = (((j - 97) + 13) % 26) + 97;

}

byte1[i]=(jbyte)j;

i++;

}

env->SetByteArrayRegion(byte0,0,size,byte1);

env->DeleteLocalRef(temp);

return byte0;

}

/*

arraycopy,自定义的数组赋值方法相当于System.copy()

*/

static void arraycopy(JNIEnv *env,jbyteArray sb,int spo,jbyteArray db,int start,int len)

{

jbyte * t=new jbyte[len];

env->GetByteArrayRegion(sb,spo,len,t);

env->SetByteArrayRegion(db,start,len,t);

delete t;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: