#include "jiami.h" #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; }
参考:http://blog.csdn.net/chenshuang_com/article/details/7681670
http://www.ibm.com/developerworks/cn/java/l-protectjava/