当前位置: 首页 > news >正文

网站建设文化服务公司做app模板网站

网站建设文化服务公司,做app模板网站,黄岛网站开发,6生肖竞猜网站建设FieldVisitor使用abstract 修饰#xff0c;用于创建变量#xff0c;在使用时调用 ClassWriter.visitField即可创建FieldVisitor 方法介绍 visitField(Opcodes.ACC_PUBLIC, “str”, “Ljava/lang/String;”, null, “Hello World”) 第一个参数是修饰类型#xff0c;第二…FieldVisitor使用abstract 修饰用于创建变量在使用时调用 ClassWriter.visitField即可创建FieldVisitor 方法介绍 visitField(Opcodes.ACC_PUBLIC, “str”, “Ljava/lang/String;”, null, “Hello World”) 第一个参数是修饰类型第二个参数是变量名第三个是变量类型第四个签名第五个是变量的值设置值好像没什么用所以我在下面代码的初始化中重新初始化了str的值 示例代码如下 package com.example.asmapplicationimport org.junit.Test import org.objectweb.asm.ClassWriter import org.objectweb.asm.Opcodes import java.io.File import java.io.FileOutputStream import java.net.URLClassLoaderclass DemoASMGenerateField {Testfun generate() {val filePath E:\\Develop\\ASMApplication2\\app\\src\\test\\java\\com\\example\\asmapplication\\generate\\GenerateField.classval file File(filePath)if (!file.parentFile.exists()) {file.parentFile.mkdir()}//创建ClassWriterval cw ClassWriter(ClassWriter.COMPUTE_FRAMES)//设定包名和类名cw.visit(Opcodes.V1_8,Opcodes.ACC_PUBLIC,com/example/asmapplication/generate/GenerateField,null,java/lang/Object,null)//创建全局变量val vfStr cw.visitField(Opcodes.ACC_PUBLIC, str, Ljava/lang/String;, null, Hello World)vfStr.visitEnd()//每个classFile都有一个init的初始化方法val mvInit cw.visitMethod(Opcodes.ACC_PUBLIC, init, ()V, null, null)mvInit.visitCode()mvInit.visitVarInsn(Opcodes.ALOAD, 0)mvInit.visitMethodInsn(Opcodes.INVOKESPECIAL, java/lang/Object, init, ()V, false)mvInit.visitVarInsn(Opcodes.ALOAD, 0)//初始化定义的变量的值mvInit.visitLdcInsn(Hello World)mvInit.visitFieldInsn(Opcodes.PUTFIELD, com/example/asmapplication/generate/GenerateField, str, Ljava/lang/String;)mvInit.visitInsn(Opcodes.RETURN)mvInit.visitMaxs(0, 0)mvInit.visitEnd()//创建一个test()方法val mvTest cw.visitMethod(Opcodes.ACC_PUBLIC, test, ()V, null, null)mvTest.visitCode()//打印Hello WordmvTest.visitVarInsn(Opcodes.ALOAD, 0);mvTest.visitFieldInsn(Opcodes.GETFIELD,com/example/asmapplication/generate/GenerateField,str,Ljava/lang/String;);mvTest.visitFieldInsn(Opcodes.GETSTATIC, java/lang/System, out, Ljava/io/PrintStream;)mvTest.visitInsn(Opcodes.SWAP)mvTest.visitMethodInsn(Opcodes.INVOKEVIRTUAL,java/io/PrintStream,println,(Ljava/lang/Object;)V,false)mvTest.visitInsn(Opcodes.RETURN)mvTest.visitMaxs(0, 0)mvTest.visitEnd()//类的访问结束cw.visitEnd()//输出为class文件val outputStream FileOutputStream(file)outputStream.write(cw.toByteArray())outputStream.flush()outputStream.close()val classLoader URLClassLoader(arrayOf(File(E:\\Develop\\ASMApplication2\\app\\src\\test\\java).toURI().toURL()))val clazz classLoader.loadClass(com.example.asmapplication.generate.GenerateField)val obj clazz.newInstance()clazz.getMethod(test).invoke(obj)} }最终生成代码 // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //package com.example.asmapplication.generate;public class GenerateField {public String str Hello World;public GenerateField() {}public void test() {System.out.println(this.str);} }技巧分享 假如我们想在MainActivity中动态生成两个变量 public int age 100; public String str Hello World; 可以这样做 1、先在一个Test类中创建两个变量代码 如下 public class Test {public int age 100;public String str Hello World;private int sum(int i, int j) {return ij;} }编译后通过ASM Bytecode Outline Rebooted等工具查看Test.class的字节码信息 public class com/baidu/main/test/Test {// access flags 0x1public I age// access flags 0x1public Ljava/lang/String; str// access flags 0x1public init()VALOAD 0INVOKESPECIAL java/lang/Object.init ()VALOAD 0BIPUSH 100PUTFIELD com/baidu/main/test/Test.age : IALOAD 0LDC Hello WorldPUTFIELD com/baidu/main/test/Test.str : Ljava/lang/String;RETURNMAXSTACK 2MAXLOCALS 1// access flags 0x2private sum(II)IILOAD 1ILOAD 2IADDIRETURNMAXSTACK 2MAXLOCALS 3 }对应的ASM信息如下 public class TestDump implements Opcodes {public static byte[] dump() throws Exception {ClassWriter classWriter new ClassWriter(0);FieldVisitor fieldVisitor;MethodVisitor methodVisitor;AnnotationVisitor annotationVisitor0;classWriter.visit(V1_8, ACC_PUBLIC | ACC_SUPER, com/baidu/main/test/Test, null, java/lang/Object, null);{fieldVisitor classWriter.visitField(ACC_PUBLIC, age, I, null, null);fieldVisitor.visitEnd();}{fieldVisitor classWriter.visitField(ACC_PUBLIC, str, Ljava/lang/String;, null, null);fieldVisitor.visitEnd();}{methodVisitor classWriter.visitMethod(ACC_PUBLIC, init, ()V, null, null);methodVisitor.visitCode();methodVisitor.visitVarInsn(ALOAD, 0);methodVisitor.visitMethodInsn(INVOKESPECIAL, java/lang/Object, init, ()V, false);methodVisitor.visitVarInsn(ALOAD, 0);methodVisitor.visitIntInsn(BIPUSH, 100);methodVisitor.visitFieldInsn(PUTFIELD, com/baidu/main/test/Test, age, I);methodVisitor.visitVarInsn(ALOAD, 0);methodVisitor.visitLdcInsn(Hello World);methodVisitor.visitFieldInsn(PUTFIELD, com/baidu/main/test/Test, str, Ljava/lang/String;);methodVisitor.visitInsn(RETURN);methodVisitor.visitMaxs(2, 1);methodVisitor.visitEnd();}{methodVisitor classWriter.visitMethod(ACC_PRIVATE, sum, (II)I, null, null);methodVisitor.visitCode();methodVisitor.visitVarInsn(ILOAD, 1);methodVisitor.visitVarInsn(ILOAD, 2);methodVisitor.visitInsn(IADD);methodVisitor.visitInsn(IRETURN);methodVisitor.visitMaxs(2, 3);methodVisitor.visitEnd();}classWriter.visitEnd();return classWriter.toByteArray();} } 从ASM生成的代码中可以看到age和str两个变量后并没有立刻赋值赋值了不一定生效而是在init方法里面进行了赋值。 2.对MainActivity进行插装 package com.baidu.plugin.printimport org.objectweb.asm.AnnotationVisitor import org.objectweb.asm.Attribute import org.objectweb.asm.ClassVisitor import org.objectweb.asm.FieldVisitor import org.objectweb.asm.Label import org.objectweb.asm.MethodVisitor import org.objectweb.asm.Opcodes import org.objectweb.asm.commons.AdviceAdapterclass PrintClassVisitor(nextVisitor: ClassVisitor, private val className: String): ClassVisitor(Opcodes.ASM5, nextVisitor) {override fun visit(version: Int,access: Int,name: String?,signature: String?,superName: String?,interfaces: Arrayout String?) {println(visit access $access className $className name $name signature $signature)val numFiledVisitor cv.visitField(Opcodes.ACC_PRIVATE, age, I, null, 25)numFiledVisitor.visitEnd()val strFiledVisitor cv.visitField(Opcodes.ACC_PUBLIC, str, Ljava/lang/String;, null, Hello World)strFiledVisitor.visitEnd()super.visit(version, access, name, signature, superName, interfaces)}override fun visitEnd() {super.visitEnd()}override fun visitField(access: Int,name: String?,descriptor: String?,signature: String?,value: Any?): FieldVisitor {println(visitField access $access className $className name $name descriptor $descriptor)val filedVisitor super.visitField(access, name, descriptor, signature, value)return MyPrintFieldVisitor(Opcodes.ASM5,filedVisitor)}override fun visitMethod(access: Int,name: String?,descriptor: String?,signature: String?,exceptions: Arrayout String?): MethodVisitor {val methodVisitor super.visitMethod(access, name, descriptor, signature, exceptions)return MyPrintMethodVisitor(Opcodes.ASM5,methodVisitor,access,className,name,descriptor)}}class MyPrintFieldVisitor(api: Int, filedVisitor: FieldVisitor) : FieldVisitor(api, filedVisitor) {override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor {println(visitAnnotation descriptor $descriptor visible $visible)return super.visitAnnotation(descriptor, visible)}}class MyPrintMethodVisitor(api: Int,methodVisitor: MethodVisitor?,private val access: Int,private val className: String,private val name: String?,private val descriptor: String? ) : AdviceAdapter(api, methodVisitor, access, name, descriptor) {override fun onMethodEnter() {println(onMethodEnter access $access className $className name $name descriptor $descriptor)if (name.equals(init) descriptor.equals(()V)) {//每个classFile都有一个init的初始化方法(固定写法)mv.visitVarInsn(Opcodes.ALOAD, 0)mv.visitMethodInsn(Opcodes.INVOKESPECIAL, java/lang/Object, init, ()V, false)mv.visitVarInsn(Opcodes.ALOAD, 0)//初始化定义的变量的值mv.visitIntInsn(BIPUSH, 100)mv.visitFieldInsn(PUTFIELD, com/baidu/main/MainActivity, age, I )//String的初始化会在构造方法中mv.visitVarInsn(Opcodes.ALOAD, 0)mv.visitLdcInsn(Hello World)mv.visitFieldInsn(PUTFIELD, com/baidu/main/MainActivity, str, Ljava/lang/String )mv.visitInsn(RETURN)}if (name.equals(sum999)) {//System.out.println(999999);mv.visitFieldInsn(Opcodes.GETSTATIC, java/lang/System, out, Ljava/io/PrintStream;);mv.visitLdcInsn(999999-begin)mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, java/io/PrintStream, println, (Ljava/lang/String;)V, false);}super.onMethodEnter()}override fun onMethodExit(opcode: Int) {println(onMethodExit access $access className $className name $name descriptor $descriptor)if (name.equals(sum999)) {//System.out.println(999999);mv.visitFieldInsn(Opcodes.GETSTATIC, java/lang/System, out, Ljava/io/PrintStream;);mv.visitLdcInsn(999999-end)mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, java/io/PrintStream, println, (Ljava/lang/String;)V, false);}super.onMethodExit(opcode)}override fun visitFieldInsn(opcode: Int, owner: String?, name: String?, descriptor: String?) {println(visitFieldInsn opcode $opcode owner $owner name $name descriptor $descriptor)super.visitFieldInsn(opcode, owner, name, descriptor)}override fun visitLocalVariable(name: String?,descriptor: String?,signature: String?,start: Label?,end: Label?,index: Int) {println(visitLocalVariable name $name descriptor $descriptor start $start end $end index $index)super.visitLocalVariable(name, descriptor, signature, start, end, index)}override fun visitAttribute(attribute: Attribute?) {println(visitAttribute attribute $attribute)super.visitAttribute(attribute)}override fun visitLineNumber(line: Int, start: Label?) {println(visitLineNumber line $line start $start)super.visitLineNumber(line, start)}override fun visitFrame(type: Int,numLocal: Int,local: Arrayout Any?,numStack: Int,stack: Arrayout Any?) {println(visitFrame type $type numLocal $numLocal local $local numStack $numStack stack $stack)super.visitFrame(type, numLocal, local, numStack, stack)}override fun visitLabel(label: Label?) {println(visitLabel label $label)super.visitLabel(label)}override fun visitCode() {println(visitCode)super.visitCode()}override fun visitMaxs(maxStack: Int, maxLocals: Int) {println(visitMaxs maxStack $maxStack maxLocals $maxLocals)super.visitMaxs(maxStack, maxLocals)}override fun visitEnd() {println(visitEnd)super.visitEnd()} }关键代码如下 创建变量 override fun visit(version: Int,access: Int,name: String?,signature: String?,superName: String?,interfaces: Arrayout String?) {println(visit access $access className $className name $name signature $signature)val numFiledVisitor cv.visitField(Opcodes.ACC_PRIVATE, age, I, null, 25)numFiledVisitor.visitEnd()val strFiledVisitor cv.visitField(Opcodes.ACC_PUBLIC, str, Ljava/lang/String;, null, Hello World)strFiledVisitor.visitEnd()super.visit(version, access, name, signature, superName, interfaces)} 注意 cv.visitField(Opcodes.ACC_PUBLIC, str, Ljava/lang/String;, null, Hello World)也给变量赋值了但是没有生效。 在init方法中给变量赋值 override fun onMethodEnter() {println(onMethodEnter access $access className $className name $name descriptor $descriptor)if (name.equals(init) descriptor.equals(()V)) {//每个classFile都有一个init的初始化方法(固定写法)mv.visitVarInsn(Opcodes.ALOAD, 0)mv.visitMethodInsn(Opcodes.INVOKESPECIAL, java/lang/Object, init, ()V, false)mv.visitVarInsn(Opcodes.ALOAD, 0)//初始化定义的变量的值mv.visitIntInsn(BIPUSH, 100)mv.visitFieldInsn(PUTFIELD, com/baidu/main/MainActivity, age, I )//String的初始化会在构造方法中mv.visitVarInsn(Opcodes.ALOAD, 0)mv.visitLdcInsn(Hello World)mv.visitFieldInsn(PUTFIELD, com/baidu/main/MainActivity, str, Ljava/lang/String )mv.visitInsn(RETURN)}super.onMethodEnter()} 如果不会写可以参考Test.class的ASM生成代码直接照抄就行。 插桩后的代码如下 package com.baidu.main;import android.os.Bundle; import androidx.activity.ComponentActivity; import kotlin.Metadata;/* compiled from: MainActivity.kt */ Metadata(d1 {\u0000\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0018\u0002\n\u0000\n\u0002\u0010\b\n\u0002\b\u0005\n\u0002\u0010\t\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u0012\u0010\u0003\u001a\u00020\u00042\b\u0010\u0005\u001a\u0004\u0018\u00010\u0006H\u0014J\u0018\u0010\u0007\u001a\u00020\b2\u0006\u0010\t\u001a\u00020\b2\u0006\u0010\n\u001a\u00020\bH\u0002J\u0018\u0010\u000b\u001a\u00020\b2\u0006\u0010\t\u001a\u00020\b2\u0006\u0010\n\u001a\u00020\bH\u0002J\u0010\u0010\f\u001a\u00020\u00042\u0006\u0010\r\u001a\u00020\u000eH\u0002¨\u0006\u000f}, d2 {Lcom/baidu/main/MainActivity;, Landroidx/activity/ComponentActivity;, ()V, onCreate, , savedInstanceState, Landroid/os/Bundle;, sum, , i, j, sum999, test, time, , app_debug}, k 1, mv {1, 8, 0}, xi 48) /* loaded from: classes4.dex */ public final class MainActivity extends ComponentActivity {private int age 100;public String str;public MainActivity() {this.str Hello World;}/* access modifiers changed from: protected */Override // androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activitypublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);test(100);sum(1, 2);}private final void test(long time) {Thread.sleep(time);}private final int sum(int i, int j) {return i j;}private final int sum999(int i, int j) {System.out.println(999999-begin);int i2 i j;System.out.println(999999-end);return i2;} }
http://www.zqtcl.cn/news/673501/

