- $Proxy该类是动态生成的,在运行的时候生成。具体源代码的提取参考的是:http://www.cnblogs.com/ctgulong/p/5011614.html?utm_source=tuicool&utm_medium=referral的blog
2.根据上面博客的内容详细写一下生成源代码的过程。参考之前的项目http://yinyueml.blog.51cto.com/4841237/1876473
1)首先需要一个agent的生成类。javaagent主要功能如下:
- 可以在加载class文件之前做拦截,对字节码做修改
- 可以在运行期对已加载类的字节码做变更,但是这种情况下会有很多的限制,后面会详细说
- 还有其他一些小众的功能
- 获取所有已经加载过的类,这个功能让我们可以获取到动态代理的生成类的class文件,经过反编译后就可以查看源代码。
- 获取所有已经初始化过的类(执行过clinit方法,是上面的一个子集)
- 获取某个对象的大小
- 将某个jar加入到bootstrap classpath里作为高优先级被bootstrapClassloader加载
- 将某个jar加入到classpath里供AppClassloard去加载
- 设置某些native方法的前缀,主要在查找native方法的时候做规则匹配
2)代码如下
package jdkReview; import java.io.File; import java.io.FileOutputStream; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.lang.instrument.Instrumentation; import java.security.ProtectionDomain; public class CustomAgent implements ClassFileTransformer { // public static void premain(String agentArgs, Instrumentation inst) { inst.addTransformer(new CustomAgent()); } @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (!className.startsWith("java") && !className.startsWith("sun")) { // 既不是java也不是sun开头的 // 导出代码 int lastIndexOf = className.lastIndexOf("/") + 1; String fileName = className.substring(lastIndexOf) + ".class"; exportClazzToFile("D:/javacode/", fileName, classfileBuffer); System.out.println(className + " --> EXPORTED Succeess!"); } return classfileBuffer; } /** * * @param dirPath *目录以/结尾,且必须存在 * @param fileName * @param data */ private void exportClazzToFile(String dirPath, String fileName, byte[] data) { try { File file = new File(dirPath + fileName); if (!file.exists()) { file.createNewFile(); } FileOutputStream fos = new FileOutputStream(file); fos.write(data); fos.close(); } catch (Exception e) { System.out.println("exception occured while doing some file operation"); e.printStackTrace(); } } }
3)将CustomAgent导出为jar包,并且修改MANIFEST.MF文件内容如下:
Manifest-Version: 1.0 Premain-Class: jdkReview.CustomAgent
该配置主要是为了Premain-Class的作用就是表示带有premain静态方法的Class。
4)在运行使用java动态代理的Client类的时候加上jvm的参数
-javaagent:d:/customAgent.jar
然后运行后如下结果为:
proxyPattern/Client --> EXPORTED Succeess! proxyPattern/GamePlayer --> EXPORTED Succeess! proxyPattern/IGamePlayer --> EXPORTED Succeess! proxyPattern/GamePlayIH --> EXPORTED Succeess! com/sun/proxy/$Proxy0 --> EXPORTED Succeess! 有人再用我的账号登陆 登陆用户名:yinyueml;玩家:张三上线 张三正在打怪。 张三升级了
现在通过
exportClazzToFile("D:/javacode/", fileName, classfileBuffer);
中的配置路劲就可以找到$Proxy0.class的文件。
5)通过jad.exe反编译应用对$Proxy0.class进行反编译就可以获取到源代码。
时间: 2024-10-08 20:50:46