How to effectively protect Java programs

zhaozj2021-02-17  52

How to effectively protect Java programs

content:

Popular Encryption Method Introduction ClassLoader Encryption How to Improve Application Example Application

Protecting Java Hu Xianli (Samenhu@yahoo.com.cn) ZTE Softswitch Product Department June 2002

At present, the encryption method of Java programs is no more Java Fuzzy Processing (Obfuscator) and two ways to encrypt to ClassLoader methods (otherwise, but most of them are both extensions and variations). These two ways do not have much difficulties to the Java anti-compiler, after all, still track, organic can be multiplied. The method described herein is an improvement to the ClassLoader mode encryption, so that the traditional binary code is secure.

The first chapter of the popular encryption method is introduced about the encryption method of the Java program, which has always been mainly based on Java Fuzzy Processing (Obfuscator). The results of this study are also quite a lot, and both ambiguator (such as the famous Jode now), also has a "bomb" against the anti-compiler (such as "Bomb" Crema and Hosemocha for anti-compilation tool Mocha). Flags, from the literal, we can know that it is fuzzy to handle Java code, specifically, that is, the change in variable name, function name, or even class name makes it uncomfortable. Let's take an example. The following source code will be compiled into a Class file. Public Class Test

{

Int Sortway;

Void Sort (Vector A)

{

......

}

Void Setsortway (int WAY)

{

......

}

Void Sort (Vector A, INT WAY)

{

......

}

}

After the fuzzy treatment is performed by Jode, it may become the following code. Public class oooooooOOO0OO0O0O0o0o

{

Int oooo0oo0oo0o0o0o0o0o

Void Ooo0ooO0oo0o (Vector OooO0oo0ooo)

{

......

}

Void Oooo00oooOOOOOOOOOOOOOO0O0O0O0o0o0o

{

......

}

Void Ooo0ooO0o0o0o (Vector OooO0oo0oo, Int Oo0oooO0o0o)

{

OOO00ooOOO0O (OO0OOOO0OO0O);

OOO0ooO0OO0O (OOOO0OO0OOO);

}

}

In fact, this is only a visual treatment, and its business logic is still constant. It is patient, and it can be broken. If you use it in user authentication, you can fully find the authentication algorithm to break through the limit. The so-called "bomb" is a defect against the anti-compilation tool itself, which is very effective for a particular anti-compilation tool, but so far, there is no all-round, which is effective for each anti-compilation tool. The limitations are obvious! Another way is to encrypt ClassLoader. The Java virtual machine is loaded with the bytecode of the class file through a target called ClassLoader, and ClassLoader can be customized by the Java program. How does ClassLoader load class? ClassLoader finds the files of the class in the JAR package according to the class name, and converts it into a Class object. The principle of this method is that we will use a certain method (which can be PGP, RSA, MD5, etc.) to encrypt, after reading the file, and then converts to a class after reading the file. Object. The detailed introduction to the ClassLoader work method is not here, and there is a topic of the article in front. Is there any found that the method did not solve the security of the ClassLoader itself? Obviously, as long as the ClassLoader class is compiled, you can find other classes. It can be seen that the ClassLoader itself "bright code" mode still causes certain unsafe, however, if the method solves the security of the ClassLoader itself, it is not a better security program. Chapter II ClassLoader Encryption Method Improvement Java Program is started by java.exe / javaw.exe, to decrypt ClassLoader, can only start from java.exe / javaw.exe. Let's take a look at the JDK's release path. Every version of the JDK provides src.jar. Take a look in Winzip, you can see a Launcher's path, which is Java.exe / Javaw.exe program. Code. Haha, we can do it with your heart. :-) Open Java.c to see, there is a paragraph, as follows: 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 = loadingclass (env, classname);

(* ENV) -> ReleaseStringutfchars (ENV, MainclassName, ClassName);

} else {mainclass = loadingclass (eNV, classname);

}

IF (mainclass == NULL) {

(* ENV) -> ExceptionDescribe (ENV);

STATUS = 4;

Goto Leave;

}

Among them, the function loadClass is asked: 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;

}

Analyze the above program, we can see that the function in the ENV Findclass directly gets the mainclass object directly according to the class name. If we want to load the encrypted Java program, it is obvious that the FindClass function calls directly, then, can we read the file yourself, then convert it into a mainclass object? Let's take a look at what else in Jnienv? Open the JDK path / include/jni.h, we check the following definition: #ifdef __cplusplus

Typedef jnienv_ jnienv;

#ELSE

TypeDef const stand JNINATIVEINTERFACE_ * Jnienv;

#ENDIF

In the definition of JNINATIVEINTERFACE_: Struct JNINATIVEINTERFACE_ {

......

JCLASS (JNICALL * DefineClass)

(JNIENV * ENV, Const Char * Name, Jobject Loader, Const Jbyte * BUF,

Jsize len);

......

}

Yes, DefineClass is what we are looking for, it can convert a buffer (Class byte code) into a class instance! Below is an implementation how to load encrypted 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');

/ * If the loaded class is 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;

}

/ * Read the encrypted Class file * /

FSeek (in, 0L, seek_end);

Length = ftell (in);

FSeek (in, 0, seek_set);

CC = MEMALLOC (Length);

Fread ((void *) CC, Length, 1, in);

Fclose (in);

/ * Decryption algorithm * /

......

/ * Convert the decrypted CLASS bytecode to 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;

}

Chapter III Application Example In practical applications, it is recommended that the new startup procedure continues to use Java.exe parameter call format, Java [-Options] class [args ...], such, on one aspect program in the development version (non- Encrypted) and publishing the call mode when publishing the version (encrypted) is maintained, it is easy to understand, on the other hand, the production of the launcher is also simple, just change the loadclass method in java.c. Here is a schematic of general application:

If the call is like this: Class1 calls Class2, call Class3 by Class2, where Class2 has its own custom ClassLoader (ClassLoader used by Class3), then add 1 Interface between Class2 and Class3, by Interface Call the Class3 corresponding ClassLoader to load the Class3, and the Interface itself cannot be encrypted. This type of typical application is a web application on Tomcat. When the Tomcat is loaded, it is loaded with your own classloader. If you encrypt the servlet, Tomcat does not load success when loading the servlet, you must use the interfab! The following is a schematic of its application:

转载请注明原文地址:https://www.9cbs.com/read-28377.html

New Post(0)