热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用stackmap框架以及它如何帮助进行字节码验证?

如何解决《使用stackmap框架以及它如何帮助进行字节码验证?》经验,为你挑选了1个好方法。

我一直试图绕过模糊的堆栈映射框架,它只是在一次通过中验证动态加载的类.

很少有堆栈溢出答案和其他资源,我发现非常有用

    堆栈映射帧有更好的解释吗?

    什么样的Java代码需要stackmap框架?

    http://chrononsystems.com/blog/java-7-design-flaw-leads-to-huge-backward-step-for-the-jvm

我理解以下内容 -

    每个基本块都应以堆栈映射帧开始.

    紧跟在无条件分支之后的每条指令(它是基本块的开始)应该具有堆栈映射帧.

    通过ASM创建堆栈映射帧的算法.ASM文档的第3.5节

所有这些文章的缺点在于它没有描述在验证中如何使用堆栈映射框.

更具体地说 - 假设我们有一个如下所述的字节码.在当前位置,操作数堆栈将为空,并且局部变量1的类型将为B.位置L0具有关联的堆栈映射帧.验证者如何使用此信息?

    
    GETSTATIC B.VALUE
    ASTORE 1 
    GOTO L0 <- Current location
    
L1  GETSTATIC A.VALUE
    ASTORE 1
    
L0  ILOAD 0
    IFNE L1
    
    ALOAD 1
    ARETURN

注意:请注意,我确实阅读了JVM规范并且很难理解堆栈映射框架.任何帮助都会非常有帮助.



1> Antimony..:

在字节码中的每一点,本地和操作数堆栈中的每个项都有一个隐式类型.在旧系统下,验证程序按原样计算这些类型,但是如果控制流向后移动,则可能会改变目标的类型,这意味着它必须迭代直到收敛.

现在,在这样的跳转目标上明确指定了类型.验证器通过字节码进行单个线性传递.每当它到达堆栈帧时,它断言当前推断的类型与堆栈帧中的显式类型兼容,然后使用堆栈帧类型继续.每当它跳转时,它断言跳转目标处的堆栈帧具有与当前推断类型兼容的类型.

本质上,堆栈帧明确地存储"迭代到收敛"的结果,这意味着验证者只是检查结果是否正确,而不是计算它们,这可以在一次通过中完成.

除此之外,不允许较新的类文件使用jsrret指令,这使得验证变得更加容易.

作为一个具体示例,假设您有类似以下的代码

.method static foo : ()V
L0: aconst_null
L1: astore_0
L2: new Foo
L3: dup
L4: invokespecial Method Foo  ()V
L5: astore_0
L6: goto L2
.end method

在推理验证下,verfier最初会在L2处将var 0的类型推断为NULL.一旦达到L6,它必须返回并将类型更改为Foo.

在堆栈映射验证下,验证器将再次在L2处初始推断var 0的类型为NULL.但是,它看到L2处有一个堆栈帧,并检查堆栈帧中0的类型.无论它是什么,它将0设置为该类型并继续检查.当它到达L6时,它查看跳转目标的堆栈帧(L2),并断言L6(即Foo)的0类型可分配给L2的0类型(在堆栈中指定) L2的框架.

假设L2处的堆栈帧声明0具有Object类型.然后,堆栈映射验证程序在每个步骤推断出以下类型

L0: INVALID (unset)
L1: INVALID (unset)
L2: NULL
(checks stack frame at L2)
(assert that NULL is assignable to Object)
L2: Object
L3: Object
L4: Object
L5: Object
L6: Foo
(check stack frame at L2)
(assert that Foo is assignable to Object)


推荐阅读
author-avatar
鹏63213
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有