GraalVM Native Image Inspect Tool 的演进:从弃用到 native-image-utils extract-sbom 的嵌入式 SBOM 提取实践与源码解析
GraalVM Native Image Inspect Tool 的演进从弃用到 native-image-utils extract-sbom 的嵌入式 SBOM 提取实践与源码解析【免费下载链接】graalGraalVM compiles applications into native executables that start instantly, scale fast, and use fewer compute resources 项目地址: https://gitcode.com/gh_mirrors/gr/graalNative Image Inspect Toolnative-image-inspect是 GraalVM 早期用于检查 native 可执行文件内部内容的独立工具。该工具已被官方弃用其仅存的有效功能是配合native-image-utils extract-sbom命令从 native 可执行文件中提取构建时嵌入的 SBOMSoftware Bill of Materials软件物料清单。读完本文你将理解该工具弃用的背景与迁移路径、extract-sbom命令的完整用法与参数并能结合 Graal 仓库源码弄清 SBOM 是如何被定位、解压并从 ELF/Mach-O/PE 二进制中还原出来的。一、Inspect Tool 是什么为何被弃用根据官方文档 InspectTool.md 的定义该工具从 native 可执行文件中提取嵌入的 SBOM而它曾经支持的类级别元数据class-level metadata提取功能已不再受支持The Native Image Inspect Tool is deprecated and will be removed in a future release.To extract embedded SBOMs, use:$JAVA_HOME/bin/native-image-utils extract-sbom --image-pathpath_to_binary从 substratevm/CHANGELOG.md 可以梳理出这次弃用的完整脉络GR-69572弃用native-image-inspect工具提取嵌入式 SBOM 一律改用native-image-utils extract-sbom --image-pathpath_to_binaryGR-59313弃用通过native-image-inspect提取类级别元数据的能力删除了DumpMethodsData构建选项并引导用户改用--enable-sbomclass-level,export生成包含类级别元数据的 SBOMGR-69116native-image-configure工具更名为native-image-utils即当前提取命令的宿主工具GR-76386native-image-utils extract-sbom命令本身已下放至 GraalVM Community Edition。这里有一个需要注意的边界SBOM 的嵌入能力与 SBOM 的提取能力是分开的。原文档明确指出在构建时向 native 可执行文件中嵌入 SBOM 的功能Not available in GraalVM Community Edition——即社区版构建出的镜像中并不包含嵌入 SBOM而提取命令extract-sbom本身在社区版工具链中可用它只能从确实嵌入了 SBOM的 Oracle GraalVM 构建产物中提取内容。二、提取嵌入式 SBOM命令用法与参数基本命令官方给出的标准用法见 InspectTool.md$JAVA_HOME/bin/native-image-utils extract-sbom --image-pathpath_to_binary其中path_to_binary是 native-image 构建产出的可执行文件或 native 共享库。执行后SBOM 的 JSON 内容会打印到标准输出。从源码看完整参数集与校验逻辑extract-sbom命令的实现位于 SBOMExtractorCommand.java。从该类的Arguments.parse与validate静态方法L64-L107可以看到它实际接受两个keyvalue形式的选项且参数解析非常严格——任何不符合keyvalue格式的参数、以及未识别的选项名都会抛出ConfigurationUsageException选项必填含义源码依据--image-pathpath是指向包含嵌入 SBOM 的 native 可执行文件或共享库OPTION_IMAGE_PATHL59--output-filepath否将解压后的 SBOM 写入该文件缺省时输出到 stdoutOPTION_OUTPUT_FILEL60对--image-path的取值validate方法L92-L106会依次检查必须指定、文件必须存在、不能是目录、不能是空文件任一不满足都会给出带明确提示的用法异常。当提取过程整体失败时文件不是 GraalVM Native Image 产物、或构建时未启用 SBOM 功能等apply方法L114-L133会抛出一个信息量很大的诊断提示其中包含版本前提说明Failed to extract embedded SBOM from image path. Reason: reason Verify the following: - The file was generated by GraalVM Native Image. - The SBOM feature was enabled when building the image. Oracle GraalVM 25 and above embeds SBOMs by default. For earlier Oracle GraalVM versions, ensure --enable-sbom is passed to native-image.这段话给出了两个重要的适用前提Oracle GraalVM 25 及以上版本默认嵌入 SBOM更早的 Oracle GraalVM 版本需要显式向native-image构建命令传入--enable-sbom否则镜像里没有 SBOM 可供提取。三、底层实现SBOM 是如何从二进制中被还原的SBOMExtractorCommand的提取逻辑L135-L143本身很薄没有--output-file时调用ResourceExtractor.extract(imagePath, sbom, System.out)有则写入目标文件。真正的从二进制里挖数据工作由 ResourceExtractor.java 承担。3.1 两个符号sbom 与 sbom_lengthSBOMExtractorCommand的类注释L36-L57说明嵌入的 SBOM 以 gzip 压缩形式存储在镜像的数据段中并伴随两个导出的符号sbom指向压缩后 SBOM 数据的起始位置sbom_length指向压缩后 SBOM 数据的长度。这与 SBOM 专题文档 的描述一致The SBOM is stored in thegzipformat with the exportedsbomsymbol referencing its start address and thesbom_lengthsymbol referencing its size. 命名规则上长度符号名固定为数据符号名拼接_length见 ResourceExtractor.java 的 Javadoc。3.2 内存映射 平台相关符号定位 gzip 解压ResourceExtractor.extractL65-L73的完整流程是只读打开并内存映射整个镜像文件FileChannel.open(image, READ)后调用channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size(), arena)。注释特别解释了为什么用MemorySegment而不是ByteBuffer——allow memory mapping images larger than 2 GB即支持超过 2GB 的大镜像定位资源locateResourceLocationL75-L79通过ResourceLocatorFactory创建一个与平台匹配的ResourceLocator再由它在镜像中查找符号对应的偏移与长度切片并解压memorySegment.asSlice(offset, size)取出压缩数据交给decompressAndWriteL81-L86后者用GZIPInputStream包裹一个自实现的MemorySegmentInputStreamL88-L111逐字节读取并做b 0xFF无符号转换最后transferTo(out)写出 JSON 明文。平台适配由extractor包下的三个定位器实现从 com.oracle.svm.configure/extractor 目录结构可以直接看到与三大操作系统的对应关系ElfResourceLocator.java —— Linux 的 ELF 格式MachOResourceLocator.java —— macOS 的 Mach-O 格式;PECoffResourceLocator.java —— Windows 的 PE/COFF 格式。ResourceLocatorFactory.java 负责按运行环境选择其中一种这正是syft等第三方工具也能提取 SBOM 的底层基础——符号约定sbom/sbom_length gzip是跨工具的通用契约。值得强调的是ResourceExtractor的设计是符号无关的SBOMExtractorCommand注释 L53-L56 提到将来若需提取其他嵌入资源可直接复用该提取器只是当前 SBOM 是唯一被嵌入的资源因此命令名被刻意命名为 SBOM 专用以保持 APIdescriptive and minimal。四、被移除的能力类级别元数据提取及其迁移路径原文档明确指出Inspect Tool 历史上还支持列出 native 可执行文件或 native 共享库中包含的类、字段与方法而该功能出于安全原因for security reasons已被移除The Native Image Inspect Tool previously supported listing the classes, fields, and methods included in a native executable or a native shared library. This functionality is no longer supported for security reasons.官方给出的迁移方案是向native-image构建命令传入--enable-sbomclass-level,export让构建器在构建阶段就生成包含同样种类类级别元数据信息的 SBOM而不是在事后从二进制中逆向查看。这与 CHANGELOG 中 GR-59313 的记录相互印证弃用native-image-inspect的类级别元数据提取、删除DumpMethodsData选项改用--enable-sbomclass-level,export。class-level SBOM 能拿到什么关于--enable-sbomclass-level的具体内容可参考 SBOM 专题文档 的 Including Class-Level Metadata in the SBOM 一节。类级别元数据以 CycloneDX 的组件嵌套结构表达层级为[component] SBOM Component └── [component] Java Modules └── [component] Java Source Files ├── [property] Classes / Interfaces / Records ├── [property] Annotations / Enums └── [property] Fields / Constructors / Methods其中字段、构造器、方法各以className.memberName(paramTypes):returnType之类的规范字符串记录例如com.sbom.ClassInSameFile.concatenate():java.lang.String。该能力的主要用途有两个一是高级漏洞扫描——当 CVE 公布了受影响的具体类或方法时可用类级别元数据判断镜像是否真正包含受影响的成员从而降低误报二是快速浏览镜像实际包含的类内容。使用时的两个约束同样来自 SBOM.md体积代价类级别元数据会显著增大 SBOM。文档以 Micronaut Hello World Rest 应用为例含类级别元数据时嵌入大小约 1.1 MB、导出大小约 13.7 MB不含时分别为 3.5 kB 与 64 kB对应 native 镜像本体约 52 MB。工具链限制syft提取 SBOM 时会剥掉承载类级别元数据的嵌套components字段因此类级别信息不会出现在 syft 的提取结果中不影响漏洞扫描功能本身。五、工具生态位native-image-utils 的命令全集extract-sbom并非孤立的脚本而是native-image-utils工具的一个子命令。该工具的入口是 ConfigurationTool.java其 Javadoc 明确写道A standalone tool for native-image. It is shipped asnative-image-utils(previouslynative-image-configure).并在main方法中检测到旧启动器名时打印您正在使用已弃用的 native-image-configure 工具请切换到 native-image-utils的警告。从static块注册表L56-L71可以确认当前工具注册的子命令除extract-sbom外还有子命令实现类用途概述helpConfigurationHelpCommand.java打印使用说明generateConfigurationGenerateCommand.java基于 tracing agent 的运行时数据生成可达性配置process-traceConfigurationProcessTraceCommand.java处理 trace 数据generate-filtersConfigurationGenerateFiltersCommand.java生成类层级过滤器配置generate-conditionalsConfigurationGenerateConditionalsCommand.java生成条件化配置extract-sbomSBOMExtractorCommand.java本文主题提取嵌入式 SBOM也就是说Inspect Tool 承担过的查看镜像内部职能如今被拆散并重新定位查看依赖构成走 SBOM 体系构建时生成、运行时提取其余配置生成类能力收敛在native-image-utils中。六、实操清单与故障排查结合原文档与源码实际操作可以归纳为以下路径构建侧Oracle GraalVM确认 SBOM 功能开启。Oracle GraalVM 25 默认启用且默认为embed将压缩 SBOM 嵌入可执行文件更早版本需显式native-image --enable-sbom ...。完整功能矩阵--enable-sbomfalse关闭、classpath/export输出位置、hashes/strict完整性校验、class-level元数据等见 SBOM 专题文档。提取侧# 输出到终端 $JAVA_HOME/bin/native-image-utils extract-sbom --image-path./my-app # 落盘 $JAVA_HOME/bin/native-image-utils extract-sbom --image-path./my-app --output-file./my-app.sbom.json失败排查若命令报错对照 SBOMExtractorCommand.java 的诊断提示逐项检查——文件是否为 GraalVM Native Image 构建产物、构建时是否启用了 SBOM 功能、以及所用 Oracle GraalVM 版本是否低于 25 而未显式传--enable-sbom。安全集成提取出的 CycloneDX JSON 可直接管道给漏洞扫描工具。SBOM.md 给出的示例native-image-utils extract-sbom --image-pathpath_to_binary | grype七、关键结论native-image-inspect已弃用并将随未来版本移除唯一保留场景提取嵌入式 SBOM由native-image-utils extract-sbom承接且该命令已进入 GraalVM Community EditionGR-76386类、字段、方法列举能力因安全原因被彻底移除替代方案是构建期的--enable-sbomclass-level,export从源码结构看提取机制依赖sbom/sbom_length两个导出符号 gzip 压缩 内存映射读取这一契约并针对 ELF、Mach-O、PE/COFF 三大格式各有一个符号定位器实现天然支持超过 2GB 的大镜像。延伸阅读Software Bill of Materials (SBOM) in Native Image、Native Image 安全指南、原始文档 Native Image Inspect Tool。【免费下载链接】graalGraalVM compiles applications into native executables that start instantly, scale fast, and use fewer compute resources 项目地址: https://gitcode.com/gh_mirrors/gr/graal创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考