标签: java-bytecode-asm

方法调用指令(invokevirtual/invokestatic)由一些意外的指令代替

我一直在调查这个错误整整三天,但仍然没有进展.我希望我能从这里得到一些提示.

我想要做的是使用ASM库将MethodNode内联到MethodHandle调用站点(#5,#17和#30).为简化起见,#5处的MethodHandle引用静态方法static Functions.isFooString(String)boolen.

在呼叫站点,内联之前的指令就像

    //Before
  stack=3, locals=3, args_size=3
     0: aload_0
     1: getfield      #15                 // Field guard:Ljava/lang/invoke/MethodHandle;
     4: aload_1
     5: invokevirtual #29                 // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;)Z
     8: ifeq          24
    11: aload_0
    12: getfield      #17                 // Field trueTarget:Ljava/lang/invoke/MethodHandle;
    15: aload_1
    16: aload_2
    17: invokevirtual #31                 // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    20: checkcast     #33                 // class java/lang/String
    23: areturn
    24: aload_0
    25: getfield      #19                 // Field falseTarget:Ljava/lang/invoke/MethodHandle;
    28: aload_1
    29: aload_2
    30: invokevirtual #31                 // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    33: checkcast     #33                 // class java/lang/String
    36: …
Run Code Online (Sandbox Code Playgroud)

java jvm bytecode java-bytecode-asm

56
推荐指数
0
解决办法
1081
查看次数

错误:java.lang.NoSuchMethodError:org.objectweb.asm.ClassWriter.<init>(I)V

我正在开发一个小型Spring应用程序.我必须将学生信息的详细信息存储在数据库中.我开发了一个SimpleFormController.我使用过NetBeans + Hibernate映射+ Spring.部署项目时,会发生以下错误.

我的spring-config-db-applicationContext.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Hibernate session factory -->
  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <constructor-arg index="0">
        <value>${driverClassName}</value>
    </constructor-arg>
    <constructor-arg index="1">
        <value>${url}</value>
    </constructor-arg>
    <constructor-arg index="2">
        <value>${username}</value>
    </constructor-arg>
    <constructor-arg index="3">
        <value>${password}</value>
    </constructor-arg>
  </bean>


  <bean id="sessionFactory"  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
        <ref bean="dataSource"/>
    </property>
    <!-- <property name="configLocation">
        <value>WEB-INF/classes/hibernate.cfg.xml</value>
    </property> -->
    <property  name="mappingResources" >
        <list>
            <value>hibernate.cfg.xml</value>
        </list>
    </property>

  <!--  <property  name="configurationClass">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
    </property> -->

    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
  <!--<prop key="hibernate.hbm2ddl.auto">create</prop>-->
        </props>
    </property>
  </bean>
  <bean …
Run Code Online (Sandbox Code Playgroud)

java orm spring hibernate java-bytecode-asm

29
推荐指数
4
解决办法
10万
查看次数

动态Java字节码操作框架比较

有一些框架用于动态字节码生成,操作和编织(BCEL,CGLIB,javassist,ASM,MPS).我想了解它们,但由于我没有太多时间知道所有这些细节,我希望看到一种比较图表,说明一种与其他的优缺点,以及对为什么.

在SO中,我发现了许多类似问题的问题,答案通常说"你可以使用cglib或ASM",或者"javassist比cglib更好",或者"BCEL已经老了,正在死"或"ASM是最好的,因为它给出X和Y".这些答案很有用,但并没有完全回答我想要的范围内的问题,更深入地比较它们并给出每个问题的优点和缺点.

bytecode-manipulation cglib javassist java-bytecode-asm jvm-bytecode

29
推荐指数
3
解决办法
5917
查看次数

运行时"最终"是最终的吗?

我一直在玩ASM,我相信我成功地将final修饰符添加到了类的实例字段中; 然后我继续实例化所述类并在其上调用一个setter,它成功地改变了now-final字段的值.我的字节码更改有问题,还是仅由Java编译器最终强制执行?

更新:(7月31日)这里有一些代码供您使用.主要部分是

  1. 一个简单的POJO与private int xprivate final int y,
  2. MakeFieldsFinalClassAdapter,它使得它访问的每个字段都是final,除非它已经是,
  3. 和AddSetYMethodVisitor,它导致POJO的setX()方法也将y设置为它设置为x的相同值.

换句话说,我们从一个具有一个final(x)和一个非final(y)字段的类开始.我们让x最终.除了设置x之外,我们使setX()设置为y.我们跑.x和y都设置为没有错误.该代码在GitHub上.你可以用以下方法克隆它:

git clone git://github.com/zzantozz/testbed.git tmp
cd tmp/asm-playground
Run Code Online (Sandbox Code Playgroud)

需要注意的两件事:我首先提出这个问题的原因是:我做了最后一个字段和一个已经是最终字段的字段都可以设置为我认为是正常的字节码指令.

另一个更新:(8月1日)使用1.6.0_26-b03和1.7.0-b147进行测试,结果相同.也就是说,JVM在运行时愉快地修改了最终字段.

最终(?)更新:(9月19日)我正在从这篇文章中删除完整的源代码,因为它相当冗长,但它仍然可以在github上看到(见上文).

我相信我已经最终证明JDK7 JVM违反了规范.(请参阅Stephen的回答摘录.)如前所述,在使用ASM修改字节码后,我将其写回到类文件中.使用优秀的JD-GUI,这个类文件反编译为以下代码:

package rds.asm;

import java.io.PrintStream;

public class TestPojo
{
  private final int x;
  private final int y;

  public TestPojo(int x)
  {
    this.x = x;
    this.y = 1;
  }

  public int getX() {
    return this.x;
  }

  public void setX(int x) { …
Run Code Online (Sandbox Code Playgroud)

java java-bytecode-asm

24
推荐指数
2
解决办法
3647
查看次数

了解常量池的javap输出

在一个非常简单的HelloWorld应用程序上运行javap时,我对常量池周围的输出有些困惑.

测试代码

public class TestClass {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}
Run Code Online (Sandbox Code Playgroud)

Javap -c -verbose输出(剪切)

// Header + consts 1..22 snipped
const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #22; //String hello world
   5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return
  // Debug info snipped
}
Run Code Online (Sandbox Code Playgroud)

好的,所以在第3行我们看到通过#22将"hello world"常量推送到堆栈上,但const#23似乎保持实际值.我想我对#(数字)在打印输出右侧出现时的含义有点困惑.

Oracle/Sun的javap手册页有很多不足之处.

java javap java-bytecode-asm

21
推荐指数
2
解决办法
1万
查看次数

是否有可能在Java中存储堆栈的秘密?

在Java中,存储密码的旧方法(如密码)可以使用,char[]因为您可以在完成后覆盖其数据.然而,由于垃圾收集器在重新组织堆时会复制内容,因此这被证明是不安全的.在某些体系结构中,可能会释放页面,并且当其他程序分配同一页面时,秘密将保留.

这非常难看,但是如果秘密存储在Thread run方法的堆栈上呢?仍需要注意优雅地终止线程,以便它可以将其数据清零,但这个问题也以旧的方式出现.

我直接看到的一个主要问题是我无法想到一种安全的方法来获取数据进出容器.您可以通过使用具有非常小的内部缓冲区的流来最小化泄露秘密的可能性,但最终您最终会遇到与此相同的问题char[].[编辑:单个private static byte成员和国旗会有效吗?虽然这会限制每个ClassLoader一个秘密.这增加了更多的丑陋,但它可能很容易隐藏在一个写得很好的界面后面.]

所以我真的有很多问题.

堆栈比这些类型的攻击更安全吗?是否有任何纯Java机制以对这个问题有用的方式在两个不同的堆栈帧之间执行堆栈到堆栈的复制?如果没有,JVM是否甚至支持字节码中的这种类型的操作?

[编辑:在人们过分担心之前,这更像是一个思想实验而不是其他任何东西.我绝对没有打算"在生产中测试"或在任何当前项目中使用它.我意识到我所说的内容真的很难看,可能非常笨重,并且可以对抗整个JVM结构.我只是对它是否有可能感兴趣,它是否真正实现了我的目标,以及它需要什么样的英雄才能实现目标.

java memory security jvm java-bytecode-asm

21
推荐指数
1
解决办法
436
查看次数

Java中的别名分析

有人可以指向我的Java框架或别名分析实现.我查看了asm框架,但它只提供数据流分析和控制流分析.

更新:只是好奇,但有人知道Findbugs是否进行别名分析?

java compiler-construction optimization code-analysis java-bytecode-asm

17
推荐指数
3
解决办法
1512
查看次数

使用ASM或Javassist改进字段获取和设置性能

我想避免在我正在开发的开源项目中反思.在这里,我有类似以下的课程.

public class PurchaseOrder {

   @Property
   private Customer customer;

   @Property
   private String name;
}
Run Code Online (Sandbox Code Playgroud)

我扫描@Property注释以确定我可以设置和反射性地从PurchaseOrder获取.有许多这样的类都使用java.lang.reflect.Field.get()java.lang.reflect.Field.set().

理想情况下,我想为每个属性生成如下调用者.

public interface PropertyAccessor<S, V> {
   public void set(S source, V value);
   public V get(S source);
}
Run Code Online (Sandbox Code Playgroud)

现在,当我扫描类时,我可以创建一个PurchaseOrder类似的静态内部类.

static class customer_Field implements PropertyAccessor<PurchaseOrder, Customer> {
   public void set(PurchaseOrder order, Customer customer) {
      order.customer = customer;
   }  
   public Customer get(PurchaseOrder order) {
      return order.customer;
   }
}
Run Code Online (Sandbox Code Playgroud)

有了这些,我完全避免了反思的代价.我现在可以使用原生性能设置并从我的实例中获取.任何人都可以告诉我如何做到这一点.代码示例会很棒.我在网上搜索了一个很好的例子但是却找不到这样的东西.ASM和Javasist的例子也很差.

这里的关键是我有一个可以传递的界面.所以我可以有各种各样的实现,也许有一个用Java反射作为默认,一个用ASM,一个用Javassist?

任何帮助将不胜感激.

java assembly java-bytecode-asm

15
推荐指数
1
解决办法
6372
查看次数

对于Doseq(和方法代码太大)

user=> (def r (range 1))
user=> (for [a r, b r, c r, d r, e r, f r, g r, h r :when (and (= 0 a) (not= 1 b))]
          (list a b c d e f g h))
((0 0 0 0 0 0 0 0))
user=> (doseq [a r, b r, c r, d r, e r, f r, g r, h r :when (and (= 0 a) (not= 1 b))]
          (println (list a b c d …
Run Code Online (Sandbox Code Playgroud)

java clojure java-bytecode-asm

15
推荐指数
1
解决办法
1027
查看次数

在Android上使用Groovy

随着ASMDEX(dex文件的ASM)和dexmaker的出现,不应该将Groovy移植到Android吗?两个框架都允许在运行时生成dex字节码.

据我了解,不可能在内存中修改APK中的dex类.但是不可能将这些类复制到可写内存,在运行时修改这些副本并使用它们吗?

还需要移植什么来处理dex类文件?CGLIB

groovy android cglib dex java-bytecode-asm

13
推荐指数
1
解决办法
4120
查看次数