使用javassist修改class文件

上传人:kms****20 文档编号:41294255 上传时间:2018-05-29 格式:DOC 页数:10 大小:43KB
返回 下载 相关 举报
使用javassist修改class文件_第1页
第1页 / 共10页
使用javassist修改class文件_第2页
第2页 / 共10页
使用javassist修改class文件_第3页
第3页 / 共10页
使用javassist修改class文件_第4页
第4页 / 共10页
使用javassist修改class文件_第5页
第5页 / 共10页
点击查看更多>>
资源描述

《使用javassist修改class文件》由会员分享,可在线阅读,更多相关《使用javassist修改class文件(10页珍藏版)》请在金锄头文库上搜索。

1、使用使用 javassistjavassist 修改修改 classclass 文件文件本文由 beikexiami 贡献doc 文档可能在 WAP 端浏览体验不佳。建议您优先选择 TXT,或下载源文件到本机查看。使用 javassist 修改 class 文件Firestorm 是一个用 JAVA 写的代码生成工具,可以替你节省很多的代码量,可以说同类软件中功能最强 的一个。 Firestorm 是一个用 JAVA 写的代码生成工具,可以替你节省很多的代码量,可以说同类软件中功能最强 的一个。 你可以在网上下载到最新的 2.3 试用版本,同时网站会发给你一个试用的 license 文件。既然

2、是试用, 那么在使用上肯定有一定的限制。主要限制有 3 个: 1.只能最多生成 5 张表的 DAO; 2.有时间限制; 3.不能自己定制代码生成; 为了能够更好的试用这个软件,我得改改它,去掉这些限制。将 firestorm.jar 打开后,可以看到它使用 了 混淆器进行代码保护, 不同于大多数的混淆器生成的文件, 它的 class 和 package 大部分都是以关键字来 命名, 所以如果你用 JAD 之类的工具把它反编译后是不能再把它编译成功,编译器会提示出错误。 反编译后,找到几个有关注册的关键文件,发现它使用的是数字签名技术来做的保护,所以想逆向找出 注册码的计算方法是不可行的了,只能

3、通过修改文件的方法来破解。通常我们是先反编译,然后再修改 反编译后生成的原文件,最后再重新编译。但是由于文件名和包名的关系我们无法进行编译,除非把它的 这些非法的文件名和包名全部改成符合 java 语言规范的名称,由于类,包众多,互相调用也很 频繁,所以这种方法几乎不可能的。 另外一种方法就是使用 softice 之类的调试软件来破解,不过这个脱离 JAVA 的范畴,这里不做讨论。 还有一种方法可能很少有人用,就是先反编译得到原文件,然后找到关键的方法后修改它的字节码, 也就是 class 文件,这中方法往往需要你知道一些有关 CLASS 文件格式方面的知识(如果没有也不用担 心) , 有许多

4、的处理字节码的工具可以帮助你,比较流行的这类工具主要有:apache.org 的 BCEL; 的 javassist;objectweb.org 的 asm。都是出身名门哈。这 3 个工具各有特点, 这次我选用 javassist,因为它修改 class 文件最方便,甚至不需要懂得字节码和 class 文件格式。 让我们来看看具体步骤:step1: 下载并安装 FIRESTORM。 step2: 反编译 jar 文件,阅读代码,找到关键的方法。当然,我这里写出来,你就不用再麻烦了。 (其实这步 是最 麻烦的) 。 找到 com.codefutures.if.if 文件中的方法 public

5、static boolean a(java.security.PublicKey publickey,byte abyte0, byte abyte1) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.InvalidKeyException, java.security.SignatureException java.security.Signature java.security.Signature.getInstance(“SHA1with

6、DSA“, “SUN“); signature.initVerify(publickey); signature.update(abyte0); return signature.verify(abyte1); 这个方法是对公钥进行检验,修改的思路就是直接让他返回一个 true. signature =step2: 收到 firestorm.license 文件后不要急着安装,先修改如下: no 改为 yes 5 改为 none 日期改为 never 修改后放到 firestorm 的安装路径的 license 目录。step3: 修改 com.codefutures.if.if 的 clas

7、s 文件.这里我们需要写一个小程序来完成实现: import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod;public class Test public static void main(String args) throws Exception ClassPool pool = ClassPool.getDefault(); /设置目标类的路径,确保能够找到需要修改的类,这里我指向 firestorm.jar /解包后的路径pool.insertClassPath(“d:/work/fir

8、estorm/firestorm“) ; /获得要修改的类 CtClass cc = pool.get(“com.codefutures.if.if“); /设置方法需要的参数 CtClass param = new CtClass3 ; param0 = pool.get(“java.security.PublicKey“) ; param1 = pool.get(“byte“) ; param2 = pool.get(“byte“) ; /得到方法 CtMethod m = cc.getDeclaredMethod(“a“, param); /插入新的代码 m.insertBefore(“

9、return true ;“) ; /保存到文件里 cc.writeFile() ; 修改完后,你可以反编译修改过的的 class 文件,看看代码是否加入成功。step4: 将所有的 class 文件重新打包成 firestorm.jar,然后替换 firestorm 安装路径/lib/firestorm.jar,再启动 firestorm 即可。一、直接修改字节码 要查看“return false”对应字节码需要使用 JClassLib 工具,JClassLib 有一个可视 化的界面,方便我们查看类的变量、方法、静态数据等,如下图:这个 a 方法(也许实际名称就是 sendsms)的字节码如

