免费网站流量统计工具,音乐网站开发与设计,wordpress在线版本,头像制作免费软件浅谈JAVA程序破解作者#xff1a;舵手申明#xff1a;如转载请保证文章的完整性以及出处 最近对JAVA程序的破解比较感兴趣#xff0c;拿几个行业软件练了一下手#xff0c;略有心得#xff0c;拿出来与菜鸟分享#xff01;注意只是一点心得#xff0c;本文并不涉及具…浅谈JAVA程序破解作者舵手申明如转载请保证文章的完整性以及出处 最近对JAVA程序的破解比较感兴趣拿几个行业软件练了一下手略有心得拿出来与菜鸟分享注意只是一点心得本文并不涉及具体软件的破解。初学破解失误之处在所难免敬请高手赐教 直接进入正题对JAVA的破可从下面几方面入手一、反编译 工具很多建意用GUI工具命令行下的JAD很容易因为不能反编译某一个方法或某一行代码而终止整个文件的反编译但GUI的工具却能搞定虽然反编译后部分代码较难看懂但总比看jvm指命要好得多。而且GUI的工具多数有批量反编译功能且能让反编译的文件直接以.java为后缀保存也是方便之处。二、方法调用 安全意识强的开发者会把他的程序进行高质量的混淆下面就是一个例子public static Object getRemoteEJBHome(String OOOoOo00oO0O0O0ooOoOO, Class OO0oOO0O0o0oO0o00oOoO)throws NamingException{try{ if(OoO0o0o0O0oo0oO00oOO0 null) OoO0o0o0O0oo0oO00oOO0 OoOOoOOO0Oo0OO0OooO0o(); Object OOOOOo00000OoOoO0O000 PortableRemoteObject.narrow(OoO0o0o0O0oo0oO00oOO0.lookup(OOOoOo00oO0O0O0ooOoOO), OO0oOO0O0o0oO0o00oOoO); Object obj OOOOOo00000OoOoO0O000; return obj;}catch(NamingException OO0Ooo0oOO0OO0OOOoOo0){ System.out.println(OO0Ooo0oOO0OO0OOOoOo0.getMessage()); throw OO0Ooo0oOO0OO0OOOoOo0;}}这是我见过的最好的混淆效果变量都是由大小写的O和数字零组程要看懂这样的程序基本上是不可能的可能有人会想到用有意义的变量进行替换当然这也是一个方法但如果应用所包括的class文件数以千记那这个工作量是相当大的。B/S结构的授权方式一般都是文件的形式当然肯定是经过加密的。像下面的license就是经过了RSA非对称加密算法要分析license的构成有明文的license就更方便了而公钥是直接被写在class文件中的24D568B6A27AEFD683BC7A1CC93D11D074FB6B982A4B6E269712773BE536B40A67F1D345654F659C66D4265F5CE8FE0494B3AF33A8299A4F6B0E7500275A27EFF3B6D2E4983F14A9EA38A1AE3394B28A9C6D6924C15027F9B689FD9A3A689A301C4D4EB878D75C207F68BAA352F550D8F19876FFA255864FDE8A7E5939202E9F那么我们可以用eclipse建一个JAVA项目把应用的jar加入该项目的库搜索路径写一个自己的类调用解密方法得到明文license再分析。当然也可以调用其它一些方法从调用参数和最后的返回值我们也可大概猜对该方法的作用对付象上面经过高质量混淆的代码也比较管用。当然我这里只是简单的举两个例子其实“方法调用”的妙用还很多自己慢慢琢磨吧三、为class添加代码 反编译多数情况下也只能让我们看看作者的思路如果想把反编译出来的代码经过修改后再编译成class通常是行不通了。而且有时候必须让程序运行在它本身的环境才能行否则一些类无法得到正确的初始化“方法调用”也就起不了什么作用。搞过java的人一定知道javassist这个库提供了足够多的方法让你直接修改class文件而不需要你了解字节码的相关知识我们可以利用这个库解决上述的问题。下面是我写的一个修改字节码的类目前还不完善真正要用时可能需要根据情况做一些修改。import java.lang.reflect.*;import javassist.*;import java.io.*;/** * pTitle: JAVA 字节码修改类/p * pDescription: 得到类的相关信息或修改该类/p * pCopyright: Copyright () 2005/p * author 舵手 * version 1.0 */public class ModifyClass { private static int call_method; private static String _class; private static ClassPool pool; private static CtClass cc; private static String[] clas; /** * 修改字节码中的方法 * param clas[0] 待修改类的方法名 * param clas[1] 修改位置定义 * param clas[2] 使用insertAt方法插放代码时行号参数 * param clas[3] 修改内容 * return */ private static void modifyMethod() { String _method; _method clas[0]; try { CtClass[] param new CtClass[4] ; //param[0] pool.get(); //param[1] pool.get(); //param[2] pool.get(java.lang.String); //param[3] pool.get(java.lang.String); CtMethod cm cc.getDeclaredMethod(_method); if (clas[1].toLowerCase().equals(a)) { //方法的尾部加入代码 cm.insertAfter(clas[3]); } if (clas[1].toLowerCase().equals(b)) { //方法的首部加入代码 cm.insertBefore(clas[3]); } if (clas[1].toLowerCase().equals(i)) { System.out.println(cm.insertAt((Integer.valueOf(clas[2]).intValue()),clas[3])); } cc.writeFile(); } catch(Exception e) { e.printStackTrace(); } } /** * 在类中增加方法 * param clas[0] 源方法名称 * param clas[1] 新方法名称 * param clas[2] 增加类型 * param clas[3] 方法内容 * return */ private static void addMethod() { String _oldmethod; String _newmethod; _oldmethod clas[0]; _newmethod clas[1]; try { StringBuffer newMethodBody new StringBuffer(); if (clas[2].toLowerCase().equals(c)) { //add new Method (copy) CtMethod oldMethod cc.getDeclaredMethod(_oldmethod); CtMethod newMethod CtNewMethod.copy(oldMethod, _newmethod, cc, null); newMethodBody.append(clas[3]); newMethod.setBody(newMethodBody.toString()); cc.addMethod(newMethod); } if (clas[2].toLowerCase().equals(r)) { //add new Method (create) CtMethod newMethod CtNewMethod.make(clas[3], cc); cc.addMethod(newMethod); } cc.writeFile(); } catch(Exception e) { e.printStackTrace(); } } private static void getMethods(){ CtMethod[] cms cc.getDeclaredMethods(); System.out.println(); System.out.println(cc.getName() 类的所有方法); for (int i0 ; icms.length ; i ) { System.out.println(cms[i].getName()); } } private static void getFields(){ CtField[] cfs cc.getDeclaredFields(); System.out.println(); System.out.println(cc.getName() 类的所有属性); for (int i0 ; icfs.length ; i ) { System.out.println(cfs[i].getName()); } } private static void delMethod(){ try{ CtMethod cm cc.getDeclaredMethod(clas[0]); cc.removeMethod(cm); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args) { StringBuffer buf new StringBuffer(500); int c; System.out.print(请输入操作类名); try{ while ((c System.in.read()) ! 13) { buf.append((char)c); } _class buf.toString(); pool ClassPool.getDefault(); cc pool.get(_class); buf.delete(0,buf.length()); System.out.println(***********************************************************); System.out.println(可供调用的方法有); System.out.println(1-modifyMethod2-addMethod3-getMethods4-getFields5-removeMethod); System.out.println(***********************************************************); System.out.print(请选择调用方法); while ((c System.in.read()) ! 13) { if (c 10) continue; buf.append((char)c); } call_method Integer.parseInt(buf.toString()); if (call_method 1) { System.out.println(***********************************************************); System.out.println(调用 modifyMethod 方法参数); System.out.println(方法名称,插入位置,行号,内容); System.out.println(***********************************************************); buf.delete(0,buf.length()); while ((c System.in.read()) ! 13) { if (c 10) continue; buf.append((char)c); } clas (buf.toString()).split(,); modifyMethod(); } buf.delete(0,buf.length()); if (call_method 2) { System.out.println(***********************************************************); System.out.println(调用 addMethod 方法参数); System.out.println(源方法,目标方法,建立方式,内容); System.out.println(***********************************************************); buf.delete(0,buf.length()); while ((c System.in.read()) ! 13) { if (c 10) continue; buf.append((char)c); } clas (buf.toString()).split(,); addMethod(); } if (call_method 3) { getMethods(); } if (call_method 4) { getFields(); } if (call_method 5) { System.out.println(***********************************************************); System.out.println(调用 removeMethod 方法参数); System.out.println(方法名称); System.out.println(***********************************************************); buf.delete(0,buf.length()); while ((c System.in.read()) ! 13) { if (c 10) continue; buf.append((char)c); } clas (buf.toString()).split(,); delMethod(); } }catch(IOException ioe) { System.out.println(); ioe.printStackTrace(); System.exit(0); } catch(NotFoundException nfe) { System.out.println(); nfe.printStackTrace(); System.exit(0); } catch(NumberFormatException nfe) { System.out.println(); nfe.printStackTrace(); System.exit(0); } }} modifyMethod方法用来在类的指定方法中插入一行或多行代码参数为a时表示插在方法现有代码的最后面为b时表示插在方法现有代码的最前面为i时表时插在代码的指定行的前面这个行和原代码中的行没有关系插入位置要插入一次才能确定为i时返回的值代表实际插入位置由这个实际插入位置你可以计算i的值。在实际破解中发现用该方法插入一些代码后会使原来反编译的不可读的代码变的容易读懂当然也有可能使本来可读性很强的代码因为你插入了一些语句而变得不可读。我常常在关键方法的代码中插入一些 System.out.println();这样的代码来跟踪程序还有一点限制你不能直接用打印输出的方法来输出方法体内的局部变量但你可以对全局变量进行引用操作。如果要操作局部变量目前我所知的方法只能在该类里重建该方法如果那位有其它的好办法也请指点我一下。 addMethod方法在是类中增加一个新的方法增加的方式有两种这里就不做具体介绍。 其它方法也就不一一解释了有兴趣的朋友可以研究一下javassist相信你会写出功能更强大的修改class文件的类库。四、class的修改 在破解过程中经常会看到rsa非对称加密算法公钥往往以十六进制存放在class文件中当然也有对公钥加密后存放在配置文件中的程序以便解密已经加密过的信息。前不久破解的一个J2EE的开发平台就是这样的license用RSA加密在搞懂了它的算法后自己构件license明文自己再生成一对rsa的公私密钥用自己的私钥对license文明进行RSA加密再用十六进制编辑器替换程序中所有的公钥当然是用你的公钥替换他的公钥不然也没法解密一切就搞定。当然我所说的只是一个方面有时暴破时可能还得用到一些JVM的指命比如你想让一个 return false 的方法 return ture那你就得把相应位置的03 AC改为04 AC位置怎么确定就不用我说了吧五、读JVM指令 没有什么可以多说的如果要从jvm指令看懂成程必须像熟汇编一样熟悉jvm指令集还得有一个工具把class翻译成jvm指令代码总不能用十六进制编辑器读代码吗如果真是那你就太牛了。我这里介绍 bcel 这个工具它可以把class解释为jvm指令集并存为html文件结果就像下面0 getstatic System.out Ljava/io/PrintStream; 3 ldc is one 5 invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V(String):void 8 getstatic System.out Ljava/io/PrintStream; 11 ldc is two 13 invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V(String):void 16 getstatic System.out Ljava/io/PrintStream; 19 ldc is three 21 invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V(String):void 24 getstatic System.out Ljava/io/PrintStream; 27 ldc is four 29 invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V(String):void 32 return 这是一个方法的全部指令熟悉jvm指令集的话就已经能读懂它在做什么了 发现有关JAVA程序破解的文章不是很多所以本人粗浅的谈论了一下JAVA程序破解时所用到的一些方法当然还有很多凭经验才能找到的灵感无法一一列举本文质在抛砖引玉望高手能写一些技术含量更高的文章供我们这些菜鸟学习。 文章转载自: http://www.morning.nfqyk.cn.gov.cn.nfqyk.cn http://www.morning.nrjr.cn.gov.cn.nrjr.cn http://www.morning.kjdxh.cn.gov.cn.kjdxh.cn http://www.morning.mmxnb.cn.gov.cn.mmxnb.cn http://www.morning.mqlsf.cn.gov.cn.mqlsf.cn http://www.morning.bzjpn.cn.gov.cn.bzjpn.cn http://www.morning.wsnbg.cn.gov.cn.wsnbg.cn http://www.morning.gqjqf.cn.gov.cn.gqjqf.cn http://www.morning.kpygy.cn.gov.cn.kpygy.cn http://www.morning.ftsmg.com.gov.cn.ftsmg.com http://www.morning.brzlp.cn.gov.cn.brzlp.cn http://www.morning.jwqqd.cn.gov.cn.jwqqd.cn http://www.morning.jkcnq.cn.gov.cn.jkcnq.cn http://www.morning.rjjjk.cn.gov.cn.rjjjk.cn http://www.morning.ktmnq.cn.gov.cn.ktmnq.cn http://www.morning.nrrzw.cn.gov.cn.nrrzw.cn http://www.morning.xfyjn.cn.gov.cn.xfyjn.cn http://www.morning.jljwk.cn.gov.cn.jljwk.cn http://www.morning.gjwkl.cn.gov.cn.gjwkl.cn http://www.morning.xbkcr.cn.gov.cn.xbkcr.cn http://www.morning.pqjlp.cn.gov.cn.pqjlp.cn http://www.morning.nxhjg.cn.gov.cn.nxhjg.cn http://www.morning.njpny.cn.gov.cn.njpny.cn http://www.morning.lzbut.cn.gov.cn.lzbut.cn http://www.morning.wdply.cn.gov.cn.wdply.cn http://www.morning.jtdrz.cn.gov.cn.jtdrz.cn http://www.morning.kxgn.cn.gov.cn.kxgn.cn http://www.morning.qyfqx.cn.gov.cn.qyfqx.cn http://www.morning.ylqrc.cn.gov.cn.ylqrc.cn http://www.morning.zxwqt.cn.gov.cn.zxwqt.cn http://www.morning.bmts.cn.gov.cn.bmts.cn http://www.morning.tdxnz.cn.gov.cn.tdxnz.cn http://www.morning.kmwbq.cn.gov.cn.kmwbq.cn http://www.morning.fnywn.cn.gov.cn.fnywn.cn http://www.morning.ynlbj.cn.gov.cn.ynlbj.cn http://www.morning.etsaf.com.gov.cn.etsaf.com http://www.morning.zybdj.cn.gov.cn.zybdj.cn http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn http://www.morning.yybcx.cn.gov.cn.yybcx.cn http://www.morning.kfsfm.cn.gov.cn.kfsfm.cn http://www.morning.yrbqy.cn.gov.cn.yrbqy.cn http://www.morning.wrysm.cn.gov.cn.wrysm.cn http://www.morning.jxwhr.cn.gov.cn.jxwhr.cn http://www.morning.rwlsr.cn.gov.cn.rwlsr.cn http://www.morning.crdtx.cn.gov.cn.crdtx.cn http://www.morning.lwgrf.cn.gov.cn.lwgrf.cn http://www.morning.lokext.com.gov.cn.lokext.com http://www.morning.zrmxp.cn.gov.cn.zrmxp.cn http://www.morning.ydryk.cn.gov.cn.ydryk.cn http://www.morning.kwqwp.cn.gov.cn.kwqwp.cn http://www.morning.rbjp.cn.gov.cn.rbjp.cn http://www.morning.jyjqh.cn.gov.cn.jyjqh.cn http://www.morning.ydnx.cn.gov.cn.ydnx.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.kwnbd.cn.gov.cn.kwnbd.cn http://www.morning.prxqd.cn.gov.cn.prxqd.cn http://www.morning.bdypl.cn.gov.cn.bdypl.cn http://www.morning.tkryt.cn.gov.cn.tkryt.cn http://www.morning.syglx.cn.gov.cn.syglx.cn http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.zzfjh.cn.gov.cn.zzfjh.cn http://www.morning.ryxgk.cn.gov.cn.ryxgk.cn http://www.morning.chzqy.cn.gov.cn.chzqy.cn http://www.morning.kpgms.cn.gov.cn.kpgms.cn http://www.morning.bklkt.cn.gov.cn.bklkt.cn http://www.morning.ryysc.cn.gov.cn.ryysc.cn http://www.morning.wxckm.cn.gov.cn.wxckm.cn http://www.morning.tsflw.cn.gov.cn.tsflw.cn http://www.morning.xltdh.cn.gov.cn.xltdh.cn http://www.morning.rdzlh.cn.gov.cn.rdzlh.cn http://www.morning.xrtsx.cn.gov.cn.xrtsx.cn http://www.morning.ymqfx.cn.gov.cn.ymqfx.cn http://www.morning.tnjz.cn.gov.cn.tnjz.cn http://www.morning.ktpzb.cn.gov.cn.ktpzb.cn http://www.morning.mhmcr.cn.gov.cn.mhmcr.cn http://www.morning.yqgny.cn.gov.cn.yqgny.cn http://www.morning.kryr.cn.gov.cn.kryr.cn http://www.morning.tdscl.cn.gov.cn.tdscl.cn http://www.morning.kqkmx.cn.gov.cn.kqkmx.cn