相关文章:

  • 网站做标题有用吗网站优化多少钱
  • 婚庆设备租赁网站源码如何进行网站的建设和维护
  • 青岛做网站公wordpress文章付费阅读
  • 小灯具网站建设方案360优化大师
  • 开发公司与物业公司前期合同网站优化的推广
  • 汉堡云虚拟主机aso安卓优化公司
  • 医院 网站建设 新闻营销外包
  • 优秀网站网址郑州无痛人流哪家医院好
  • 备案网站能打开吗大良营销网站建设流程
  • 哪些网站可以做淘宝店招石油网站编辑怎么做
  • 网站出现建设中集团网站建设特点
  • asp网站开发 pdf企业展厅设计公司盛世笔特
  • 怎么创建网站 免费的免费开源的网站系统
  • 中山精品网站建设资讯网页设计师就业趋势
  • 网站建设哪家好 万维科技wordpress广告公司模板
  • 如何选择建网站公司网站页面html静态化
  • 建设银行网站入口网页设计培训 周末双休
  • 做企业网站建设的公司为什么企业网站不是开源系统
  • 网站客户端怎么做的做汽车脚垫版的网站
  • 做数学题挣钱的网站广西建筑特种作业证件查询官网
  • 汉字叔叔花了多少钱做网站免费原创视频素材
  • 网站开发提现功能互联网推广工作好做吗
  • 做阿里渠道的销售要有哪些网站网站评论怎么做的
  • 建设中网站如何上传图片深圳营销型网站建设设计公司
  • 建设电商网站需要多少钱家具网页设计素材
  • 物流网站html5模板网站整站开发
  • 网站随机代码网站开发技术试验教程
  • 做翻译 网站吗仿京东电商的网站开发报价
  • 霞山网站建设公司网站开发怎样手机号验证
  • 大型门户网站建设苏州优化网站建设