分享
 
 
 

深入讨论JAVA字节码加密技术(2)

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

这个累加载器(EncryptedClassLoader)有两个基本的操作,在给定的类路径下加密一系列Class文件并且运行一个先前加密的程序。加密后的文件很简单,有一些极讨厌的各个字节的位组成。(当然,XOR运算符不可能被加密,这只是一个范例,请多多包涵。)

通过EncryptedClassLoader来加载类需要注意一些问题,我实现的是继承自java.net.URLClassLoader并且重载了loadClass()和defineClass()两个方法来实现自己的两个功能。一个是专心于JAVA 2 类加载器的委托规则并且在系统类加载器做之前先加载一个经加密过的类;二是在执行defineClass()之前立即调用crypt()方法,否则会执行URLClassLoader.findClass()。

执行下面的语句:

javac -d bin src/*.java src/my/secret/code/*.java

我把Main.class和MySecretClass.class进行了.加密:

java -cp bin EncryptedClassLoader -encrypt bin Main my.

secret.code.MySecretClass

encrypted [Main.class]

encrypted [my\secret\code\MySecretClass.class]

现在原先编译的class文件已经被加密后的文件所替代了,如果我想运行原始类文件,需要使用EncryptedClassLoader来操作:

java -cp bin Main

Exception in thread "main" java.lang.ClassFormatError:

Main (Illegal constant pool type)

at java.lang.ClassLoader.defineClass0(Native Method)

at java.lang.ClassLoader.defineClass(ClassLoader.java:502)

at java.security.SecureClassLoader.defineClass

(SecureClassLoader.java:123)

at java.net.URLClassLoader.defineClass(URLClassLoader.java:250)

at java.net.URLClassLoader.access$100(URLClassLoader.java:54)

at java.net.URLClassLoader$1.run(URLClassLoader.java:193)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:186)

at java.lang.ClassLoader.loadClass(ClassLoader.java:299)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)

at java.lang.ClassLoader.loadClass(ClassLoader.java:255)

at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:315)

java -cp bin EncryptedClassLoader -run bin Main

decrypted [Main]

decrypted [my.secret.code.MySecretClass]

secret result = 1362768201

现在可以确信,采用任何反编译工具对加密后的Class文件都不会起作用的。

现在添加一个可靠的密码保护机制,把它打包成本地可执行文件,并且使其对外收费。这样子可以吗?当然不能这样了。

ClassLoader.defineClass():必然经过的接口

所有的类加载器必须经过明确地API把类定义传递到JVM里,这就需要java.lang.ClassLoader.defineClass()方法了。类加载器的API有多个这个方法的重载,但是所有的方法都会调用defineClass(String, byte[], int, int, ProtectionDomain),这是一个在经过一些简单验证后放入到JVM里的最终的方法。如果你想建立一个新的Class文件的话,这对于理解每个类加载器都会不可避免的调用该方法是很重要的。

你只能在方法defineClass()里把一些单调的字节数组生成Class对象,并且我们猜测这些字节数组文件会包含一些文档格式化(查看class文件格式规范well-document.d format)的未加密的class定义,通过拦截对该方法的所有调用可以很简单的破坏这种加密模式,并且很方便的反编译你感兴趣的Class文件。

做这种拦截并不困难,实际上破坏自己建立的保护模式比用工具更加迅速的。首先,我取得基于J2SDK的java.lang.ClassLoader源文件,并修改defineClass(String, byte[], int, int, ProtectionDomain)方法,在里面加入其他的类。正如下面:

...

c = defineClass0(name, b, off, len, protectionDomain);

//Intercept classes defined by the system loader and its children:

if (isAncestor (getSystemClassLoader ().getParent ()))

{

// Choose your own dump location here [use an absolute pathname]:

final File parentDir = new File ("c:/TEMP/classes/");

File dump = new File (parentDir,

name.replace ('.', File.separatorChar) + "[" +

getClass ().getName () + "@" +Long.toHexString

(System.identityHashCode (this)) + "].class");

dump.getParentFile ().mkdirs ();

FileOutputStream out = null;

try

{

out = new FileOutputStream (dump);

out.write (b, off, len);

}

catch (IOException ioe)

{

ioe.printStackTrace (System.out);

}

finally

{

if (out != null) try { out.close (); }

catch (Exception ignore) {}

}

}

...

注意if里的语句可以过滤系统类加载器及其子类加载器,同样在defineClass()方法可以正常工作的情况下才能载入类。很难以相信不只有一个类加载器实例加载一个类,可通过在文件名堆里面加入类加载器标志我还是最终把这一问题给解决了。:-)

最后一步是用包含java.lang.ClassLoader类的可执行文件临时替换由JRE使用的文件rt.jar,你也可以使用-Xbootclasspath/p选项。

我再一次运行加密的程序,并恢复了所有的未加密的文件,这么说可以很容易的把.class文件正确的反编译。我先声明我并没有用EncryptedClassLoader类的内部机制来完成此壮举的。

在这里注意一点,假如我没去使用一个系统类,我可以使用别的方法,比如自定义一个JVMPI代理来处理JVMPI_EVENT_CLASS_LOAD_HOOK事件。

学习小结:

我希望你能对本文有所兴趣,你必须认识到得很重要的一点是在购买市面上任何反编译工具前要三思而行,除非JVM体系结构进行改革以支持class字节码在本地能进行译码转换,你才会更好的从传统的困惑中走出来,上演一场字节码的改革浪潮!当然也有其他的更有效的方法:对类加载进行调试。尽可能地得到类加载的轨迹是很有价值的,特别是在类加载时你去捕获异常情况下使用。因此,JAVA的诞生可能纯粹是为了开源项目,当然,其他一些体系结构(如:。NET)也正在倾向于反编译。目前我就说说这种思想了.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有