您的位置:首页 > 编程语言 > Java开发

java反编译工具jd-core

2016-07-29 12:43 821 查看
java的反编译工具有那么几款,使用最广泛的当属jd-gui,速度快,功能强大。网上介绍反编译工具的文章也不少,但几乎没有介绍如何与程序对接的。jd-gui的设计相当精妙,核心就是jd-core,但核心几乎没有人提到,开源的jd-gui也没有找到core的踪影。我是这么获的jd-core的,在官网下载jd-gui-1.4.0.jar,删除其他只保留jd文件夹,里面就是core了。反编译jd-core之后发现api使用也相当简单:jd.core.Decompiler----反编译接口jd.core.process.DecompilerImpl--反编译接口实现 只有一个方法:public void <strong>decompile</strong>(jd.core.preferences.Preferences preferences, jd.core.loader.Loader loader, jd.core.printer.Printer printer, java.lang.String internalClassPath) throws jd.core.loader.LoaderException;Preferences 为配置,构造方法只有两个参数:
<h5><div style="padding-top: 2px; margin-left: 20px; position: relative; -ms-word-wrap: break-word;"><a target=_blank href="eclipse-open:%E2%98%82=boss/jd-core-1.4.0.jar%3Cjd.core.preferences(Preferences.class%E2%98%83Preferences~Preferences~Z~Z"></a><a target=_blank class="header" href="eclipse-javadoc:%E2%98%82=boss/jd-core-1.4.0.jar%3Cjd">jd</a>.<a target=_blank class="header" href="eclipse-javadoc:%E2%98%82=boss/jd-core-1.4.0.jar%3Cjd.core">core</a>.<a target=_blank class="header" href="eclipse-javadoc:%E2%98%82=boss/jd-core-1.4.0.jar%3Cjd.core.preferences">preferences</a>.<a target=_blank class="header" href="eclipse-javadoc:%E2%98%82=boss/jd-core-1.4.0.jar%3Cjd.core.preferences(Preferences.class%E2%98%83Preferences">Preferences</a>.Preferences(<span style="font-weight: normal;"></span>boolean showDefaultConstructor, <span style="font-weight: normal;"></span>boolean realignmentLineNumber) 参数含义不言自明</div></h5>
loader为加载文件(.class或.jar)的接口,自己实现也很简单internalClassPath 参数是内部路径,这个会作为参数传给load接口
稍微复杂点的就是Printer了 (再次赞叹jd灵活的设计)我这里实现一个简单的动态代理,仅为了减少一些方法实现而已,因为printer接口的方法比较多。final StringBuilder javaFileBuilder = new StringBuilder();// 将反编译后源码输出到StringBuilder// jd.core.printer.Printer接口代理的简单实现InvocationHandler h = new java.lang.reflect.InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String name = method.getName();System.out.println("Printer:: " + name + "(" + Arrays.toString(args) + ")");if (name.equals("print")) {javaFileBuilder.append(args[0]);} else if (name.equals("endOfLine")) {javaFileBuilder.append("\n");} else if (name.equals("printKeyword")) {javaFileBuilder.append(args[0]);} else if (name.equals("printTypeImport")) {javaFileBuilder.append(args[1]);} else if (name.equals("printMethodDeclaration")) {javaFileBuilder.append(args[1]);} else if (name.equals("printStaticMethodDeclaration")) {javaFileBuilder.append(args[1]);} else if (name.equals("printType")) {javaFileBuilder.append(args[0].toString().replace('/', '.'));} else if (name.equals("printString")) {javaFileBuilder.append(args[0]);} else if (name.equals("printStaticMethod")) {javaFileBuilder.append(args[1]);} else if (name.equals("printMethod")) {javaFileBuilder.append(args[1]);} else if (name.equals("printField")) {javaFileBuilder.append(args[1]);} else if (name.equals("printConstructor")) {javaFileBuilder.append(args[0].toString().replace('/', '.'));} else if (name.equals("printNumeric")) {javaFileBuilder.append(args[0]);} else if (name.equals("printTypeDeclaration")) {javaFileBuilder.append(args[1]);}return null;}};Printer printer = (Printer) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { Printer.class },h);loader接口的实现比较简单,就不贴了,读者自己解决吧,下面是最终的反编译的调用:DecompilerImpl de = new DecompilerImpl();de.decompile(preferences, loader, printer, internalClassPath);
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息