使用ASM通过帧跟踪栈和局部变量字面量的跳转处理问题咨询
LDC字符串字面量跟踪跳转场景实现思路
核心思路是绕开AnalyzerAdapter默认的无标记类型分析逻辑,自行维护带字面量标记的帧状态,覆盖跳转和帧合并的默认实现:
- 自定义可跟踪的值类型:定义
TrackedString包装类,存储三个核心属性:值的原始JVM类型标识、是否为LDC加载的字面量的标记、字面量具体值(非字面量时置空),替换ASM默认帧中存储的无标记类型枚举。 - 重写帧合并规则:两个分支合并时,同一个局部变量槽/操作数栈位的
TrackedString只有在两个分支中均标记为LDC字面量、且字面量值完全一致时,合并后才保留字面量标记,否则统一标记为普通字符串引用,丢弃字面量属性。 - 劫持跳转逻辑的帧处理:遇到
GOTO、条件跳转、switch类跳转指令时,不要清空当前帧,而是将当前完整的帧状态(带所有字面量标记)拷贝一份存入跳转目标Label的前驱帧缓存队列中,待后续分析到目标Label时取用。 - 替换栈映射表的帧恢复逻辑:分析到
Label节点时,不要使用AnalyzerAdapter默认从栈映射表读取的无标记类型初始化帧,而是用该Label对应缓存队列中所有前驱帧做自定义合并后的结果作为初始帧,保证所有字面量标记不会在跳转后丢失。 - 可选简化方案:如果不需要处理所有混淆后的字节码场景,且目标代码都带有完整栈映射表,可以在
visitFrame回调中,将栈映射表返回的每个类型槽位,和所有前驱分支的帧状态做匹配,标记出匹配成功的字面量值,不过该方案准确性低于自行维护帧的方案。
开发时建议直接继承
asm-tree包下的Analyzer和Interpreter接口实现,比修改AnalyzerAdapter的灵活度更高:Interpreter的newOperation回调可直接拦截LDC指令,返回带标记的自定义值实例,无需修改ASM的底层执行逻辑。
内容的提问来源于stack exchange,提问作者Ander Ruiz
相关产品推荐
相关产品推荐

