- 类别:common 别名:— 优先级:未设置(null)
- 作者:—
- 依赖:
groovy(目标运行时具备groovy.lang.GroovyShell等可对字符串求值的 Groovy 组件;内嵌逻辑再借道 JDK 的 JS 引擎)
「表达式转换」构件:把内层产出的 byte[] 字节码封装成一段 可直接求值的 Groovy 表达式字符串。表达式被 Groovy 求值时经 JDK 内置 JS 引擎 eval 一段 JS,用 sun.misc.Unsafe.defineAnonymousClass 加载字节码执行。是「字节码 → Groovy 表达式」的适配层,供以 Groovy 求值的上游 sink 消费。
- 入口
tags:Groovy_Expr、Expression—— 声明产物是 Groovy / 通用表达式字符串,可被nextTags含Groovy_Expr的上游 sink(如GroovyShellRef)承接。 - 衔接
nextTags:BytecodeConvertTag—— 内层须为BytecodeConvert类构件,提供byte[]字节码。 excludes:无。
public static String template =
"Class.forName(\"javax.script.ScriptEngineManager\").newInstance()" +
".getEngineByName(\"JavaScript\").eval(\"" + JsConvert.jsTemplate + "\")";
private String getObject(byte[] bytecode) {
String bytecodeB64 = Base64.encodeBase64String(bytecode);
return String.format(template, bytecodeB64);
}逐段解释:
template是一句 Groovy 表达式:Class.forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval(...)。与 Groovy2Convert 不同,这里 没有@ASTTest注解包裹——它需要被真正「求值/执行」而非仅编译,故用于GroovyShell.evaluate一类运行期注入点。- 借道 JDK 内置 JS 引擎(Nashorn/Rhino)执行内嵌 JS,JS 体直接复用 JsConvert 的
JsConvert.jsTemplate(编译期字符串拼接),该 JS 用Unsafe.defineAnonymousClass从 Base64 字节码定义匿名类并实例化。整体是「Groovy 求值 → JS 引擎 → Unsafe 定义类」的跳板。 String.format(template, bytecodeB64)唯一的%s来自jsTemplate内var s='%s',填入 Base64 字节码。
public Object invoke(GadgetContext context, GadgetChain chain) throws Exception {
return this.getObject((byte[]) chain.doCreate(context));
}invoke 只做一件事:驱动内层拿 byte[],转成 Groovy 表达式字符串返回。头部 Could not load ... Base64 为缺依赖的正常反编译提示。
本类无 @Param。字节码由内层 BytecodeConvert 提供;template 与所用 JsConvert.jsTemplate 均为写死字段。
- 因内嵌 JS 复用
JsConvert.jsTemplate(Unsafe.defineAnonymousClass),受其版本约束:目标需可用 JS 引擎(JDK 8~14 的 Nashorn,JDK 15 起被移除),且defineAnonymousClass在高版本 JDK 受限。 - 与 Groovy2Convert 的关键区别:本类是「运行期求值」型(无
@ASTTest),Groovy2Convert 是「编译期触发」型。选用取决于上游 sink 是求值还是编译源码。 - 在预设链「Groovy 脚本执行」中作为字节码→表达式的中间层,由
GroovyShellRef求值触发。
- Groovy 脚本执行(
[GroovyShellRef, GroovyConvert, BytecodeConvert, Exec],见 chains/42-Groovy脚本执行.md)。
- 上游(承接本
tags=Groovy_Expr):GroovyShellRef(其nextTags指向Groovy_Expr)。 - 内层(
nextTags=BytecodeConvertTag):BytecodeConvert → 字节码 sink(如Exec)。 - 复用:JsConvert(
jsTemplate)。同族:Groovy2Convert、FreemarkerConvert、FreemarkerConvert2。