10、下: 0 aload_0 1 invokestatic #42 4 checkcast #11 7 dup 8 astore_2 9 ldc #61 11 invokeinterface #48 count 2 16 checkcast #12 19 astore_3 20 aload_2 21 invokestatic #29 24 ifne 34 (+10)27 aload_3 28 invokestatic #29 31 ifeq 36 (+5) 34 iconst_0 35 ireturn 36 aload_3 37 aload_0 38 invokeinterface #50 cou

11、nt 2 43 aload_3 44 aload_1 45 invokeinterface #51 count 2 50 aload_2 51 aload_3 52 invokeinterface #49 count 2 57 aload_2 58 invokeinterface #47 count 1 63 iconst_1 64 ireturn 65 pop 66 iconst_0 67 ireturn 通过查找 JVM 指令集, 0x03 iconst_0 int 型 1 推送至栈顶 ,0xac ireturn 的 将 int 型 0 推送至栈顶 , 0x04 iconst_1 将从当前

12、方法返回 int,很明显,63-67 行就是对应return true; JVM INSTR pop ; return false; 这 5 行对应的 16 进制值是: 0x04,0xAC,0x57,0x03,0xAC,于是, 16 进制编辑器打开, 用 查找 04AC5703AC 的位置,果然不负众望,接下来你知道怎么做了吧,把 0x03 这个位置的值 换成 0x04,那么这个 return false 不就变成 return true 了,呵呵。JVM 指令集及各指令的详细使用说明1. 指令码 助记符 2. 0x00 nop 说明 什么都不做 将 int 型-1 推送至栈顶 将 int 型

13、 0 推送至栈顶 将 int 型 1 推送至栈顶 将 int 型 2 推送至栈顶 将 int 型 3 推送至栈顶 将 int 型 4 推送至栈顶 将 int 型 5 推送至栈顶 将 long 型 0 推送至栈顶 将 long 型 1 推送至栈顶 将 float 型 0 推送至栈顶 将 float 型 1 推送至栈顶 将 float 型 2 推送至栈顶 将 double 型 0 推送至栈顶 将 double 型 1 推送至栈顶 将单字节的常量值(-128127)推送至栈顶 将一个短整型常量值(-3276832767)推送至栈顶 将 int, float 或 String 型常量值从常量池中推送至

14、栈顶 将 int, float 或 String 型常量值从常量池中推送至栈顶(宽索引) 将 long 或 double 型常量值从常量池中推送至栈顶(宽索引) 将指定的 int 型本地变量推送至栈顶 将指定的 long 型本地变量推送至栈顶 将指定的 float 型本地变量推送至栈顶 将指定的 double 型本地变量推送至栈顶 将指定的引用类型本地变量推送至栈顶 将第一个 int 型本地变量推送至栈顶 将第二个 int 型本地变量推送至栈顶 将第三个 int 型本地变量推送至栈顶3. 0x01 aconst_null 将 null 推送至栈顶 4. 0x02 iconst_m1 5. 0x

15、03 iconst_0 6. 0x04 iconst_1 7. 0x05 iconst_2 8. 0x06 iconst_3 9. 0x07 iconst_4 10. 0x08 iconst_5 11. 0x09 lconst_0 12. 0x0a lconst_1 13. 0x0b fconst_0 14. 0x0c fconst_1 15. 0x0d fconst_2 16. 0x0e dconst_0 17. 0x0f dconst_1 18. 0x10 bipush 19. 0x11 sipush 20. 0x12 ldc 21. 0x13 ldc_w 22. 0x14 ldc2_w

16、23. 0x15 iload 24. 0x16 lload 25. 0x17 fload 26. 0x18 dload 27. 0x19 aload 28. 0x1a iload_0 29. 0x1b iload_1 30. 0x1c iload_231. 0x1d iload_3 32. 0x1e lload_0 33. 0x1f lload_1 34. 0x20 lload_2 35. 0x21 lload_3 36. 0x22 fload_0 37. 0x23 fload_1 38. 0x24 fload_2 39. 0x25 fload_3 40. 0x26 dload_0 41. 0x27 dload_1 42. 0x28 dload_2 43. 0x29 dload_3 44. 0x2a aload_0 45. 0x2b aload_1 46. 0x2c aload_2 47. 0x2d aload_3 48. 0x2e iaload 49. 0x2f

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号