- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试做一个简单的Java字节码混淆器,它通过替换 GOTO
来工作。具有简单条件跳转的指令,例如 if 10 != 15 GOTO else throw IllegalStateException
。我当前的代码是:
final AbstractInsnNode[] insns = method.instructions.toArray().clone();
for (final AbstractInsnNode insn : insns) {
final int op = insn.getOpcode();
if ((op == GOTO) || (op == IFLE) || (op == IFGE)) {
LabelNode l0 = new LabelNode();
LabelNode l1 = new LabelNode();
LabelNode l2 = new LabelNode();
int locals = (method.localVariables == null) ? 0 : method.localVariables.size();
int params = (method.parameters == null) ? 0 : method.parameters.size();
int v0index = locals + params;
int v1index = v0index + 1;
int exindex = v1index + 1;
// Init fake conditional fields
method.instructions.insertBefore(insn, new LdcInsnNode(10F));
method.instructions.insertBefore(insn, new VarInsnNode(FSTORE, v0index));
method.instructions.insertBefore(insn, new LdcInsnNode(45F));
method.instructions.insertBefore(insn, new VarInsnNode(FSTORE, v1index));
// Crossing jumps
method.instructions.insertBefore(insn, l1);
method.instructions.insert(insn, l0);
method.instructions.insert(l0, l2);
LabelNode l3 = new LabelNode();
LabelNode l4 = new LabelNode();
method.instructions.insert(l2, l3);
method.instructions.insert(l3, l4);
// If 'v0!=v1', jump to l0, otherwise goto l3
method.instructions.insertBefore(l1, new VarInsnNode(FLOAD, v0index));
method.instructions.insertBefore(l1, new VarInsnNode(FLOAD, v1index));
method.instructions.insertBefore(l1, new InsnNode(FCMPG));
method.instructions.insertBefore(l1, new JumpInsnNode(IFNE, l0));
method.instructions.insertBefore(l1, new JumpInsnNode(GOTO, l3));
// Jump to l3 results in throwing an exception
// Create and throw the exception
method.instructions.insertBefore(l4, new TypeInsnNode(NEW, "java/lang/IllegalStateException"));
method.instructions.insertBefore(l4, new InsnNode(DUP));
method.instructions.insertBefore(l4, new MethodInsnNode(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "()V", false));
method.instructions.insertBefore(l4, new InsnNode(ATHROW));
method.instructions.insertBefore(l0, new JumpInsnNode(GOTO, l2));
method.instructions.insertBefore(l2, new JumpInsnNode(GOTO, l1));
// Exception handler
LabelNode start = new LabelNode();
LabelNode handler = new LabelNode();
LabelNode end = new LabelNode();
method.instructions.insertBefore(l0, start);
method.instructions.insert(l2, end);
method.instructions.insert(end, handler);
// Just throw the exception again
LabelNode l5 = new LabelNode();
method.instructions.insert(handler, l5);
method.instructions.insertBefore(l5, new TypeInsnNode(NEW, "java/lang/IllegalStateException"));
method.instructions.insertBefore(l5, new InsnNode(DUP));
method.instructions.insertBefore(l5, new MethodInsnNode(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>", "()V", false));
method.instructions.insertBefore(l5, new InsnNode(ATHROW));
// Try/catch
TryCatchBlockNode tryBlock = new TryCatchBlockNode(start, end, handler, "java/lang/IllegalStateException");
method.tryCatchBlocks.add(tryBlock);
// Init local variables
method.visitLocalVariable("_v0_" + Rand.alphaNumeric(5), "F", null, l0.getLabel(), l2.getLabel(), v0index);
method.visitLocalVariable("_v1_" + Rand.alphaNumeric(5), "F", null, l0.getLabel(), l2.getLabel(), v1index);
method.visitLocalVariable("_ex_" + Rand.alphaNumeric(5), "Ljava/lang/IllegalArgumentException;", null, start.getLabel(), handler.getLabel(), exindex);
}
}
哪里method
是混淆方法的类型为 MethodNode
的参数,并且该类实现接口(interface) Opcodes
.
这工作正常,但不适用于所有方法(我对字节码很陌生,所以不知道确切的情况)。例如,它适用于 main
方法:
原始Java代码(在Procyon中反编译): https://p.reflex.rip/DLMT.cs
原始字节码: https://p.reflex.rip/ywJt.go
混淆的 Java 代码(在 Procyon 中反编译): https://p.reflex.rip/Er9V.cs
混淆的字节码: https://p.reflex.rip/JBAb.go
但是,它破坏了其他一个,divMinByMax
,方法:
原始Java代码(在Procyon中反编译): https://p.reflex.rip/AW9W.java
原始字节码: https://p.reflex.rip/GX2k.cpp
混淆的 Java 代码(在 Procyon 中反编译,失败): https://p.reflex.rip/Eqju.java
混淆的字节码: https://p.reflex.rip/isiX.cpp
当我尝试使用 java -jar
运行混淆的 JAR 时,此方法会导致 VerifyError :
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 27
Exception Details:
Location:
test/one/HelloRandom.divMinByMax(DD)D @21: goto
Reason:
Current frame's stack size doesn't match stackmap.
Current Frame:
bci: @21
flags: { }
locals: { double, double_2nd, float, float }
stack: { }
Stackmap Frame:
bci: @27
flags: { }
locals: { double, double_2nd, float, float }
stack: { 'java/lang/IllegalStateException' }
Bytecode:
0x0000000: 2826 9712 7145 1272 4624 2596 9a00 0ca7
0x0000010: 0014 9e00 48a7 0006 a7ff fabb 0016 59b7
0x0000020: 0073 bfbb 0016 59b7 0073 bf00 0000 0000
0x0000030: 00bf 0000 00bf 0000 0000 0000 00bf 0000
0x0000040: bf00 00bf 0000 bf00 00bf 0000 0000 0000
0x0000050: 00bf 0000 0000 0000 00bf 2826 6faf
Exception Handler Table:
bci [24, 27] => handler: 27
Stackmap Table:
full_frame(@18,{Double,Float,Float},{Integer})
same_locals_1_stack_item_frame(@24,Integer)
same_locals_1_stack_item_frame(@27,Object[#22])
same_locals_1_stack_item_frame(@35,Integer)
full_frame(@43,{},{Object[#159]})
same_locals_1_stack_item_frame(@50,Object[#159])
same_locals_1_stack_item_frame(@54,Object[#159])
same_locals_1_stack_item_frame(@62,Object[#159])
same_locals_1_stack_item_frame(@65,Object[#159])
same_locals_1_stack_item_frame(@68,Object[#159])
same_locals_1_stack_item_frame(@71,Object[#159])
same_locals_1_stack_item_frame(@74,Object[#159])
same_locals_1_stack_item_frame(@82,Object[#159])
append_frame(@90,Double,Float,Float)
same_locals_1_stack_item_frame(@93,Double)
我做了很多研究,我唯一找到的就是原因:据我了解,问题在于 @21
上的堆栈( GOTO
跳转到执行 throw new IllegalStateException
的标签):
stack: { }
(为空)与 @27
处的堆栈不匹配,在跳转目标标签上:
stack: { 'java/lang/IllegalStateException' }
(其中包含应“抛出”的异常)。
所以基本上,据我所知,错误是在我尝试执行 GOTO <n>
时发生的。跳到哪里<n>
是“抛出” IllegalStateException
的标签编号.
如何解决这个问题?也许有一种方法可以使堆栈位于 @21
包含java/lang/IllegalStateException
也在跳跃之前(以便这两个堆栈,即跳跃之前的堆栈和跳跃之后的堆栈匹配)?或者我可以用它做其他什么?
最佳答案
您在指令后插入异常处理程序,但当指令是条件分支时,即IFLE
或IFGE
,分支可能不会被执行,并且代码流在指令之后继续,运行到异常处理程序中。
这会产生不一致的状态,因为异常处理程序期望堆栈上有一个 Throwable
,而当代码流在检测指令之后继续运行时,该堆栈不存在。但当然,在这种情况下您不想执行异常处理程序,因此您必须插入另一个 GOTO
,从 l2
到 l5
如果我做对了。
在检测 GOTO
指令时这不是问题,因为指令之后不会继续执行。
在这里,我推荐一种不同的编码风格。在不同的引用节点之前和之后插入使得在阅读代码时无法预测实际的代码结构。如果您只使用一个引用节点插入一个线性指令列表,那么它的可维护性会更高。
关于java - ASM - 分支目标处的堆栈图帧不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48325824/
我创建了一个基于命令行可移植脚本的工业化不可知构建系统,可用于快速构建多个依赖项目,而不必依赖特定的 IDE 或构建工厂。它是不可知的,因为它不是基于单个构建引擎。我使用 cmake 创建了第一个版本
我最初使用 Java 目标开发了一个语法(用于 TestRig 支持),然后将其移植到 Python(从 git hub 语法存储库扩展了 Python3 语法,因此需要将操作移植到 Python
我有一个以 iPhone 和 watchOS 为目标的 Xcode 项目。 iPhone 目标使用加速度计,模拟器不支持。我可以只启动 iPhone 应用程序而不启动 watch 目标吗?我从: Ca
您好,我想创建一个批处理文件,用于在 .eml 文件(目标 A)中查找某些关键字,然后删除它们所在的行。之后,我需要批处理文件将"new"文件放入(目标 B)中的单独 .eml 文件中。文件也可以是
当尝试通过 IntelliJ 运行示例 CorDapp (GitHub CorDapp) 时,我收到以下错误: Cannot inline bytecode built with JVM target
我在尝试向我的 kotlin spring 项目添加一些依赖项时遇到问题。我使用 spring boot 初始化程序来运行一个基本项目。 我的问题:如果我取消对 jackson 或 Koin 依赖项的
这是有问题的网站: http://www.onepixelroom.com/londonrefurb 当我点击关于部分后面的多个圆圈时,我希望它更改上面文本中的引号。 到目前为止,我得到它来显示 文本
单击后,我将删除两个元素 $(this) 和 $("#foo")。 目前我的代码如下所示: $(this).remove(); $("#foo").remove(); 如何在不重复自己的情况下优化它?
我有一个小脚本,可将 Markdown 文件编译为 html,并将其与一些样式表和 javascript 一起插入到模板的主体中。我有一个 GNU makefile 来完成这个: output.htm
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
一些背景知识: 在android中我们开发了同样的应用,基本上我们先开发了Android应用,现在我们创建了它的IOS版本,所以这个应用有多个客户端。在 android 中,我们实际上是使用 Andr
我想知道是否可以使用 knockout 来更改html中的目标() 我的所有其他信息都在 JavaScript 中,所以这对我来说是一个大问题。这是我的 JavaScript: var library
这个问题在这里已经有了答案: Selecting and manipulating CSS pseudo-elements such as ::before and ::after using j
我在我的有向图中添加了一堆节点和顶点,使用设置 typedef boost::adjacency_list graph; 创建 Node有一个节点名称字符串,Edge它的分数有一个整数。我试图遍历所有
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 8 年前。 Improve
如何存储我在 NSUserDefaults 中创建的 Goal 类型的对象数组? ( swift ) 代码如下: func saveGoalList ( newGoalList : [Goal] ){
Array.prototype.indexOf 和 Date.now 已在 ES5 中引入。如果我编译存储在文件 test.ts 中的以下代码,为什么 Typescript 不能转译? Date.no
我正在阅读有关属性的内容,并了解到可以使用您的代码将它们应用于不同的目标实体 -(请参阅 Attribute Targets)。 因此,查看我项目中的 AssemblyInfo.cs 文件,我可以看到
给定一个 Makefile: all: build/a build/b build/c # need to change this to all: build/* build/a:
我有一个带有多框架目标的项目- netstandard2.0;net471 . 我想为 netframework 构建解决方案和 netstandard分别。 目前我使用这个 MSBuild 命令:
我是一名优秀的程序员,十分优秀!