第二章 ClassLoader加密方式改进
JAVA程序是通过java.exe/javaw.exe来启动的,要对ClassLoader进行解密处理,只能从java.exe/javaw.exe身上着手。
我们先来考察一下JDK的发布路径, 发现JDK的每一个版本都提供了src.jar,用winzip打开看看, 可以看到一个launcher的路径,里面包含的就是java.exe/javaw.exe的程序代码。哈哈, 这下我们可以随心所欲了。:-)打开java.c看看,里面有一段, 如下:
jstring mainClassName = GetMainClassName(env, jarfile);
if ((*env)->ExceptionOccurred(env)) {
(*env)->ExceptionDescribe(env);
goto leave;
}
if (mainClassName == NULL) {
fprintf(stderr, "Failed to load Main-Class manifest attribute "
"from\n%s\n", jarfile);
goto leave;
}
classname = (char *)(*env)->GetStringUTFChars(env, mainClassName, 0);
if (classname == NULL) {
(*env)->ExceptionDescribe(env);
goto leave;
}
mainClass = LoadClass(env, classname);
(*env)->ReleaseStringUTFChars(env, mainClassName, classname);
} else {
mainClass = LoadClass(env, classname);
}
if (mainClass == NULL) {
(*env)->ExceptionDescribe(env);
status = 4;
goto leave;
}
其中,函数LoadClass见下:
static jclass
LoadClass(JNIEnv *env, char *name)
{
char *buf = MemAlloc(strlen(name) + 1);
char *s = buf, *t = name, c;
jclass cls;
jlong start, end;
if (debug)
start = CounterGet();
do {
c = *t++;
*s++ = (c == '.') ? '/' : c;
} while (c != '\0');
cls = (*env)->FindClass(env, buf);
free(buf);
if (debug) {
end = CounterGet();
printf("%ld micro seconds to load main class\n",
(jint)Counter2Micros(end-start));
printf("----_JAVA_LAUNCHER_DEBUG----\n");
}
return cls;
}
分析上面的程序,我们可以看到env中的函数FindClass根据类名直接得到mainClass对象的。如果我们要装载已加密过的JAVA程序, 显然直接调用FindClass函数是不行的,那么,我们有没有办法自己读取文件,然后将之转换成一个mainClass对象呢?
我们来看看JNIEnv里面还有什么?打开JDK路径\include\jni.h, 在里面我们查到下列定义:
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;
#else
typedef const struct JNINativeInterface_ *JNIEnv;
#endif
而在JNINativeInterface_的定义中:
struct JNINativeInterface_ {
……
jclass (JNICALL *DefineClass)
(JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
jsize len);
……
}
对了,DefineClass就是我们要找的,它可以将一个缓冲区(class字节码)转换成一个类实例!下面就是一个实现如何装载加密Class:
static jclass
LoadClass(JNIEnv *env, char *name)
{
FILE *in;
long length, i;
char *cc;
int x;
char javaloader [MAXPATHLEN], javapath[MAXPATHLEN];
char *buf = MemAlloc(strlen(name) + 1);
char *s = buf, *t = name, c;
jclass cls;
jlong start, end;
if (debug)
start = CounterGet();
do {
c = *t++;
*s++ = (c == '.') ? '/' : c;
} while (c != '\0');
/*如果装载的类是MyLoader*/
if(strcmp(buf,"MyLoader")==0) {
if (GetApplicationHome(javapath, sizeof(javapath)))
{
sprintf(javaloader, "%s\\MyLoader.class", javapath);
}
if ((in = fopen(javaloader, "rb")) == NULL)
{
fprintf(stderr, "Cannot open input file.\n");
return (jclass)0x0f;
}
/*读出加密的class文件*/
fseek(in, 0L, SEEK_END);
length = ftell(in);
fseek(in, 0, SEEK_SET);
cc = MemAlloc(length);
fread((void*)cc,length,1,in);
fclose(in);
/*解密算法*/
……
/*将解密后的class字节码转换成class*/
cls = (*env)->DefineClass(env, buf, 0, cc, length-1);
free(cc);
}
else
cls = (*env)->FindClass(env, buf);
free(buf);
if (debug) {
end = CounterGet();
printf("%ld micro seconds to load main class\n",
(jint)Counter2Micros(end-start));
printf("----_JAVA_LAUNCHER_DEBUG----\n");
}
return cls;
}
分享到:
相关推荐
本文将深入探讨`ClassLoader`的工作原理、加密解密应用程序以及如何防止类被反编译。 首先,让我们理解`ClassLoader`的基本概念。`ClassLoader`是Java中的一个接口,位于`java.lang`包下,它是Java运行时环境的一...
破解java加密的ClassLoader.java,在classloader植入破解代码
二、创建自定义Classloader 创建自定义Classloader需要继承java.lang.ClassLoader类,并重写其关键方法,如`findClass(String name)`或`loadClass(String name)`。这两个方法分别用于查找指定类的字节码和实际加载...
通过创建自定义ClassLoader,你可以定制JVM,使类文件的引入方式完全重新定义,这提供了很多实用和有趣的可能。这篇教程将对Java ClassLoader进行概述,并指导你构建一个示例ClassLoader,该ClassLoader可以自动编译...
- 在某些特殊情况下,我们可能需要自定义ClassLoader来实现特定的加载逻辑,例如从网络、数据库或加密文件中加载类。 - 自定义ClassLoader通常需要重写`loadClass()`方法,该方法在找不到类时调用`findClass()`...
该项目是一款基于ClassLoader扩展的Spring Boot JAR安全加密运行工具源码,包含74个文件,其中69个为Java源文件,1个为Git忽略文件,1个为LICENSE文件,1个为Markdown文件,1个为XML文件,以及1个Go语言文件。...
### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`...
破解java加密的rt.jar,在classloader植入破解代码,默认输出到c:/TEMP/classes/目录。使用方法:只要下载本rt.jar,然后替换掉jdk1.8.0_25\jre\lib目录下的rt.jar。然后运行你需要破解的java程序即可,如果你的java...
1. Bootstrap ClassLoader:这是JVM启动时的第一个ClassLoader,负责加载JDK核心类库(如rt.jar)。 2. Extension ClassLoader:加载JDK扩展目录(如$JAVA_HOME/jre/lib/ext)中的类。 3. System ClassLoader(也...
自定义ClassLoader是Java平台的一大特色,开发人员可以根据需要创建自己的类加载器,例如实现模块化、热部署或者加密解密类等高级功能。自定义ClassLoader通常需要重写findClass()或loadClass()方法,以控制类的加载...
在Java编程语言中,ClassLoader是一个至关重要的组成部分,它负责加载类到JVM(Java虚拟机)中。理解ClassLoader的工作原理以及如何定制它,对于深入学习Java的运行机制和进行高级应用开发具有重要意义。本篇文章将...
ClassLoader是JVM中的一个重要组件,它的主要任务是加载类的二进制数据,转换为Class对象,并供Java应用程序使用。本文将深入浅出地探讨JVM ClassLoader的工作原理和相关知识点。 首先,ClassLoader可以分为三种...
1. **加载**:加载是ClassLoader工作的起点,它从文件系统或网络中找到类的二进制数据,然后创建一个对应的Class对象。这个过程可以通过自定义ClassLoader来实现,比如从数据库中加载类。 2. **验证**:验证是确保...
二、ClassLoader的体系结构 ClassLoader形成一个树状结构,BootstrapClassLoader是根节点,ExtensionClassLoader是其子节点,SystemClassLoader是ExtensionClassLoader的子节点。用户还可以自定义ClassLoader,插入...
Bootstrap ClassLoader是JVM启动时的第一个加载器,负责加载JDK的根目录下`jre/lib/rt.jar`等核心类库。Extension ClassLoader则负责加载`jre/lib/ext`目录下的扩展类库。最后,App ClassLoader加载的是应用类路径...
Bootstrap ClassLoader是JVM启动时的第一个ClassLoader,负责加载JRE的`<JAVA_HOME>/jre/lib`目录下的核心类库,如rt.jar。Extension ClassLoader接着加载`<JAVA_HOME>/jre/lib/ext`目录下的扩展类库。最后,...
在Java编程语言中,ClassLoader是核心组件之一,它负责加载类到JVM(Java虚拟机)中。自定义ClassLoader允许开发者根据特定需求加载类,比如动态加载或更新类文件,这在某些高级应用场景中非常有用,如插件系统、热...