11package com .threedr3am .bug .asm ;
22
33import com .google .common .reflect .ClassPath ;
4+ import com .sun .org .apache .bcel .internal .Constants ;
45import java .io .IOException ;
56import java .io .InputStream ;
7+ import java .lang .reflect .Method ;
8+ import org .mozilla .javascript .GeneratedClassLoader ;
69import org .objectweb .asm .AnnotationVisitor ;
710import org .objectweb .asm .Attribute ;
811import org .objectweb .asm .ClassReader ;
912import org .objectweb .asm .ClassVisitor ;
13+ import org .objectweb .asm .ClassWriter ;
1014import org .objectweb .asm .FieldVisitor ;
1115import org .objectweb .asm .Handle ;
1216import org .objectweb .asm .Label ;
1822
1923/**
2024 * 学习asm字节码操作,fuzz基础
25+ *
2126 * @author xuanyh
2227 */
2328public class Test {
@@ -45,34 +50,48 @@ public static void main(String[] args) {
4550 try (InputStream in = Thread .currentThread ().getContextClassLoader ()
4651 .getResourceAsStream ("com.threedr3am.bug.asm.Test" .replace ("." , "/" ) + ".class" )) {
4752 ClassReader cr = new ClassReader (in );
53+ ClassWriter cw = new ClassWriter (ClassWriter .COMPUTE_MAXS );
4854 try {
49- MethodCallDiscoveryClassVisitor visitor = new MethodCallDiscoveryClassVisitor (
50- Opcodes .ASM6 );
55+ MyClassVisitorAdapter visitor = new MyClassVisitorAdapter (
56+ Opcodes .ASM6 , cw );
5157 cr .accept (visitor , ClassReader .EXPAND_FRAMES );
58+ GeneratorClassLoader classLoader = new GeneratorClassLoader ();
59+ classLoader .defineClassFromClassFile ("com.threedr3am.bug.asm.Test" , cw .toByteArray ());
60+ Class c = classLoader .loadClass ("com.threedr3am.bug.asm.Test" );
61+ Object o = c .newInstance ();
62+ Method method = c .getDeclaredMethod ("test" , new Class []{String .class });
63+ method .invoke (o , "输入参数" );
5264 } catch (Exception e ) {
5365 e .printStackTrace ();
5466 }
5567 }
5668 } catch (IOException e ) {
5769 e .printStackTrace ();
5870 }
71+ }
5972
60- new Test ().test ();
73+ public void test (String str ) {
74+ System .out .println ("call Test.test(" + str + ")" );
6175 }
6276
63- public void test () {
64- System .out .println ("call Test.test()" );
77+ public static class GeneratorClassLoader extends ClassLoader {
78+
79+ public Class defineClassFromClassFile (String className , byte [] classFile )
80+ throws ClassFormatError {
81+ return defineClass (className , classFile , 0 , classFile .length );
82+ }
6583 }
6684
6785 /**
6886 * ClassVisitor 基于观察者模式的class asm操作
6987 *
70- * visit -> visitSource -> visitInnerClass -> visitInnerClass -> visitMethod -> visitMethod -> visitMethod -> visitEnd
88+ * visit -> visitSource -> visitInnerClass -> visitInnerClass -> visitMethod -> visitMethod ->
89+ * visitMethod -> visitEnd
7190 */
72- private static class MethodCallDiscoveryClassVisitor extends ClassVisitor {
91+ private static class MyClassVisitorAdapter extends ClassVisitor {
7392
74- public MethodCallDiscoveryClassVisitor (int api ) {
75- super (api );
93+ public MyClassVisitorAdapter (int api , ClassVisitor cv ) {
94+ super (api , cv );
7695 }
7796
7897 @ Override
@@ -140,11 +159,8 @@ public FieldVisitor visitField(int access, String name, String descriptor, Strin
140159 private String name = null ;
141160
142161 /**
143- *
144162 * @param version 字节码版本
145- * @param access
146163 * @param name 类全限定名
147- * @param signature
148164 * @param superName 继承的基类
149165 * @param interfaces 实现的接口
150166 */
@@ -167,13 +183,10 @@ public void visit(int version, int access, String name, String signature,
167183 }
168184
169185 /**
170- *
171- * @param access
172186 * @param name 方法名
173187 * @param desc 方法参数和返回值
174188 * @param signature 方法签名
175189 * @param exceptions 方法抛出的异常数组
176- * @return
177190 */
178191 @ Override
179192 public MethodVisitor visitMethod (int access , String name , String desc ,
@@ -186,31 +199,28 @@ public MethodVisitor visitMethod(int access, String name, String desc,
186199// System.out.println("desc: " + desc);
187200// System.out.println("signature: " + signature);
188201// System.out.println("exceptions: " + Arrays.toString(exceptions));
189- MethodCallDiscoveryMethodVisitor modelGeneratorMethodVisitor = new MethodCallDiscoveryMethodVisitor (
190- api , mv , this .name , name , desc );
191202
192203 //适配器封装MethodVisitor,进行asm操作方法字节码
193- return new JSRInlinerAdapter (modelGeneratorMethodVisitor , access , name , desc , signature ,
194- exceptions );
204+ return new MethodVisitorAdapter (api , mv , this .name , name , desc );
195205 }
196206
197207 @ Override
198208 public void visitEnd () {
199- System .out .printf ("visitEnd -> " );
209+ System .out .printf ("visitEnd\n " );
200210 super .visitEnd ();
201211 }
202212 }
203213
204214 /**
205215 * MethodVisitor 基于观察者模式的method asm操作
206216 */
207- private static class MethodCallDiscoveryMethodVisitor extends MethodVisitor {
217+ private static class MethodVisitorAdapter extends MethodVisitor {
208218
209219 private String owner = null ;
210220 private MethodVisitor mv = null ;
211221 private String name = null ;
212222
213- public MethodCallDiscoveryMethodVisitor (final int api , final MethodVisitor mv ,
223+ public MethodVisitorAdapter (final int api , final MethodVisitor mv ,
214224 final String owner , String name , String desc ) {
215225 super (api , mv );
216226 this .owner = owner ;
@@ -255,9 +265,18 @@ public void visitAttribute(Attribute attribute) {
255265 super .visitAttribute (attribute );
256266 }
257267
268+ /**
269+ * 进入方法代码执行时会先执行该方法
270+ */
258271 @ Override
259272 public void visitCode () {
260273 super .visitCode ();
274+ if (name .equals ("test" )) {
275+ mv .visitFieldInsn (Opcodes .GETSTATIC , "java/lang/System" , "out" , "Ljava/io/PrintStream;" );
276+ mv .visitLdcInsn ("插入代码调用,输出字符串" );
277+ mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "java/io/PrintStream" , "println" ,
278+ "(Ljava/lang/String;)V" , false );
279+ }
261280 }
262281
263282 @ Override
@@ -383,14 +402,11 @@ public void visitEnd() {
383402 }
384403
385404 /**
405+ * TODO this.name base call method(调用方法) TODO this.owner base call class(调用类)
386406 *
387- * TODO this.name base call method(调用方法)
388- * TODO this.owner base call class(调用类)
389- * @param opcode
390407 * @param owner target class(被调用类)
391408 * @param name target method(被调用方法)
392409 * @param desc 方法参数和返回值描述
393- * @param itf
394410 */
395411 @ Override
396412 public void visitMethodInsn (int opcode , String owner , String name , String desc , boolean itf ) {
0 commit comments