- 浏览: 153844 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
lanhaitun1991:
亲,其实你这里介绍的方法有一个最大的问题:如果放入队列之后,但 ...
分布式事务 -
lp385267935:
不错 很好用~3Q
jsonlib json-->object,忽略object中没有的属性 -
xiebo1983:
http://www.sqkoo.com/show/detai ...
mysql latin1乱码 -
envy2002:
当然可以了,tomcat中源码你可以看看,只要“欺骗”过去to ...
tomcat中的长连接 -
newSaa:
问一下,可以在 tomcat 建立tcp 长连接吗?
tomcat中的长连接
现在开始研究Junit,试图通过Junit来改善自己的编程,看了一两天,觉得自己懂了,开始上马。
同事写了一个byte 数组转 json的组件,我的目标是通过撰写 Juit的测试用例来测试这些组件是否OK。
一上来就遇到了一个不小的麻烦,我的测试主要是来比较两个“对象”是否相等,给定了一个byte数组,组件返回给我了一个
json对象,我也自己模拟了一个json对象,我需要用JSONObject.equals来判断两个对象是否相等,很遗憾,同时用的是
org.json,但不是json-lib中的 net.sf.json中的JSONObject,json-lib中的JSONObject是有equals方法的,可以递归地
比较到最底层。我用的是jar包,我修改不了org.json.JSONObject的源代码,我后来想用 toString来比较,但是org.json.
JSONObject反编译出来的源码是:
public JSONObject() { map = new HashMap(); }
private Map map;
它里面的数据结构是hashmap, 所以就可能和我要求的不一样,
例如 加入我要求 {"aa":"11","bb":"22"},
它 toString 给我的结果可能是 {"bb":"22","aa":"11"}
所以,这个toString方法是不能间接证明它们 not equlas的。现在如果想想,如果能让
public JSONObject()
{
map = new LinkedHashMap();
}
那该多好啊,转化组件是有配置的,配置是有顺序的,所以我自己知道顺序,那么这样toString就可以做到比较两者之间
是否相等。
该 如何让这个jar里面的类的hashmap-->linkedhashmap呢,我在网上找到了ASM。
废话不多说了,就是看看如何做吧。我们那这个问题当模型的话,那么我们只需要修改类的构造方法就是了。
但是,我需要提一点的是,网上很多教程没有说,类的值域好像是无法修改的,只能先删除,后添加一个新的,比如如果类
里面有个 private String name-->你希望name是int型,那么先删掉name,后价格 string 型的name.至于有没有修改
的方法,我也不确定。我以网上这个例子来当范本吧。
http://victorzhzh.iteye.com/blog/882699
import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; public class Person { public int name ; public Map address ; }
我们的目标是
import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; public class Person { public String name ; public Map address ; public Person() { address=new LinkedHashMap(); } }
怎么做呢?
import java.util.LinkedHashMap; import java.util.Map; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.util.CheckClassAdapter; public class Transform extends CheckClassAdapter { public Transform(ClassVisitor cv) { super(cv); } @Override public void visitEnd() { //这个方法只会执行一次,在这里我们可以构造我们需要的东西。 cv.visitField(Opcodes.ACC_PUBLIC, "name", Type.getDescriptor(int.class), null, null); //新增加一个方法 MethodVisitor mv= cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Objec", "<init>", "()V"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.ICONST_2); mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "name", "I"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.NEW, "java/util/LinkedHashMap"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/LinkedHashMap", "<init>", "()V"); mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "address", " java/util/Map"); // mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitInsn(Opcodes.RETURN); // mv.visitMaxs(0, 0); mv.visitEnd(); } public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { // cv.visitField(Opcodes.ACC_PUBLIC, "age", Type.getDescriptor(int.class), // null, null); if("name".equals(name)) //值域变量名称为name的时候 return null; //为null表示去掉 return super.visitField(access, name, desc, signature, value); //不为null,保留 } @Override public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions) { if ( "<init>".equals(name)) { //init为初始化方法 return null; //为空表示删除 } //其他的方法保留 return super.visitMethod(access, name, desc, signature, exceptions); } }
public class GeneratorClassLoader extends ClassLoader { @SuppressWarnings("rawtypes") public Class defineClassFromClassFile(String className, byte[] classFile) throws ClassFormatError { return defineClass(className, classFile, 0, classFile.length); } }
import java.io.FileOutputStream; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.util.CheckClassAdapter; public class TransformTest { public void addAge() throws Exception {
// 输入需要改造的类,Person ClassReader classReader = new ClassReader( "Person");
// 写改造好的类,怎么改,谁改,classAdapter ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); CheckClassAdapter classAdapter = new Transform(classWriter); classReader.accept(classAdapter, ClassReader.SKIP_DEBUG);
//生成的,改造好的类的二级制文件。 byte[] classFile = classWriter.toByteArray();
//直接把这些二进制文件,通过类加载器,加载到虚拟机中去,为了检验,我们需要存到文件中去 // GeneratorClassLoader classLoader = new GeneratorClassLoader(); // Class clazz = classLoader.defineClassFromClassFile( // "Person", classFile); // Object obj = clazz.newInstance(); //System.out.println(clazz.getDeclaredField("name").get(obj));//----(1) //System.out.println(clazz.getDeclaredField("age").get(obj));//----(2) //存到e盘log目录下的Example.class文件中,我们可以用反编译工具来查看,我们修改的
是否正确。 FileOutputStream fos = new FileOutputStream("e:\\logs\\Example.class"); fos.write(classFile); fos.close(); } public static void main(String[] args) throws Exception { new TransformTest().addAge(); } }
我们重点考察的是Transform的visitEnd方法,这个方法完成了我们队类的改写。
public FieldVisitor visitField(int access, String name, String desc,
String signature, Object value)
和 public MethodVisitor visitMethod(
int access,
String name,
String desc,
String signature,
String[] exceptions)
这两个方法,分别表示构建值域和函数,如果为空,就表示没有这个值域或者函数了。这个应该会遍历那个最原始的类。
比方说,我们最初的Person类里面有2个值域,5个方法,那么就会执行两次visitField,5次visitMethod方法。
所以我们遇到想去掉的方法,或者值域就Ok了。
visitEnd这个方法只会执行一次,所以,我们在这里加上我们想要的东西。
cv.visitField(Opcodes.ACC_PUBLIC, "name", Type.getDescriptor(int.class), null, null); //name改变为int 型 //新增加一个方法,构造方法 MethodVisitor mv= cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); //为什么加这段,以后再说 mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Objec", "<init>", "()V");
//让int型的name=2 mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitInsn(Opcodes.ICONST_2); mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "name", "I");
//让 address=new LinkedHashMap(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitTypeInsn(Opcodes.NEW, "java/util/LinkedHashMap"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/LinkedHashMap", "<init>", "()V"); mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "address", " java/util/Map"); // mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitInsn(Opcodes.RETURN); // mv.visitMaxs(0, 0); mv.visitEnd();
这样,我们就完成了改造的任务,为什么这样改,怎样改。
首先我们需要分析一下这个过程。我们需要工具,一个是asm的eclipse插件,这个插件负责把类的二进制结构显示出来,
名字叫
bytecode-outline
在这里 2.4.0版本的 http://forge.ow2.org/project/download.php?group_id=23&file_id=17193
还有一个windows xp上的反编译工具。
我们先用eclipse写出,我们需要的类,然后用 bytecode-outline观察,然后再用asm api构造出这个想要的类,然后保存到文件中,然后用 jd-gui反编译,看看是不是我们想要的类。
例如,我们需要这样,这是我们的目标代码
public class Person { public int name ; public String address ; // private Map map; // public Person() { name=7; address="福田"; } }
bytecode-outline看到的是:
// class version 50.0 (50) // access flags 0x21 public class Person { // compiled from: Person.java // access flags 0x1 public I name // access flags 0x1 public Ljava/lang/String; address // access flags 0x1 public <init>()V L0 LINENUMBER 10 L0 ALOAD 0 INVOKESPECIAL java/lang/Object.<init>()V L1 LINENUMBER 12 L1 ALOAD 0 BIPUSH 7 PUTFIELD Person.name : I L2 LINENUMBER 13 L2 ALOAD 0 LDC "\u798f\u7530" PUTFIELD Person.address : Ljava/lang/String; L3 LINENUMBER 14 L3 RETURN L4 LOCALVARIABLE this LPerson; L0 L4 0 MAXSTACK = 2 MAXLOCALS = 1 }
那么我们的构建代码将是这样:
public void visitEnd() { cv.visitField(Opcodes.ACC_PUBLIC, "name", Type.getDescriptor(int.class), null, null); //新增加一个方法 MethodVisitor mv= cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Objec", "<init>", "()V"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.BIPUSH, 7); //mv.visitInsn(Opcodes.ICONST_2); mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "name", "I"); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn("\u798f\u7530"); mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "address", "Ljava/lang/String"); // mv.visitVarInsn(Opcodes.ALOAD, 0); // mv.visitTypeInsn(Opcodes.NEW, "java/util/LinkedHashMap"); // mv.visitInsn(Opcodes.DUP); // mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/LinkedHashMap", "<init>", "()V"); // mv.visitFieldInsn(Opcodes.PUTFIELD, "Person", "address", " java/util/Map"); // mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitInsn(Opcodes.RETURN); // mv.visitMaxs(0, 0); mv.visitEnd(); }
蓝色对蓝色,红色对红色。呵呵,然后我们用 jd-gui反编译一下example.class会发现
public class Person { public String address; public int name = 7; public Person() { super(); this.address = "福田"; } }
这样,我们就找到了一种比较好的途径来构建我们需要的类,因为java类的字节码还是比较难认的,这种方式就能照葫芦画瓢,
以比较小的代价完成我们的目标,如果你要想深入,那么就需要精通虚拟机的类的结构了。
掌握了这个方法,我们就可以在没有源代码的情况下,通过反编译工具来构建我们需要的类了,快试试吧。其实我也不怎么懂这个ASM框架的,就是调试调试,基本了解了其流程,利用“工具”吧,逆向工程来学习。
- jd-gui-0.3.3.windows.rar (690.8 KB)
- 下载次数: 10
发表评论
-
java NIO
2013-05-02 16:51 791... -
Thread.interrupt
2013-04-10 21:25 1014Thread.interrupt(),就是置状态。 ... -
分布式事务2
2013-02-19 14:16 10221.jar包,应该用带有二步提交事务的驱动,mysq ... -
分布式事务
2013-02-17 17:40 2404... -
spring SimpleFormController流程
2013-02-08 11:43 1781最近在学习spring mvc. 网上了收集了一下Simp ... -
谷歌面试题一枚
2012-10-16 09:46 1292机械开发代码久了,看了看一些面试题,可以活跃大脑,最近网上看了 ... -
java concurrent学习记录
2012-10-10 09:51 937今天决定学习一下java.concurrent包,以这个 ... -
jsonlib json-->object,忽略object中没有的属性
2012-09-21 09:42 10010Java code skel ... -
java并发编程pdf纠错
2012-08-14 09:21 0java并发编程实践里面讲究CAS算法,其中这个 算法comp ... -
5分钟内搞定 Tomcat 的 SSL 配置
2012-07-02 11:52 9035分钟内搞定 Tomcat 的 SSL 配置(转) ... -
java nio测试
2012-06-29 12:00 994import java.io.IOException; ... -
屌丝comet
2012-06-26 09:29 871很显然tomcat能和浏览器之间实现长连接还是不错的,看了ib ... -
eclipse 远程调试 web程序
2012-05-31 16:37 992需要远程调试web程序,没办法啊。 1. 需要把%TO ... -
tomcat停止
2012-04-18 12:50 0#!/bin/sh #kill tomcat pid ... -
json转java对象
2012-04-10 20:54 1056String json = "{\&qu ... -
bonecp源码陌生类选读
2012-03-01 17:16 837今天在学习bonecp源码,看到了好多从来没有用过的类,现在记 ... -
TOMCAT源码分析(消息处理)(转)
2012-02-28 14:06 787TOMCAT源码分析(消息处理) http://bl ... -
tomcat流程启动图
2012-02-28 10:56 970tomcat6从启动到监听8080端口来处理请求的过程,如图: ... -
tomcat源码的几个问题
2012-02-24 11:31 9621. tomcat如何区分静态页面.html .jpg 和.j ... -
java 中的classloader
2012-02-23 11:35 959java中的.class文件必须有classl ...
相关推荐
在本文中,我们将深入探讨"asm330lhh-STdC嵌入式程序示例",这是一个基于ASM330LHH传感器的嵌入式系统应用实例。ASM330LHH是一款高性能的三轴加速度计和三轴陀螺仪,常用于运动检测、导航系统以及物联网(IoT)设备。...
总的来说,"简单ASM示例"是一个很好的起点,通过实践这些例子,你可以逐步掌握ASM的基本语法和编程思想。同时,建议配合相关的教材或在线资源,深入学习汇编语言与计算机体系结构的关系,以便更好地理解和利用这种...
它可以是机械设备、汽车部件或任何其他工程组件,其中每个零件都有独立的特征和属性,但它们在Asm中协同工作,形成一个整体。 Pro/Toolkit为开发者提供了访问Asm数据的接口,包括但不限于以下功能: 1. 创建Asm:...
内容包含ASM4.0中文手册,以及四种ASM常见的字节码操作应用范例,包含最新版本的ASM9.2的jar包,包含asm-9.2.jar,asm-commons-9.2.jar,asm-util-9.2.jar。 学习文章地址 ...
然而,需要注意的是,`scanf`函数中的`&y`表示取`y`的地址,这是因为`scanf`函数需要一个变量的地址来存储输入的值。 通过这个简单的示例,我们可以看到C语言与汇编语言的结合如何使得程序能够更精细地控制底层硬件...
hkWin7asm 采用win32汇编写的模仿windows7 win+上下左右控制顶层窗口大小效果,另外加了个win+回车窗口自适应居中效果 压缩包内含有编译完成的本件及源代码 编译环境使用masm32,需要先下载masm32才可以进行编译操作
汇编语言则更接近底层硬件,可以直接控制单片机的每一个硬件资源,虽然编写起来较为繁琐,但在需要高效运行或者精确控制硬件时不可或缺。压缩包中的C语言示例可能包括了基本的I/O操作、中断服务例程、定时器设置等,...
他的教学实践为那些从事教育工作、特别是计算机教育的教师们提供了一个极佳的范例。通过《汇编语言》这本书,我们可以窥见王爽教授如何将知识与兴趣相结合,将技术与教学相融合,以及如何将复杂的理论化为简单的实践...
总之,这个范例是一个很好的学习资源,它演示了如何在LabVIEW和单片机之间建立可靠的串口通信。通过深入理解并实践这个例子,开发者可以更好地掌握两者之间的数据交互,为未来的嵌入式系统设计打下坚实基础。
汇编语言范例,读者可以参考编程,喜爱汇编的朋友可以下来看看
1) 添加 取值时可提供一个逻辑参考参数,保存取值状态结果。2) 添加 支持自定义数据值, 以及使用范例(用法比较另类)。0.4版(2018.11.22)。1) 修复 由于WIN10下,文本比较SSE4.2会产生奔溃,屏蔽掉文本比较SSE4.2。...
“FPPA 80Cxx”是这款MCU的具体型号,FPPA可能是制造商的缩写或者产品系列名,而80Cxx可能是该系列中的一个具体产品代号,通常这类编号会包含关于芯片性能和功能的一些信息。“范例程序”则意味着这是用于演示和学习...
EM78P153 C语言唤醒范例 #include "EM78x153xx.h" #define ENWDT 1 #define DSWDT 0 #define WATCHDOG ENWDT void Pin_Wake_up(void) { _asm { mov a,@0x0e contw } WDTCR=0x3f; //disable wdt _asm { ...
标题中的“PIC10F200 Example program”和描述中的“pic10f200范例”指的是基于Microchip公司的微控制器PIC10F200的一个示例程序。PIC10F200是一款低功耗、高性能的8位微控制器,常用于小型嵌入式系统设计。这个示例...
标题和描述中提到的"一个温控的例子带汇编"是一个关于温度控制系统的实例,其中涉及到使用汇编语言编程和可能的硬件设计。这个系统可能是基于微控制器的,通过读取温度传感器的数据来调节环境温度。汇编语言是低级...
《C51及汇编语言范例程序》是学习微控制器编程的重要参考资料,它涵盖了多个实际应用项目,如数字多用仪表、红外遥控系统、简易电子琴和带农历的电子万年历。这些项目不仅展示了C51语言和汇编语言的结合使用,还提供...
1. "范例.asm":这是一个示例汇编源代码文件,初学者可以通过阅读和分析这个文件来了解80X86汇编的基本语法和结构。它可能包含了基本的指令,如数据定义、过程调用、控制流程指令等。 2. "ASM_Tool.exe":这是80X86...
根据提供的文件信息,本文将详细解析“VB与S7-200通讯例子——读取温度值的程序范例”中的关键...同时,对于初学者来说,这也是一个很好的学习案例,能够帮助他们理解如何通过编程实现工业自动化系统的数据采集和处理。
### Linux 2.6.26.6 内核下的 LED 驱动程序分析 ...通过上述分析,我们可以看出,对于初学者来说,这个驱动程序是一个很好的学习范例,不仅可以了解到 Linux 内核的基本结构,还可以掌握字符设备驱动的编写方法。
ASM最佳实践范例 交通转移 交通管理 流量解码 安全的 观察 网格化 http_hybrid_demo http_workload_blue_green_demo vm_tracing_demo