NOP ATHROW hack defeated !
Rémi Forax <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
Charles Nutter (a JRuby guy) was able to generate a code that defeat
the infamous NOP ... ATHROW hack.
see http://asm.ow2.org/doc/developer-guide.html#deadcode
for the background.
Basically, when a code is dead, not reachable, ASM replaces the
offending code by
NOP ... ATHROW and generate a dedicated stackmap: [] [java/lang/Throwable].
But if the unreachable code is in a try/catch, we create a path where no
local variable
are available anymore. So the split verifier will reject the bytecode if
a local variable is used in the exception handler of the try/catch.
The program below generates a bytecode which is rejected by the split
verifier.
[forax@localhost asm4-test]$ java deadcode
Exception in thread "main" java.lang.VerifyError: Stack map does not
match the one at exception handler 7 in method
deadcode.foo(Ljava/lang/Object;)V at offset 3
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2440)
at java.lang.Class.getMethod0(Class.java:2683)
at java.lang.Class.getMethod(Class.java:1618)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:484)
at
sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:476)
Eric, do you see a solution for that ?
Rémi
----------------------------------------------------------------------------------------------------------------
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_STATIC;
import static org.objectweb.asm.Opcodes.ASTORE;
import static org.objectweb.asm.Opcodes.ATHROW;
import static org.objectweb.asm.Opcodes.GOTO;
import static org.objectweb.asm.Opcodes.ISTORE;
import static org.objectweb.asm.Opcodes.RETURN;
import static org.objectweb.asm.Opcodes.V1_7;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.util.CheckClassAdapter;
public class DeadCode2 {
public static void main(String[] args) throws IOException {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
writer.visit(V1_7, ACC_PUBLIC, "deadcode", null,
"java/lang/Object", null);
MethodVisitor mv = writer.visitMethod(ACC_PUBLIC|ACC_STATIC,
"foo", "(Ljava/lang/Object;)V", null, null);
mv.visitCode();
Label L0, L1, L3;
L0 = new Label(); L1 = new Label(); L3 = new Label();
mv.visitTryCatchBlock(L0, L1, L1, "java/lang/RuntimeException");
mv.visitLabel(L0);
mv.visitJumpInsn(GOTO, L3);
mv.visitLdcInsn("foo");
mv.visitVarInsn(ASTORE, 0);
mv.visitVarInsn(ISTORE, 0);
mv.visitLabel(L1);
mv.visitInsn(ATHROW);
mv.visitLabel(L3);
mv.visitInsn(RETURN);
mv.visitMaxs(-1, -1);
mv.visitEnd();
writer.visitEnd();
CheckClassAdapter.verify(new ClassReader(writer.toByteArray()),
true, new PrintWriter(System.err));
Files.write(Paths.get("deadcode.class"), writer.toByteArray());
}
}
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws