用jvmti调试java application: hello world 实现

本文介绍了一个使用C语言编写的动态链接库示例,该示例展示了如何通过JVMTI接口获取已加载的Java类签名。同时提供了两种将动态链接库加载到Java应用程序的方法:启动时加载和启动后动态加载。
1. 用C写一个动态链接库, 代码如下:

ubuntu@ubuntu-VirtualBox:~$ cat agent.cpp
#include <jvmti.h>

#include <string>

#include <cstring>

#include <iostream>

#include <list>

#include <map>

#include <set>

#include <stdlib.h>

#include <jni_md.h>
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void
*reserved)
{
return Agent_OnAttach(vm, options, reserved);
}
JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options,

void *reserved) {

jvmtiEnv *jvmti;

jint result = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);

if (result != JNI_OK) {
printf("ERROR: Unable to access JVMTI!\n");

}

jvmtiError err = (jvmtiError) 0;

jclass *classes;

jint count;

err = jvmti->GetLoadedClasses(&count, &classes);

if (err) {

printf("ERROR: JVMTI GetLoadedClasses failed!\n");

}

for (int i = 0; i < count; i++) {

char *sig;

jvmti->GetClassSignature(classes[i], &sig, NULL);

printf("cls sig=%s\n", sig);

}

return err;

}

JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) {

// nothing to do

}

编成.so文件:
gcc agent.cpp -I/usr/java/jdk1.6.0_27/include -I/usr/java/jdk1.6.0_27/include/linux -shared -fPIC -o ./libtestagent.so

2. load动态链接库到java application.
两种方法:
1) 启动时加载: java -agentpath:./libtestagent.so Test
2) 启动后加载:java -cp .:$JAVA_HOME/lib/tools.jar VMAttacher 2413 ./libtestagent.so a

3. 测试代码:
//Test.java
public class Test {

public static void main(String[] args) {
new Thread() {
@Override
public void run() {
Test test = new Test();
while (true) {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
test.printHello();
}
}
}.start();
}

protected void printHello() {
System.out.println("hello");

}
}

4. 动态加载代码:
//VMAttacher.java
import java.io.IOException;

import com.sun.tools.attach.VirtualMachine;

public class VMAttacher {

public static void main(String[] args) throws Exception {

// args[0]为java进程id

VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(args[0]);

// args[1]为共享库路径,args[2]为传递给agent的参数

virtualMachine.loadAgentPath(args[1], args[2]);

virtualMachine.detach();

}

}


启动后加载的结果:
cls sig=Ljava/io/ExpiringCache$1;
cls sig=Ljava/lang/Math;
cls sig=Ljava/util/LinkedHashMap;
cls sig=Ljava/util/HashMap$EntryIterator;
cls sig=Ljava/util/LinkedHashMap$Entry;
cls sig=Ljava/util/concurrent/ConcurrentHashMap$Segment;
cls sig=[Ljava/util/concurrent/ConcurrentHashMap$Segment;
cls sig=Ljava/util/concurrent/locks/ReentrantLock;
cls sig=[Ljava/util/concurrent/locks/ReentrantLock;
cls sig=Ljava/util/concurrent/locks/Lock;
cls sig=[Ljava/util/concurrent/locks/Lock;
cls sig=Ljava/lang/NullPointerException;
cls sig=Ljava/lang/StringBuilder;
cls sig=Ljava/lang/ArithmeticException;
cls sig=Ljava/io/ObjectStreamField;
cls sig=[Ljava/io/ObjectStreamField;
cls sig=Ljava/util/jar/JarFile;
cls sig=Ljava/util/zip/ZipFile;
cls sig=Ljava/util/zip/ZipConstants;
cls sig=Ljava/lang/ThreadGroup;
cls sig=[Ljava/lang/ThreadGroup;
cls sig=Lsun/nio/cs/HistoricallyNamedCharset;
cls sig=Ljava/lang/Thread$UncaughtExceptionHandler;
cls sig=[Ljava/lang/Thread$UncaughtExceptionHandler;
cls sig=Lsun/misc/VM;
cls sig=Lsun/misc/JavaSecurityAccess;
cls sig=LTest;
cls sig=Ljava/lang/String$CaseInsensitiveComparator;
cls sig=Ljava/util/Comparator;
cls sig=Ljava/lang/RuntimePermission;
cls sig=Ljava/security/BasicPermission;
cls sig=Ljava/security/Permission;
cls sig=Ljava/security/Guard;
cls sig=Ljava/lang/StringCoding;
cls sig=Lsun/misc/SoftCache;
cls sig=Ljava/util/AbstractMap;
cls sig=Ljava/util/concurrent/locks/ReentrantLock$NonfairSync;
cls sig=Ljava/util/concurrent/locks/ReentrantLock$Sync;
cls sig=Ljava/util/concurrent/locks/AbstractQueuedSynchronizer;
cls sig=Ljava/util/concurrent/locks/AbstractOwnableSynchronizer;
cls sig=Ljava/lang/ThreadLocal$ThreadLocalMap;
cls sig=Ljava/util/Properties;
cls sig=Ljava/util/Hashtable;
cls sig=Ljava/util/Dictionary;
cls sig=Ljava/util/Map;
cls sig=Ljava/util/zip/InflaterInputStream;
cls sig=Ljava/io/File$1;
cls sig=Ljava/util/jar/JavaUtilJarAccessImpl;
cls sig=Lsun/misc/JavaUtilJarAccess;
cls sig=Lsun/misc/JavaIODeleteOnExitAccess;
cls sig=Lsun/misc/SharedSecrets;
cls sig=Lsun/misc/JarIndex;
cls sig=Ljava/lang/ref/ReferenceQueue;
cls sig=Ljava/util/zip/Inflater;
cls sig=Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
cls sig=[Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
cls sig=Ljava/lang/StringCoding$StringDecoder;
cls sig=Ljava/lang/ref/ReferenceQueue$Null;
cls sig=Ljava/util/HashMap$EntrySet;
cls sig=Ljava/lang/ClassLoader$3;
cls sig=Ljava/lang/ref/ReferenceQueue$Lock;
cls sig=Ljava/lang/StringCoding$StringEncoder;
cls sig=Ljava/util/HashMap;
cls sig=Ljava/util/zip/ZipEntry;
cls sig=Ljava/nio/charset/CharsetDecoder;
cls sig=Ljava/io/ExpiringCache$Entry;
cls sig=Ljava/lang/ClassLoader$NativeLibrary;
cls sig=Ljava/lang/Terminator;
cls sig=Ljava/lang/Terminator$1;
cls sig=Lsun/misc/SignalHandler;
cls sig=Ljava/util/jar/JarFile$JarFileEntry;
cls sig=Ljava/util/jar/JarEntry;
cls sig=Lsun/misc/Signal;
cls sig=Lsun/misc/URLClassPath$JarLoader$1;
cls sig=Lsun/misc/FileURLMapper;
cls sig=Lsun/misc/NativeSignalHandler;
cls sig=Ljava/util/concurrent/locks/AbstractQueuedSynchronizer$Node;
cls sig=Ljava/io/Console;
cls sig=Ljava/nio/charset/CodingErrorAction;
cls sig=Ljava/nio/ByteBuffer;
cls sig=Ljava/util/concurrent/ConcurrentHashMap$HashEntry;
cls sig=[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;
cls sig=Ljava/lang/annotation/Annotation;
cls sig=[Ljava/lang/annotation/Annotation;
cls sig=Ljava/lang/CharacterDataLatin1;
cls sig=Ljava/lang/CharacterData;
cls sig=Ljava/util/HashMap$Entry;
cls sig=[Ljava/util/HashMap$Entry;
cls sig=Ljava/util/Map$Entry;
cls sig=[Ljava/util/Map$Entry;
cls sig=Ljava/security/AccessController;
cls sig=Ljava/io/Console$1;
cls sig=Lsun/misc/JavaIOAccess;
cls sig=Ljava/io/Console$1$1;
cls sig=Ljava/lang/reflect/AccessibleObject;
cls sig=[Ljava/lang/reflect/AccessibleObject;
cls sig=Ljava/lang/Shutdown;
cls sig=Ljava/lang/reflect/ReflectPermission;
cls sig=Lsun/reflect/ReflectionFactory$GetReflectionFactoryAction;
cls sig=Ljava/security/PrivilegedAction;
cls sig=Ljava/util/Stack;
cls sig=Ljava/net/Parts;
cls sig=Ljava/lang/reflect/Field;
cls sig=[Ljava/lang/reflect/Field;
cls sig=Ljava/lang/reflect/Member;
cls sig=[Ljava/lang/reflect/Member;
cls sig=Lsun/net/www/protocol/file/Handler;
cls sig=Ljava/net/URLStreamHandler;
cls sig=Lsun/reflect/ReflectionFactory;
cls sig=Ljava/util/ArrayList;
cls sig=Ljava/nio/HeapByteBuffer;
cls sig=Lsun/misc/JavaSecurityProtectionDomainAccess;
cls sig=Lsun/misc/ExtensionDependency;
cls sig=Ljava/lang/ref/Reference$Lock;
cls sig=Ljava/lang/ref/Reference$ReferenceHandler;
cls sig=Ljava/lang/ref/Finalizer$FinalizerThread;
cls sig=Ljava/util/Enumeration;
cls sig=Ljava/util/Iterator;
cls sig=Ljava/util/Hashtable$Entry;
cls sig=[Ljava/util/Hashtable$Entry;
cls sig=Ljava/lang/Class$1;
cls sig=Ljava/lang/reflect/Method;
cls sig=Ljava/nio/Bits;
cls sig=Lsun/reflect/ReflectionFactory$1;
cls sig=Ljava/lang/Shutdown$Lock;
cls sig=Ljava/lang/ApplicationShutdownHooks;
cls sig=Lsun/reflect/NativeConstructorAccessorImpl;
cls sig=Ljava/nio/charset/Charset;
cls sig=Ljava/util/zip/ZipFile$ZipFileInputStream;
cls sig=Lsun/reflect/DelegatingConstructorAccessorImpl;
cls sig=Ljava/util/IdentityHashMap;
cls sig=Ljava/util/HashSet;
cls sig=Lsun/misc/URLClassPath;
cls sig=Ljava/lang/reflect/Constructor;
cls sig=[Ljava/lang/reflect/Constructor;
cls sig=Lsun/nio/cs/StandardCharsets;
cls sig=Lsun/nio/cs/FastCharsetProvider;
cls sig=Ljava/nio/charset/spi/CharsetProvider;
cls sig=Lsun/net/www/protocol/jar/Handler;
cls sig=Lsun/misc/OSEnvironment;
cls sig=Ljava/lang/System$2;
cls sig=Lsun/misc/JavaLangAccess;
cls sig=Lsun/misc/Launcher$AppClassLoader;
cls sig=Ljava/lang/Compiler;
cls sig=Lsun/nio/cs/StandardCharsets$Aliases;
cls sig=Lsun/util/PreHashedMap;
cls sig=Lsun/misc/Launcher$AppClassLoader$1;
cls sig=Ljava/lang/Compiler$1;
cls sig=Lsun/reflect/MagicAccessorImpl;
cls sig=Ljava/lang/SystemClassLoaderAction;
cls sig=Lsun/reflect/MethodAccessorImpl;
cls sig=Lsun/misc/Launcher;
cls sig=Lsun/reflect/MethodAccessor;
cls sig=Lsun/reflect/ConstructorAccessorImpl;
cls sig=Lsun/reflect/ConstructorAccessor;
cls sig=Ljava/net/URLClassLoader$1;
cls sig=Lsun/reflect/DelegatingClassLoader;
cls sig=Lsun/misc/URLClassPath$3;
cls sig=Lsun/reflect/ConstantPool;
cls sig=Lsun/misc/URLClassPath$JarLoader;
cls sig=Lsun/misc/URLClassPath$Loader;
cls sig=Lsun/misc/Launcher$Factory;
cls sig=Ljava/net/URLStreamHandlerFactory;
cls sig=Lsun/misc/Launcher$ExtClassLoader;
cls sig=Ljava/net/URLClassLoader;
cls sig=Ljava/security/SecureClassLoader;
cls sig=Ljava/nio/ByteOrder;
cls sig=Lsun/reflect/UnsafeStaticFieldAccessorImpl;
cls sig=Lsun/reflect/UnsafeFieldAccessorImpl;
cls sig=Ljava/nio/CharBuffer;
cls sig=Lsun/reflect/FieldAccessorImpl;
cls sig=Lsun/reflect/FieldAccessor;
cls sig=Ljava/lang/Readable;
cls sig=Ljava/lang/Object;
cls sig=[Ljava/lang/Object;
cls sig=Lsun/nio/cs/StandardCharsets$Classes;
cls sig=Ljava/lang/String;
cls sig=[Ljava/lang/String;
cls sig=Ljava/lang/Comparable;
cls sig=[Ljava/lang/Comparable;
cls sig=Ljava/io/Serializable;
cls sig=[Ljava/io/Serializable;
cls sig=Ljava/lang/CharSequence;
cls sig=[Ljava/lang/CharSequence;
cls sig=Lsun/nio/cs/StandardCharsets$Cache;
cls sig=Ljava/security/PrivilegedActionException;
cls sig=Ljava/lang/ThreadLocal;
cls sig=Lsun/misc/URLClassPath$FileLoader;
cls sig=Lsun/misc/URLClassPath$FileLoader$1;
cls sig=Lsun/misc/Resource;
cls sig=Ljava/nio/HeapCharBuffer;
cls sig=Ljava/util/concurrent/atomic/AtomicInteger;
cls sig=Ljava/util/Vector;
cls sig=Ljava/util/AbstractList;
cls sig=Ljava/util/AbstractCollection;
cls sig=Ljava/util/Collection;
cls sig=Ljava/lang/Iterable;
cls sig=Lsun/security/util/Debug;
cls sig=Lsun/nio/ByteBuffered;
cls sig=Ljava/security/CodeSource;
cls sig=Lsun/misc/Unsafe;
cls sig=Ljava/nio/charset/CoderResult;
cls sig=Ljava/net/URLClassLoader$7;
cls sig=Lsun/misc/JavaNetAccess;
cls sig=Ljava/util/StringTokenizer;
cls sig=Ljava/util/List;
cls sig=Ljava/nio/charset/CoderResult$1;
cls sig=Ljava/nio/charset/CoderResult$Cache;
cls sig=Ljava/nio/charset/CoderResult$2;
cls sig=Lsun/misc/Version;
cls sig=Ljava/security/Permissions;
cls sig=Ljava/security/PermissionCollection;
cls sig=Lsun/misc/Launcher$ExtClassLoader$1;
cls sig=Ljava/security/PrivilegedExceptionAction;
cls sig=Lsun/misc/MetaIndex;
cls sig=Ljava/util/RandomAccess;
cls sig=Ljava/io/BufferedReader;
cls sig=Ljava/io/Reader;
cls sig=Ljava/io/FileInputStream;
cls sig=Ljava/io/InputStream;
cls sig=Ljava/io/Closeable;
cls sig=Lsun/net/www/protocol/file/FileURLConnection;
cls sig=Lsun/net/www/URLConnection;
cls sig=Ljava/net/URLConnection;
cls sig=Ljava/lang/NoSuchMethodError;
cls sig=Ljava/lang/IncompatibleClassChangeError;
cls sig=Lsun/reflect/Reflection;
cls sig=Ljava/io/FileDescriptor;
cls sig=Ljava/io/FileOutputStream;
cls sig=Ljava/io/OutputStream;
cls sig=Ljava/io/Flushable;
cls sig=Ljava/io/FileReader;
cls sig=Ljava/io/InputStreamReader;
cls sig=Ljava/lang/Class;
cls sig=[Ljava/lang/Class;
cls sig=Ljava/lang/reflect/GenericDeclaration;
cls sig=[Ljava/lang/reflect/GenericDeclaration;
cls sig=Ljava/lang/reflect/AnnotatedElement;
cls sig=[Ljava/lang/reflect/AnnotatedElement;
cls sig=Ljava/lang/reflect/Type;
cls sig=[Ljava/lang/reflect/Type;
cls sig=Ljava/lang/StringBuffer;
cls sig=Ljava/lang/AbstractStringBuilder;
cls sig=Ljava/lang/Appendable;
cls sig=Lsun/nio/cs/StreamDecoder;
cls sig=Ljava/io/BufferedInputStream;
cls sig=Ljava/io/FilterInputStream;
cls sig=Ljava/util/zip/ZStreamRef;
cls sig=Ljava/security/ProtectionDomain$Key;
cls sig=Ljava/security/ProtectionDomain$2;
cls sig=Ljava/security/AccessControlContext$1;
cls sig=Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;
cls sig=Ljava/lang/reflect/Array;
cls sig=Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl;
cls sig=Lsun/net/www/ParseUtil;
cls sig=Lsun/reflect/misc/ReflectUtil;
cls sig=Ljava/io/PrintStream;
cls sig=Ljava/io/FilterOutputStream;
cls sig=Ljava/net/UnknownContentHandler;
cls sig=Ljava/net/ContentHandler;
cls sig=Lsun/net/www/MessageHeader;
cls sig=Ljava/util/AbstractSet;
cls sig=Ljava/util/Set;
cls sig=Ljava/io/FilePermission;
cls sig=Ljava/util/BitSet;
cls sig=Ljava/io/IOException;
cls sig=Ljava/lang/ClassLoader;
cls sig=Ljava/lang/Cloneable;
cls sig=Ljava/io/BufferedOutputStream;
cls sig=Ljava/io/FilePermission$1;
cls sig=Ljava/io/OutputStreamWriter;
cls sig=Ljava/io/Writer;
cls sig=Lsun/security/provider/PolicyFile;
cls sig=Ljava/security/Policy;
cls sig=Ljava/lang/StackTraceElement;
cls sig=[Ljava/lang/StackTraceElement;
cls sig=Lsun/nio/cs/StreamEncoder;
cls sig=Ljava/io/ObjectStreamClass;
cls sig=Ljava/lang/Class$3;
cls sig=Ljava/nio/Buffer;
cls sig=Ljava/lang/reflect/Modifier;
cls sig=Ljava/lang/reflect/ReflectAccess;
cls sig=Lsun/reflect/LangReflectAccess;
cls sig=Ljava/lang/Boolean;
cls sig=Lsun/security/action/GetPropertyAction;
cls sig=Ljava/lang/Character;
cls sig=Ljava/nio/charset/CharsetEncoder;
cls sig=Ljava/util/Arrays;
cls sig=Ljava/lang/System;
cls sig=Lsun/nio/cs/UTF_8;
cls sig=Lsun/nio/cs/Unicode;
cls sig=Ljava/io/DataInputStream;
cls sig=Ljava/io/DataInput;
cls sig=Lsun/nio/cs/UTF_8$Encoder;
cls sig=Ljava/lang/Throwable;
cls sig=[Ljava/lang/Throwable;
cls sig=Ljava/io/BufferedWriter;
cls sig=Lsun/nio/cs/UTF_8$Decoder;
cls sig=Ljava/lang/Float;
cls sig=Ljava/lang/Number;
cls sig=Ljava/lang/Runtime;
cls sig=Ljava/lang/Error;
cls sig=[Ljava/lang/Error;
cls sig=Ljava/lang/ThreadDeath;
cls sig=Ljava/lang/Exception;
cls sig=Ljava/lang/RuntimeException;
cls sig=Ljava/security/Policy$UnsupportedEmptyCollection;
cls sig=Ljava/security/ProtectionDomain;
cls sig=[Ljava/security/ProtectionDomain;
cls sig=Ljava/io/FilePermissionCollection;
cls sig=Ljava/lang/Double;
cls sig=Ljava/io/File;
cls sig=[Ljava/io/File;
cls sig=Ljava/net/URL;
cls sig=[Ljava/net/URL;
cls sig=Ljava/security/AllPermission;
cls sig=Ljava/security/UnresolvedPermission;
cls sig=Ljava/security/AccessControlContext;
cls sig=Ljava/lang/Byte;
cls sig=Ljava/util/zip/ZipException;
cls sig=Ljava/lang/Short;
cls sig=Ljava/security/BasicPermissionCollection;
cls sig=Ljava/lang/ClassNotFoundException;
cls sig=Ljava/lang/NoClassDefFoundError;
cls sig=Ljava/lang/LinkageError;
cls sig=Ljava/lang/ClassCastException;
cls sig=Ljava/security/Principal;
cls sig=[Ljava/security/Principal;
cls sig=Ljava/io/FileDescriptor$1;
cls sig=Ljava/lang/ArrayStoreException;
cls sig=Ljava/security/cert/Certificate;
cls sig=[Ljava/security/cert/Certificate;
cls sig=Ljava/lang/Integer;
cls sig=Ljava/lang/VirtualMachineError;
cls sig=[Ljava/lang/VirtualMachineError;
cls sig=Ljava/util/Locale;
cls sig=Ljava/lang/OutOfMemoryError;
cls sig=[Ljava/lang/OutOfMemoryError;
cls sig=Ljava/util/HashMap$HashIterator;
cls sig=Ljava/lang/StackOverflowError;
cls sig=Ljava/lang/IllegalMonitorStateException;
cls sig=Ljava/lang/ref/Reference;
cls sig=[Ljava/lang/ref/Reference;
cls sig=Ljava/lang/ref/SoftReference;
cls sig=Ljava/io/FileSystem;
cls sig=Ljava/lang/ref/WeakReference;
cls sig=[Ljava/lang/ref/WeakReference;
cls sig=Lsun/misc/JavaIOFileDescriptorAccess;
cls sig=Ljava/lang/ref/FinalReference;
cls sig=Ljava/util/zip/ZipFile$1;
cls sig=Ljava/lang/ref/PhantomReference;
cls sig=Ljava/lang/ref/Finalizer;
cls sig=Ljava/io/UnixFileSystem;
cls sig=Ljava/lang/InterruptedException;
cls sig=Ljava/lang/Thread;
cls sig=[Ljava/lang/Thread;
cls sig=Ljava/lang/Runnable;
cls sig=[Ljava/lang/Runnable;
cls sig=Ljava/lang/Long;
cls sig=Ljava/util/concurrent/ConcurrentHashMap;
cls sig=Ljava/util/concurrent/ConcurrentMap;
cls sig=Ljava/io/ExpiringCache;
cls sig=LTest$1;


启动时加载的结果:乱码,待查
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
cls sig=
众所周知,Java编译后的Jar包和Class文件,可以轻而易举的使用反编译工具(如JD-GUI)进行反编译,拿到源码。为了保护自己发布的Jar包和Class文件,采用的方式大多是混淆方式,这种方式对于Class文件的加密是不彻底的,还是能够通过分析得出核心算法。本工具是采用jvmti方式对Class文件进行加密,使用C++生成加密和解密库,先用加密库对Jar包进行加密,将加密后的Jar包及解密库文件发布出去,执行时候需要JVM引入解密库文件,解密后执行。c++的.dll文件和.so文件的破解难度是很大的,这就能有效的保护软件和代码的知识产权. 使用方法: 1.打开windows命令行(运行=>cmd=>回车),在命令行中 进入 EncryptJar目录 2.执行 java -jar encrypt.jar 3.输入h,然后回车,可以看到帮助菜单 4.输入3,然后按回车键,进入加入jar文件功能 5.输入要加密的jar文件的路径 6.提示输入秘钥(key)的时候,直接回车,不要输入任何字符(否则后面classhook将不可解密加密后的jar包) 7.输入目标路径(加密后的jar文件路径,此处要注意:jar文件名要保持相同,将加密后的文件保存到不同的目录) 8.将加密后的jar包,替换原来的没有加密的jar包,与要发布的程序一起进行发布.(一般替换lib目录下对应的jar包即可) 9.加密后的jar包运行方法: windows下: 拷贝libClassHook.dll文件到程序的根目录(通常为要执行的jar程序的根目录) 使用以下命令启动程序: java -agentlib:libClassHook -jar xxxxxxxxxxx.jar 则在运行过程中会自动进行解密操作(解密过程是运行过程中用c++的dll进行解密的,可以有效防止破解class文件) 如果执行过程报错,可将程序根目录添加到环境变量path中去 Linux下: 拷贝libClassHook.so到程序的根目录(通常为要执行的jar程序的根目录) 使用以下命令启动程序: java -agentlib:ClassHook -jar xxxxxxxxxxx.jar (这里要删除掉lib,linux系统下会自动补全) 则在运行过程中会自动进行解密操作(解密过程是运行过程中用c++的dll进行解密的,可以有效防止破解class文件) 如果执行过程报错,可以在程序根目录下执行以下语句:export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH 或将libClassHook.so 拷贝到/usr/lib目录中去。 支持操作系统:加密请在windows64位系统并安装了64位jdk环境下进行。 需要解密运行的程序支持LINUX(64位)和windows(64位)安装了JDK1.8以上的系统。 测试程序: (t_lib目录下的jar包为经过加密的jar包) java -agentlib:libClassHook -jar test.jar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值