热门标签 | 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)


推荐阅读
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 该问题可能由守护进程配置不当引起,例如未识别的JVM选项或内存分配不足。建议检查并调整JVM参数,确保为对象堆预留足够的内存空间(至少1572864KB)。此外,还可以优化应用程序的内存使用,减少不必要的内存消耗。 ... [详细]
  • Java中不同类型的常量池(字符串常量池、Class常量池和运行时常量池)的对比与关联分析
    在研究Java虚拟机的过程中,笔者发现存在多种类型的常量池,包括字符串常量池、Class常量池和运行时常量池。通过查阅CSDN、博客园等相关资料,对这些常量池的特性、用途及其相互关系进行了详细探讨。本文将深入分析这三种常量池的差异与联系,帮助读者更好地理解Java虚拟机的内部机制。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 解决 Windows Server 2016 网络连接问题
    本文详细介绍了如何解决 Windows Server 2016 在使用无线网络 (WLAN) 和有线网络 (以太网) 时遇到的连接问题。包括添加必要的功能和安装正确的驱动程序。 ... [详细]
  • 深入解析Struts、Spring与Hibernate三大框架的面试要点与技巧 ... [详细]
  • 类加载机制是Java虚拟机运行时的重要组成部分。本文深入解析了类加载过程的第二阶段,详细阐述了从类被加载到虚拟机内存开始,直至其从内存中卸载的整个生命周期。这一过程中,类经历了加载(Loading)、验证(Verification)等多个关键步骤。通过具体的实例和代码示例,本文探讨了每个阶段的具体操作和潜在问题,帮助读者全面理解类加载机制的内部运作。 ... [详细]
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • Java测试服务器调试指南详细介绍了如何进行远程调试,并深入解析了Java Xdebug参数的使用方法。本文首先概述了Java内置的调试功能,重点介绍了JDB这一类似于GDB的强大调试工具。通过实例演示,读者可以掌握在测试环境中高效调试Java应用程序的技巧,包括配置远程调试环境和优化调试参数,以提高开发效率和代码质量。 ... [详细]
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社区 版权所有