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